2021-04-29 19:32:06 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "VideoEncoderInput.h"
# include "VideoEncoderInputImpl.h"
# include "VideoEncoderCommon.h"
# include "VideoEncoderFactory.h"
# include "AVEncoderDebug.h"
# include "Misc/Paths.h"
2021-10-26 09:13:01 -04:00
# include "GenericPlatform/GenericPlatformMath.h"
2021-05-25 02:43:26 -04:00
2021-10-26 09:13:01 -04:00
# include "Misc/Guid.h"
2021-04-29 19:32:06 -04:00
# if PLATFORM_WINDOWS
# include "MicrosoftCommon.h"
# endif
2021-10-26 09:13:01 -04:00
FString GetGUID ( )
{
static FGuid id ;
if ( ! id . IsValid ( ) )
{
id = FGuid : : NewGuid ( ) ;
}
return id . ToString ( ) ;
}
2021-04-29 19:32:06 -04:00
namespace AVEncoder
{
2021-11-23 01:47:46 -05:00
// *** FVideoEncoderInput *************************************************************************
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
// --- construct video encoder input based on expected input frame format -------------------------
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateDummy ( bool bIsResizable )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
Input - > bIsResizable = bIsResizable ;
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForDummy ( ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
return Input ;
2021-04-29 19:32:06 -04:00
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateForYUV420P ( uint32 InWidth , uint32 InHeight , bool bIsResizable )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
Input - > bIsResizable = bIsResizable ;
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
if ( ! Input - > SetupForYUV420P ( InWidth , InHeight ) )
{
Input . Reset ( ) ;
}
return Input ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateForD3D11 ( void * InApplicationD3DDevice , bool bIsResizable , bool IsShared )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
2021-10-26 09:13:01 -04:00
# if PLATFORM_WINDOWS
2021-11-23 01:47:46 -05:00
Input - > bIsResizable = bIsResizable ;
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
if ( IsShared )
2021-10-26 09:13:01 -04:00
{
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForD3D11Shared ( static_cast < ID3D11Device * > ( InApplicationD3DDevice ) ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
2021-10-26 09:13:01 -04:00
}
2021-11-23 01:47:46 -05:00
else
2021-10-26 09:13:01 -04:00
{
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForD3D11 ( static_cast < ID3D11Device * > ( InApplicationD3DDevice ) ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
2021-10-26 09:13:01 -04:00
}
2021-04-29 19:32:06 -04:00
# endif
2021-11-23 01:47:46 -05:00
return Input ;
}
2021-04-29 19:32:06 -04:00
2021-10-26 09:13:01 -04:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateForD3D12 ( void * InApplicationD3DDevice , bool bIsResizable , bool IsShared )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
2021-10-26 09:13:01 -04:00
# if PLATFORM_WINDOWS
2021-11-23 01:47:46 -05:00
Input - > bIsResizable = bIsResizable ;
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
if ( IsShared )
2021-10-26 09:13:01 -04:00
{
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForD3D12Shared ( static_cast < ID3D12Device * > ( InApplicationD3DDevice ) ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
2021-10-26 09:13:01 -04:00
}
2021-11-23 01:47:46 -05:00
else
2021-10-26 09:13:01 -04:00
{
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForD3D12 ( static_cast < ID3D12Device * > ( InApplicationD3DDevice ) ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
2021-10-26 09:13:01 -04:00
}
2021-11-23 01:47:46 -05:00
2021-04-29 19:32:06 -04:00
# endif
2021-11-23 01:47:46 -05:00
return Input ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateForCUDA ( void * InApplicationContext , bool bIsResizable )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
Input - > bIsResizable = bIsResizable ;
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForCUDA ( reinterpret_cast < CUcontext > ( InApplicationContext ) ) )
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
return Input ;
2021-04-29 19:32:06 -04:00
}
2021-10-26 09:13:01 -04:00
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
TSharedPtr < FVideoEncoderInput > FVideoEncoderInput : : CreateForVulkan ( void * InApplicationVulkanData , bool bIsResizable )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-10-26 09:13:01 -04:00
{
2021-11-23 01:47:46 -05:00
TSharedPtr < FVideoEncoderInputImpl > Input = MakeShared < FVideoEncoderInputImpl > ( ) ;
Input - > bIsResizable = bIsResizable ;
2021-10-26 09:13:01 -04:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVulkanDataStruct * VulkanData = static_cast < FVulkanDataStruct * > ( InApplicationVulkanData ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-02-10 21:16:24 -05:00
if ( ! Input - > SetupForVulkan ( VulkanData - > VulkanInstance , VulkanData - > VulkanPhysicalDevice , VulkanData - > VulkanDevice ) )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
Input . Reset ( ) ;
}
return Input ;
}
2021-10-26 09:13:01 -04:00
# endif
2021-11-23 01:47:46 -05:00
void FVideoEncoderInput : : SetMaxNumBuffers ( uint32 InMaxNumBuffers )
{
MaxNumBuffers = InMaxNumBuffers ;
}
// --- encoder input frames -----------------------------------------------------------------------
// *** FVideoEncoderInputImpl *********************************************************************
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputImpl : : ~ FVideoEncoderInputImpl ( )
2021-04-29 19:32:06 -04:00
{
{
2021-11-23 01:47:46 -05:00
FScopeLock Guard ( & ProtectFrames ) ;
if ( ActiveFrames . Num ( ) > 0 )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " There are still %d active input frames. " ) , ActiveFrames . Num ( ) ) ;
}
check ( ActiveFrames . Num ( ) = = 0 ) ;
2021-04-29 19:32:06 -04:00
}
2021-11-23 01:47:46 -05:00
# if PLATFORM_WINDOWS
// DEBUG_D3D11_REPORT_LIVE_DEVICE_OBJECT(FrameInfoD3D.EncoderDeviceD3D11);
# endif
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForDummy ( )
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : Undefined ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
return true ;
}
bool FVideoEncoderInputImpl : : SetupForYUV420P ( uint32 InWidth , uint32 InHeight )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : YUV420P ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameInfoYUV420P . StrideY = InWidth ;
FrameInfoYUV420P . StrideU = ( InWidth + 1 ) / 2 ;
FrameInfoYUV420P . StrideV = ( InWidth + 1 ) / 2 ;
CollectAvailableEncoders ( ) ;
return true ;
}
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForD3D11 ( void * InApplicationD3DDevice )
2021-11-23 01:47:46 -05:00
{
# if PLATFORM_WINDOWS
TRefCountPtr < IDXGIDevice > DXGIDevice ;
TRefCountPtr < IDXGIAdapter > Adapter ;
HRESULT Result = static_cast < ID3D11Device * > ( InApplicationD3DDevice ) - > QueryInterface ( __uuidof ( IDXGIDevice ) , ( void * * ) DXGIDevice . GetInitReference ( ) ) ;
if ( Result ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::QueryInterface() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
else if ( ( Result = DXGIDevice - > GetAdapter ( Adapter . GetInitReference ( ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " DXGIDevice::GetAdapter() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
uint32 DeviceFlags = 0 ;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0 ;
D3D_FEATURE_LEVEL ActualFeatureLevel ;
if ( ( Result = D3D11CreateDevice (
Adapter ,
D3D_DRIVER_TYPE_UNKNOWN ,
NULL ,
DeviceFlags ,
& FeatureLevel ,
1 ,
D3D11_SDK_VERSION ,
FrameInfoD3D . EncoderDeviceD3D11 . GetInitReference ( ) ,
& ActualFeatureLevel ,
FrameInfoD3D . EncoderDeviceContextD3D11 . GetInitReference ( ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " D3D11CreateDevice() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceD3D11 , " FVideoEncoderInputImpl " ) ;
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceContextD3D11 , " FVideoEncoderInputImpl " ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
# endif
return false ;
}
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForD3D11Shared ( void * InApplicationD3DDevice )
2021-11-23 01:47:46 -05:00
{
# if PLATFORM_WINDOWS
TRefCountPtr < IDXGIDevice > DXGIDevice ;
TRefCountPtr < IDXGIAdapter > Adapter ;
HRESULT Result = static_cast < ID3D11Device * > ( InApplicationD3DDevice ) - > QueryInterface ( __uuidof ( IDXGIDevice ) , ( void * * ) DXGIDevice . GetInitReference ( ) ) ;
if ( Result ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::QueryInterface() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
else if ( ( Result = DXGIDevice - > GetAdapter ( Adapter . GetInitReference ( ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " DXGIDevice::GetAdapter() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
uint32 DeviceFlags = 0 ;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_1 ;
D3D_FEATURE_LEVEL ActualFeatureLevel ;
if ( ( Result = D3D11CreateDevice (
Adapter ,
D3D_DRIVER_TYPE_UNKNOWN ,
NULL ,
DeviceFlags ,
& FeatureLevel ,
1 ,
D3D11_SDK_VERSION ,
FrameInfoD3D . EncoderDeviceD3D11 . GetInitReference ( ) ,
& ActualFeatureLevel ,
FrameInfoD3D . EncoderDeviceContextD3D11 . GetInitReference ( ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " D3D11CreateDevice() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceD3D11 , " FVideoEncoderInputImpl " ) ;
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceContextD3D11 , " FVideoEncoderInputImpl " ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
# endif
return false ;
}
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForD3D12 ( void * InApplicationD3DDevice )
2021-11-23 01:47:46 -05:00
{
# if PLATFORM_WINDOWS
LUID AdapterLuid = static_cast < ID3D12Device * > ( InApplicationD3DDevice ) - > GetAdapterLuid ( ) ;
TRefCountPtr < IDXGIFactory4 > DXGIFactory ;
HRESULT Result ;
if ( ( Result = CreateDXGIFactory ( IID_PPV_ARGS ( DXGIFactory . GetInitReference ( ) ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " CreateDXGIFactory() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
// get the adapter game uses to render
TRefCountPtr < IDXGIAdapter > Adapter ;
if ( ( Result = DXGIFactory - > EnumAdapterByLuid ( AdapterLuid , IID_PPV_ARGS ( Adapter . GetInitReference ( ) ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " DXGIFactory::EnumAdapterByLuid() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
uint32 DeviceFlags = 0 ;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_12_0 ; // TODO get this from the adaptor support
if ( ( Result = D3D12CreateDevice ( Adapter , FeatureLevel , IID_PPV_ARGS ( FrameInfoD3D . EncoderDeviceD3D12 . GetInitReference ( ) ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " D3D11CreateDevice() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : D3D12_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
# endif
return false ;
}
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForD3D12Shared ( void * InApplicationD3DDevice )
2021-11-23 01:47:46 -05:00
{
# if PLATFORM_WINDOWS
LUID AdapterLuid = static_cast < ID3D12Device * > ( InApplicationD3DDevice ) - > GetAdapterLuid ( ) ;
TRefCountPtr < IDXGIFactory4 > DXGIFactory ;
HRESULT Result ;
if ( ( Result = CreateDXGIFactory ( IID_PPV_ARGS ( DXGIFactory . GetInitReference ( ) ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " CreateDXGIFactory() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
// get the adapter game uses to render
TRefCountPtr < IDXGIAdapter > Adapter ;
if ( ( Result = DXGIFactory - > EnumAdapterByLuid ( AdapterLuid , IID_PPV_ARGS ( Adapter . GetInitReference ( ) ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " DXGIFactory::EnumAdapterByLuid() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
uint32 DeviceFlags = 0 ;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_1 ;
D3D_FEATURE_LEVEL ActualFeatureLevel ;
if ( ( Result = D3D11CreateDevice (
Adapter ,
D3D_DRIVER_TYPE_UNKNOWN ,
NULL ,
DeviceFlags ,
& FeatureLevel ,
1 ,
D3D11_SDK_VERSION ,
FrameInfoD3D . EncoderDeviceD3D11 . GetInitReference ( ) ,
& ActualFeatureLevel ,
FrameInfoD3D . EncoderDeviceContextD3D11 . GetInitReference ( ) ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " D3D11CreateDevice() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
return false ;
}
if ( ActualFeatureLevel ! = D3D_FEATURE_LEVEL_11_1 )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " D3D11CreateDevice() - failed to create device w/ feature level 11.1 - needed to encode textures from D3D12. " ) ) ;
FrameInfoD3D . EncoderDeviceD3D11 . SafeRelease ( ) ;
FrameInfoD3D . EncoderDeviceContextD3D11 . SafeRelease ( ) ;
return false ;
}
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceD3D11 , " FVideoEncoderInputImpl " ) ;
DEBUG_SET_D3D11_OBJECT_NAME ( FrameInfoD3D . EncoderDeviceContextD3D11 , " FVideoEncoderInputImpl " ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
# endif
return false ;
}
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForCUDA ( void * InApplicationContext )
2021-11-23 01:47:46 -05:00
{
FrameInfoCUDA . EncoderContextCUDA = static_cast < CUcontext > ( InApplicationContext ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameFormat = EVideoFrameFormat : : CUDA_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
}
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2022-02-10 21:16:24 -05:00
bool FVideoEncoderInputImpl : : SetupForVulkan ( VkInstance InApplicationVulkanInstance , VkPhysicalDevice InApplicationVulkanPhysicalDevice , VkDevice InApplicationVulkanDevice )
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FrameInfoVulkan . VulkanInstance = InApplicationVulkanInstance ;
FrameInfoVulkan . VulkanPhysicalDevice = InApplicationVulkanPhysicalDevice ;
FrameInfoVulkan . VulkanDevice = InApplicationVulkanDevice ;
FrameFormat = EVideoFrameFormat : : VULKAN_R8G8B8A8_UNORM ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CollectAvailableEncoders ( ) ;
return true ;
}
# endif
// --- available encoders -------------------------------------------------------------------------
void FVideoEncoderInputImpl : : CollectAvailableEncoders ( )
{
AvailableEncoders . Empty ( ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
for ( const FVideoEncoderInfo & Info : FVideoEncoderFactory : : Get ( ) . GetAvailable ( ) )
{
if ( Info . SupportedInputFormats . Contains ( FrameFormat ) )
{
AvailableEncoders . Push ( Info ) ;
}
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
const TArray < FVideoEncoderInfo > & FVideoEncoderInputImpl : : GetAvailableEncoders ( )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
return AvailableEncoders ;
}
// --- encoder input frames -----------------------------------------------------------------------
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
bool FVideoEncoderInputImpl : : IsUserManagedFrame ( const FVideoEncoderInputFrame * InBuffer ) const
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
const FVideoEncoderInputFrameImpl * Frame = static_cast < const FVideoEncoderInputFrameImpl * > ( InBuffer ) ;
FScopeLock Guard ( & ProtectFrames ) ;
for ( int32 Index = UserManagedFrames . Num ( ) - 1 ; Index > = 0 ; - - Index )
{
if ( UserManagedFrames [ Index ] . Key = = Frame )
{
return true ;
}
}
return false ;
}
// create a user managed buffer
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrame * FVideoEncoderInputImpl : : CreateBuffer ( OnFrameReleasedCallback InOnFrameReleased )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
FVideoEncoderInputFrameImpl * Frame = CreateFrame ( ) ;
if ( Frame )
{
FScopeLock Guard ( & ProtectFrames ) ;
UserManagedFrames . Emplace ( Frame , MoveTemp ( InOnFrameReleased ) ) ;
}
return Frame ;
}
// destroy user managed buffer
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputImpl : : DestroyBuffer ( FVideoEncoderInputFrame * InBuffer )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
FVideoEncoderInputFrameImpl * Frame = static_cast < FVideoEncoderInputFrameImpl * > ( InBuffer ) ;
FScopeLock Guard ( & ProtectFrames ) ;
bool bAnythingRemoved = false ;
for ( int32 Index = UserManagedFrames . Num ( ) - 1 ; Index > = 0 ; - - Index )
{
if ( UserManagedFrames [ Index ] . Key = = Frame )
{
UserManagedFrames . RemoveAt ( Index ) ;
bAnythingRemoved = true ;
}
}
if ( bAnythingRemoved )
{
delete Frame ;
}
}
// --- encoder input frames -----------------------------------------------------------------------
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-10-10 01:07:51 -04:00
TSharedPtr < FVideoEncoderInputFrame > FVideoEncoderInputImpl : : ObtainInputFrame ( )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
2022-10-10 01:07:51 -04:00
TSharedPtr < FVideoEncoderInputFrameImpl > Frame ;
2021-11-23 01:47:46 -05:00
FScopeLock Guard ( & ProtectFrames ) ;
if ( ! AvailableFrames . IsEmpty ( ) )
{
AvailableFrames . Dequeue ( Frame ) ;
}
else
{
2022-10-10 01:07:51 -04:00
Frame = MakeShareable ( CreateFrame ( ) ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
UE_LOG ( LogVideoEncoder , Verbose , TEXT ( " Created new frame total frames: %d " ) , NumBuffers ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
2024-03-14 20:30:26 -04:00
2021-11-23 01:47:46 -05:00
ActiveFrames . Push ( Frame ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFrameID ( NextFrameID + + ) ;
if ( NextFrameID = = 0 )
{
+ + NextFrameID ; // skip 0 id
}
2022-10-10 01:07:51 -04:00
Frame - > Obtain ( ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2022-10-10 01:07:51 -04:00
return Frame ;
2021-11-23 01:47:46 -05:00
}
FVideoEncoderInputFrameImpl * FVideoEncoderInputImpl : : CreateFrame ( )
{
FVideoEncoderInputFrameImpl * Frame = new FVideoEncoderInputFrameImpl ( this ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
NumBuffers + + ;
switch ( FrameFormat )
{
case EVideoFrameFormat : : Undefined :
UE_LOG ( LogVideoEncoder , Error , TEXT ( " Got undefined frame format! " ) ) ;
break ;
case EVideoFrameFormat : : YUV420P :
SetupFrameYUV420P ( Frame ) ;
break ;
case EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM :
SetupFrameD3D11 ( Frame ) ;
break ;
case EVideoFrameFormat : : D3D12_R8G8B8A8_UNORM :
SetupFrameD3D12 ( Frame ) ;
break ;
case EVideoFrameFormat : : VULKAN_R8G8B8A8_UNORM :
SetupFrameVulkan ( Frame ) ;
break ;
case EVideoFrameFormat : : CUDA_R8G8B8A8_UNORM :
SetupFrameCUDA ( Frame ) ;
break ;
default :
check ( false ) ;
break ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
return Frame ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputImpl : : ReleaseInputFrame ( FVideoEncoderInputFrame * InFrame )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
FVideoEncoderInputFrameImpl * InFrameImpl = static_cast < FVideoEncoderInputFrameImpl * > ( InFrame ) ;
FScopeLock Guard ( & ProtectFrames ) ;
// check user managed buffers first
for ( const UserManagedFrame & Frame : UserManagedFrames )
{
if ( Frame . Key = = InFrameImpl )
{
Frame . Value ( InFrameImpl ) ;
return ;
}
}
2022-10-10 01:07:51 -04:00
TSharedPtr < FVideoEncoderInputFrameImpl > * InFramePtrPtr = ActiveFrames . FindByPredicate ( [ InFrameImpl ] ( TSharedPtr < FVideoEncoderInputFrameImpl > ActiveFrame ) { return ActiveFrame . Get ( ) = = InFrameImpl ; } ) ;
if ( ! InFramePtrPtr )
{
// releasing a non active frame. might be after we flushed or something. ignore it.
return ;
}
TSharedPtr < FVideoEncoderInputFrameImpl > InFramePtr = * InFramePtrPtr ;
int32 NumRemoved = ActiveFrames . Remove ( InFramePtr ) ;
2021-11-23 01:47:46 -05:00
check ( NumRemoved = = 1 ) ;
if ( NumRemoved > 0 )
{
// drop frame if format changed
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( InFrame - > GetFormat ( ) ! = FrameFormat )
{
ProtectFrames . Unlock ( ) ;
NumBuffers - - ;
UE_LOG ( LogVideoEncoder , Verbose , TEXT ( " Deleted buffer (format mismatch) total remaining: %d " ) , NumBuffers ) ;
return ;
}
if ( ! AvailableFrames . IsEmpty ( ) & & NumBuffers > MaxNumBuffers )
{
ProtectFrames . Unlock ( ) ;
NumBuffers - - ;
UE_LOG ( LogVideoEncoder , Verbose , TEXT ( " Deleted buffer (too many) total frames: %d " ) , NumBuffers ) ;
return ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
2022-10-10 01:07:51 -04:00
AvailableFrames . Enqueue ( InFramePtr ) ;
2021-11-23 01:47:46 -05:00
}
}
void FVideoEncoderInputImpl : : Flush ( )
{
2022-10-10 01:07:51 -04:00
FScopeLock ScopeLock ( & ProtectFrames ) ;
AvailableFrames . Empty ( ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2022-10-10 01:07:51 -04:00
NumBuffers = 0 ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
}
2024-03-14 20:30:26 -04:00
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputImpl : : SetupFrameYUV420P ( FVideoEncoderInputFrameImpl * Frame )
2021-10-26 09:13:01 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFormat ( EVideoFrameFormat : : YUV420P ) ;
FVideoEncoderInputFrame : : FYUV420P & YUV420P = Frame - > GetYUV420P ( ) ;
YUV420P . StrideY = FrameInfoYUV420P . StrideY ;
YUV420P . StrideU = FrameInfoYUV420P . StrideU ;
YUV420P . StrideV = FrameInfoYUV420P . StrideV ;
YUV420P . Data [ 0 ] = YUV420P . Data [ 1 ] = YUV420P . Data [ 2 ] = nullptr ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
void FVideoEncoderInputImpl : : SetupFrameD3D11 ( FVideoEncoderInputFrameImpl * Frame )
{
# if PLATFORM_WINDOWS
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFormat ( FrameFormat ) ;
2021-10-26 09:13:01 -04:00
FVideoEncoderInputFrame : : FD3D11 & Data = Frame - > GetD3D11 ( ) ;
Data . EncoderDevice = FrameInfoD3D . EncoderDeviceD3D11 ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-10-26 09:13:01 -04:00
# endif
2021-11-23 01:47:46 -05:00
}
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputImpl : : SetupFrameD3D12 ( FVideoEncoderInputFrameImpl * Frame )
{
2021-04-29 19:32:06 -04:00
# if PLATFORM_WINDOWS
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFormat ( FrameFormat ) ;
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
if ( FrameFormat = = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM )
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrame : : FD3D11 & Data = Frame - > GetD3D11 ( ) ;
Data . EncoderDevice = FrameInfoD3D . EncoderDeviceD3D11 ;
2021-04-29 19:32:06 -04:00
}
2021-11-23 01:47:46 -05:00
else
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrame : : FD3D12 & Data = Frame - > GetD3D12 ( ) ;
Data . EncoderDevice = FrameInfoD3D . EncoderDeviceD3D12 ;
2021-04-29 19:32:06 -04:00
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# endif
2021-04-29 19:32:06 -04:00
}
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputImpl : : SetupFrameVulkan ( FVideoEncoderInputFrameImpl * Frame )
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFormat ( FrameFormat ) ;
FVideoEncoderInputFrame : : FVulkan & Data = Frame - > GetVulkan ( ) ;
Data . EncoderDevice = FrameInfoVulkan . VulkanDevice ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# endif
}
void FVideoEncoderInputImpl : : SetupFrameCUDA ( FVideoEncoderInputFrameImpl * Frame )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Frame - > SetFormat ( FrameFormat ) ;
2024-03-14 20:30:26 -04:00
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrame : : FCUDA & Data = Frame - > GetCUDA ( ) ;
Data . EncoderDevice = FrameInfoCUDA . EncoderContextCUDA ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
// ---
# if PLATFORM_WINDOWS
TRefCountPtr < ID3D11Device > FVideoEncoderInputImpl : : GetD3D11EncoderDevice ( ) const
{
return FrameInfoD3D . EncoderDeviceD3D11 ;
}
TRefCountPtr < ID3D12Device > FVideoEncoderInputImpl : : GetD3D12EncoderDevice ( ) const
{
return FrameInfoD3D . EncoderDeviceD3D12 ;
}
# endif
CUcontext FVideoEncoderInputImpl : : GetCUDAEncoderContext ( ) const
{
return FrameInfoCUDA . EncoderContextCUDA ;
2021-04-29 19:32:06 -04:00
}
2021-10-26 09:13:01 -04:00
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2021-11-23 01:47:46 -05:00
void * FVideoEncoderInputImpl : : GetVulkanEncoderDevice ( ) const
2021-10-26 09:13:01 -04:00
{
2021-11-23 01:47:46 -05:00
return ( void * ) & FrameInfoVulkan ;
2021-10-26 09:13:01 -04:00
}
# endif
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
// *** FVideoEncoderInputFrame ********************************************************************
FVideoEncoderInputFrame : : FVideoEncoderInputFrame ( )
: FrameID ( 0 )
, TimestampUs ( 0 )
, TimestampRTP ( 0 )
, NumReferences ( 0 )
, Width ( 0 )
, Height ( 0 )
, bFreeYUV420PData ( false )
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
, Format ( EVideoFrameFormat : : Undefined )
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-05-25 02:43:26 -04:00
{
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrame : : FVideoEncoderInputFrame ( const FVideoEncoderInputFrame & CloneFrom )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
: FrameID ( CloneFrom . FrameID )
, TimestampUs ( CloneFrom . TimestampUs )
, TimestampRTP ( CloneFrom . TimestampRTP )
, NumReferences ( 0 )
, Width ( CloneFrom . Width )
, Height ( CloneFrom . Height )
, bFreeYUV420PData ( false )
2024-03-14 20:30:26 -04:00
, Format ( CloneFrom . Format )
2021-11-23 01:47:46 -05:00
{
# if PLATFORM_WINDOWS
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
D3D11 . EncoderDevice = CloneFrom . D3D11 . EncoderDevice ;
D3D11 . Texture = CloneFrom . D3D11 . Texture ;
if ( ( D3D11 . EncoderTexture = CloneFrom . D3D11 . EncoderTexture ) ! = nullptr )
{
D3D11 . EncoderTexture - > AddRef ( ) ;
}
D3D12 . EncoderDevice = CloneFrom . D3D12 . EncoderDevice ;
D3D12 . Texture = CloneFrom . D3D12 . Texture ;
if ( ( D3D12 . EncoderTexture = CloneFrom . D3D12 . EncoderTexture ) ! = nullptr )
{
D3D12 . EncoderTexture - > AddRef ( ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# endif
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
CUDA . EncoderDevice = CloneFrom . CUDA . EncoderDevice ;
CUDA . EncoderTexture = CloneFrom . CUDA . EncoderTexture ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
FVideoEncoderInputFrame : : ~ FVideoEncoderInputFrame ( )
2021-04-29 19:32:06 -04:00
{
if ( bFreeYUV420PData )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
delete [ ] YUV420P . Data [ 0 ] ;
delete [ ] YUV420P . Data [ 1 ] ;
delete [ ] YUV420P . Data [ 2 ] ;
2021-11-23 01:47:46 -05:00
YUV420P . Data [ 0 ] = YUV420P . Data [ 1 ] = YUV420P . Data [ 2 ] = nullptr ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
bFreeYUV420PData = false ;
}
# if PLATFORM_WINDOWS
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( D3D11 . EncoderTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
// check to make sure this frame holds the last reference
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
auto NumRef = D3D11 . EncoderTexture - > AddRef ( ) ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( NumRef > 2 )
{
UE_LOG ( LogVideoEncoder , Warning , TEXT ( " VideoEncoderFame - D3D11 input texture still holds %d references. " ) , NumRef ) ;
}
2021-11-26 03:04:55 -05:00
// Need to call release twice as we have added an extra reference just above (only way to count how many references we have)
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
D3D11 . EncoderTexture - > Release ( ) ;
D3D11 . EncoderTexture - > Release ( ) ;
D3D11 . EncoderTexture = nullptr ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( D3D11 . SharedHandle )
{
CloseHandle ( D3D11 . SharedHandle ) ;
D3D11 . SharedHandle = nullptr ;
}
if ( D3D11 . Texture & & OnReleaseD3D11Texture )
{
OnReleaseD3D11Texture ( D3D11 . Texture ) ;
}
if ( D3D12 . EncoderTexture )
{
// check to make sure this frame holds the last reference
auto NumRef = D3D12 . EncoderTexture - > AddRef ( ) ;
if ( NumRef > 2 )
{
UE_LOG ( LogVideoEncoder , Warning , TEXT ( " VideoEncoderFame - D3D12 input texture still holds %d references. " ) , NumRef ) ;
}
2021-11-26 03:04:55 -05:00
// Need to call release twice as we have added an extra reference just above (only way to count how many references we have)
2021-11-23 01:47:46 -05:00
D3D12 . EncoderTexture - > Release ( ) ;
D3D12 . EncoderTexture - > Release ( ) ;
D3D12 . EncoderTexture = nullptr ;
}
if ( D3D12 . Texture & & OnReleaseD3D12Texture )
{
OnReleaseD3D12Texture ( D3D12 . Texture ) ;
D3D12 . Texture = nullptr ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-26 03:04:55 -05:00
// D3D12 specific handle atm
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-26 03:04:55 -05:00
if ( CUDA . SharedHandle )
{
CloseHandle ( CUDA . SharedHandle ) ;
CUDA . SharedHandle = nullptr ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# endif
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( CUDA . EncoderTexture )
{
OnReleaseCUDATexture ( CUDA . EncoderTexture ) ;
CUDA . EncoderTexture = nullptr ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Vulkan . EncoderTexture ! = VK_NULL_HANDLE )
{
OnReleaseVulkanTexture ( Vulkan . EncoderTexture ) ;
}
if ( Vulkan . EncoderSurface )
{
OnReleaseVulkanSurface ( Vulkan . EncoderSurface ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
# endif
}
void FVideoEncoderInputFrame : : AllocateYUV420P ( )
{
if ( ! bFreeYUV420PData )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
YUV420P . StrideY = Width ;
YUV420P . StrideU = ( Width + 1 ) / 2 ;
YUV420P . StrideV = ( Width + 1 ) / 2 ; ;
YUV420P . Data [ 0 ] = new uint8 [ Height * YUV420P . StrideY ] ;
YUV420P . Data [ 1 ] = new uint8 [ ( Height + 1 ) / 2 * YUV420P . StrideU ] ;
YUV420P . Data [ 2 ] = new uint8 [ ( Height + 1 ) / 2 * YUV420P . StrideV ] ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
bFreeYUV420PData = true ;
}
}
void FVideoEncoderInputFrame : : SetYUV420P ( const uint8 * InDataY , const uint8 * InDataU , const uint8 * InDataV , uint32 InStrideY , uint32 InStrideU , uint32 InStrideV )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : YUV420P )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
if ( bFreeYUV420PData )
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
delete [ ] YUV420P . Data [ 0 ] ;
delete [ ] YUV420P . Data [ 1 ] ;
delete [ ] YUV420P . Data [ 2 ] ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
bFreeYUV420PData = false ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
YUV420P . Data [ 0 ] = InDataY ;
YUV420P . Data [ 1 ] = InDataU ;
YUV420P . Data [ 2 ] = InDataV ;
YUV420P . StrideY = InStrideY ;
YUV420P . StrideU = InStrideU ;
YUV420P . StrideV = InStrideV ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
}
}
static FThreadSafeCounter _VideoEncoderInputFrameCnt { 0 } ;
# if PLATFORM_WINDOWS
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputFrame : : SetTexture ( ID3D11Texture2D * InTexture , FReleaseD3D11TextureCallback InOnReleaseTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
check ( D3D11 . Texture = = nullptr ) ;
if ( ! D3D11 . Texture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
TRefCountPtr < IDXGIResource > DXGIResource ;
HANDLE SharedHandle ;
HRESULT Result = InTexture - > QueryInterface ( IID_PPV_ARGS ( DXGIResource . GetInitReference ( ) ) ) ;
if ( FAILED ( Result ) )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::QueryInterface() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
//
// NOTE : The HANDLE IDXGIResource::GetSharedHandle gives us is NOT an NT Handle, and therefre we should not call CloseHandle on it
//
else if ( ( Result = DXGIResource - > GetSharedHandle ( & SharedHandle ) ) ! = S_OK )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " IDXGIResource::GetSharedHandle() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
else if ( SharedHandle = = nullptr )
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " IDXGIResource::GetSharedHandle() failed to return a shared texture resource no created as shared? (D3D11_RESOURCE_MISC_SHARED). " ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
else if ( ( Result = D3D11 . EncoderDevice - > OpenSharedResource ( SharedHandle , __uuidof ( ID3D11Texture2D ) , ( LPVOID * ) & D3D11 . EncoderTexture ) ) ! = S_OK )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::OpenSharedResource() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
else
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
DEBUG_SET_D3D11_OBJECT_NAME ( D3D11 . EncoderTexture , " FVideoEncoderInputFrame::SetTexture() " ) ;
D3D11 . Texture = InTexture ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
OnReleaseD3D11Texture = InOnReleaseTexture ;
}
}
}
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputFrame : : SetTexture ( ID3D12Resource * InTexture , FReleaseD3D12TextureCallback InOnReleaseTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : D3D11_R8G8B8A8_UNORM )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
check ( D3D12 . Texture = = nullptr )
2024-03-14 20:30:26 -04:00
check ( D3D11 . EncoderTexture = = nullptr )
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
2024-03-14 20:30:26 -04:00
TRefCountPtr < ID3D12Device > OwnerDevice ;
2021-11-23 01:47:46 -05:00
HRESULT Result ;
if ( ( Result = InTexture - > GetDevice ( IID_PPV_ARGS ( OwnerDevice . GetInitReference ( ) ) ) ) ! = S_OK )
2021-04-29 19:32:06 -04:00
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::QueryInterface() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
//
2021-11-23 01:47:46 -05:00
// NOTE: ID3D12Device::CreateSharedHandle gives as an NT Handle, and so we need to call CloseHandle on it
2021-04-29 19:32:06 -04:00
//
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
else if ( ( Result = OwnerDevice - > CreateSharedHandle ( InTexture , NULL , GENERIC_ALL , * FString : : Printf ( TEXT ( " %s_FVideoEncoderInputFrame_%d " ) , * GetGUID ( ) , _VideoEncoderInputFrameCnt . Increment ( ) ) , & D3D11 . SharedHandle ) ) ! = S_OK )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D12Device::CreateSharedHandle() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
2021-04-29 19:32:06 -04:00
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
else if ( D3D11 . SharedHandle = = nullptr )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2021-11-23 01:47:46 -05:00
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D12Device::CreateSharedHandle() failed to return a shared texture resource no created as shared? (D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS). " ) ) ;
2021-04-29 19:32:06 -04:00
}
else
{
2021-11-23 01:47:46 -05:00
TRefCountPtr < ID3D11Device1 > Device1 ;
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( ( Result = D3D11 . EncoderDevice - > QueryInterface ( IID_PPV_ARGS ( Device1 . GetInitReference ( ) ) ) ) ! = S_OK )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::QueryInterface() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
else if ( ( Result = Device1 - > OpenSharedResource1 ( D3D11 . SharedHandle , IID_PPV_ARGS ( & D3D11 . EncoderTexture ) ) ) ! = S_OK )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
UE_LOG ( LogVideoEncoder , Error , TEXT ( " ID3D11Device::OpenSharedResource1() failed 0x%X - %s. " ) , Result , * GetComErrorDescription ( Result ) ) ;
}
else
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
DEBUG_SET_D3D11_OBJECT_NAME ( D3D11 . EncoderTexture , " FVideoEncoderInputFrame::SetTexture() " ) ;
D3D12 . Texture = InTexture ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
OnReleaseD3D12Texture = InOnReleaseTexture ;
}
2021-04-29 19:32:06 -04:00
}
}
2021-10-26 09:13:01 -04:00
else
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
check ( D3D12 . Texture = = nullptr ) ;
check ( D3D12 . EncoderTexture = = nullptr ) ;
D3D12 . Texture = InTexture ;
D3D12 . EncoderTexture = InTexture ;
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
OnReleaseD3D12Texture = InOnReleaseTexture ;
2021-04-29 19:32:06 -04:00
}
}
# endif
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-26 03:04:55 -05:00
void FVideoEncoderInputFrame : : SetTexture ( CUarray InTexture , EUnderlyingRHI UnderlyingRHI , void * SharedHandle , FReleaseCUDATextureCallback InOnReleaseTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : CUDA_R8G8B8A8_UNORM )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-26 03:04:55 -05:00
CUDA . UnderlyingRHI = UnderlyingRHI ;
CUDA . SharedHandle = SharedHandle ;
2021-11-23 01:47:46 -05:00
CUDA . EncoderTexture = InTexture ;
OnReleaseCUDATexture = InOnReleaseTexture ;
if ( ! CUDA . EncoderTexture )
{
UE_LOG ( LogVideoEncoder , Warning , TEXT ( " SetTexture | Cuda device pointer is null " ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
}
}
2021-10-26 09:13:01 -04:00
# if PLATFORM_DESKTOP && !PLATFORM_APPLE
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputFrame : : SetTexture ( VkImage InTexture , FReleaseVulkanTextureCallback InOnReleaseTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-05-25 02:43:26 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : VULKAN_R8G8B8A8_UNORM )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-05-25 02:43:26 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Vulkan . EncoderTexture = InTexture ;
OnReleaseVulkanTexture = InOnReleaseTexture ;
if ( ! Vulkan . EncoderTexture )
{
UE_LOG ( LogVideoEncoder , Warning , TEXT ( " SetTexture | Vulkan VkImage is null " ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-05-25 02:43:26 -04:00
}
}
2021-10-26 09:13:01 -04:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputFrame : : SetTexture ( VkImage InTexture , VkDeviceMemory InTextureDeviceMemory , uint64 InTextureMemorySize , FReleaseVulkanTextureCallback InOnReleaseTexture )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-10-26 09:13:01 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
if ( Format = = EVideoFrameFormat : : VULKAN_R8G8B8A8_UNORM )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-10-26 09:13:01 -04:00
{
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
Vulkan . EncoderTexture = InTexture ;
Vulkan . EncoderDeviceMemory = InTextureDeviceMemory ;
Vulkan . EncoderMemorySize = InTextureMemorySize ;
OnReleaseVulkanTexture = InOnReleaseTexture ;
if ( ! Vulkan . EncoderTexture | | ! InTextureDeviceMemory )
{
UE_LOG ( LogVideoEncoder , Warning , TEXT ( " SetTexture | Vulkan VkImage or VkTextureDeviceMemory is null " ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-10-26 09:13:01 -04:00
}
}
2021-05-25 02:43:26 -04:00
# endif
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
// *** FVideoEncoderInputFrameImpl ****************************************************************
2021-04-29 19:32:06 -04:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrameImpl : : FVideoEncoderInputFrameImpl ( FVideoEncoderInputImpl * InInput )
: Input ( InInput )
2021-04-29 19:32:06 -04:00
{
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrameImpl : : FVideoEncoderInputFrameImpl ( const FVideoEncoderInputFrameImpl & InCloneFrom , FCloneDestroyedCallback InCloneDestroyedCallback )
: FVideoEncoderInputFrame ( InCloneFrom )
, Input ( InCloneFrom . Input )
, ClonedReference ( InCloneFrom . Obtain ( ) )
, OnCloneDestroyed ( MoveTemp ( InCloneDestroyedCallback ) )
{
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
FVideoEncoderInputFrameImpl : : ~ FVideoEncoderInputFrameImpl ( )
2021-04-29 19:32:06 -04:00
{
if ( ClonedReference )
{
2021-11-23 01:47:46 -05:00
ClonedReference - > Release ( ) ;
2021-04-29 19:32:06 -04:00
}
else
{
}
}
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-04-29 19:32:06 -04:00
2021-11-23 01:47:46 -05:00
void FVideoEncoderInputFrameImpl : : Release ( ) const
{
// User managed frames get released without checking reference count, as the reference count doesn't matter for them
if ( Input - > IsUserManagedFrame ( this ) )
{
Input - > ReleaseInputFrame ( const_cast < FVideoEncoderInputFrameImpl * > ( this ) ) ;
}
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
else if ( NumReferences . Decrement ( ) = = 0 )
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
if ( ClonedReference )
{
OnCloneDestroyed ( this ) ;
delete this ;
}
else
{
Input - > ReleaseInputFrame ( const_cast < FVideoEncoderInputFrameImpl * > ( this ) ) ;
}
}
}
// Clone frame - this will create a copy that references the original until destroyed
2024-03-14 20:30:26 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
const FVideoEncoderInputFrame * FVideoEncoderInputFrameImpl : : Clone ( FCloneDestroyedCallback InCloneDestroyedCallback ) const
2024-03-14 20:30:26 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2021-11-23 01:47:46 -05:00
{
FVideoEncoderInputFrameImpl * ClonedFrame = new FVideoEncoderInputFrameImpl ( * this , MoveTemp ( InCloneDestroyedCallback ) ) ;
return ClonedFrame ;
}
2021-04-29 19:32:06 -04:00
} /* namespace AVEncoder */