You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
216 lines
6.7 KiB
C
216 lines
6.7 KiB
C
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||
|
|
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "CoreMinimal.h"
|
||
|
|
#include "VideoCommon.h"
|
||
|
|
|
||
|
|
#if WITH_CUDA
|
||
|
|
#include "CudaModule.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if PLATFORM_WINDOWS
|
||
|
|
struct ID3D11Device;
|
||
|
|
struct ID3D11Texture2D;
|
||
|
|
struct ID3D12Device;
|
||
|
|
struct ID3D12Resource;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
namespace AVEncoder
|
||
|
|
{
|
||
|
|
class FVideoEncoderInputFrame;
|
||
|
|
|
||
|
|
|
||
|
|
class AVENCODER_API FVideoEncoderInput
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
// --- construct video encoder input based on expected input frame format
|
||
|
|
static TSharedPtr<FVideoEncoderInput> CreateDummy(uint32 InWidth, uint32 InHeight, bool isResizable = false);
|
||
|
|
static TSharedPtr<FVideoEncoderInput> CreateForYUV420P(uint32 InWidth, uint32 InHeight, bool isResizable = false);
|
||
|
|
|
||
|
|
// create input for an encoder that encodes a D3D11 texture
|
||
|
|
static TSharedPtr<FVideoEncoderInput> CreateForD3D11(void* InApplicationD3D11Device, uint32 InWidth, uint32 InHeight, bool isResizable = false);
|
||
|
|
|
||
|
|
// create input for an encoder that encodes a D3D12 texture in the context of a D3D11 device (i.e. nvenc)
|
||
|
|
static TSharedPtr<FVideoEncoderInput> CreateForD3D12(void* InApplicationD3D12Device, uint32 InWidth, uint32 InHeight, bool isResizable = false);
|
||
|
|
|
||
|
|
// create input for an encoder that encodes a Vulkan External Texture in the context of a CUDA context (for nvenc)
|
||
|
|
static TSharedPtr<FVideoEncoderInput> CreateForCUDA(void* InApplicationCudaContext, uint32 InWidth, uint32 InHeight, bool isResizable = false);
|
||
|
|
|
||
|
|
// --- properties
|
||
|
|
virtual void SetResolution(uint32 InWidth, uint32 InHeight);
|
||
|
|
|
||
|
|
EVideoFrameFormat GetFrameFormat() const { return FrameFormat; }
|
||
|
|
|
||
|
|
// --- available encoders
|
||
|
|
|
||
|
|
// get a list of supported video encoders
|
||
|
|
virtual const TArray<FVideoEncoderInfo>& GetAvailableEncoders() = 0;
|
||
|
|
|
||
|
|
// --- create encoders
|
||
|
|
|
||
|
|
// --- encoder input frames - user managed
|
||
|
|
|
||
|
|
// new packet callback prototype void(uint32 LayerIndex, const FCodecPacket& Packet)
|
||
|
|
using OnFrameReleasedCallback = TFunction<void(const FVideoEncoderInputFrame* /* InReleasedFrame */)>;
|
||
|
|
|
||
|
|
// create a user managed buffer
|
||
|
|
virtual FVideoEncoderInputFrame* CreateBuffer(OnFrameReleasedCallback InOnFrameReleased) = 0;
|
||
|
|
|
||
|
|
// destroy user managed buffer
|
||
|
|
virtual void DestroyBuffer(FVideoEncoderInputFrame* Buffer) = 0;
|
||
|
|
|
||
|
|
// --- encoder input frames - managed by this object
|
||
|
|
|
||
|
|
// obtain a video frame that can be used as a buffer for input to a video encoder
|
||
|
|
virtual FVideoEncoderInputFrame* ObtainInputFrame() = 0;
|
||
|
|
|
||
|
|
// release (free) an input frame and make it available for future use
|
||
|
|
virtual void ReleaseInputFrame(FVideoEncoderInputFrame* InFrame) = 0;
|
||
|
|
|
||
|
|
// destroy/release any frames that are not currently in use
|
||
|
|
virtual void Flush() = 0;
|
||
|
|
|
||
|
|
protected:
|
||
|
|
FVideoEncoderInput() = default;
|
||
|
|
virtual ~FVideoEncoderInput() = default;
|
||
|
|
FVideoEncoderInput(const FVideoEncoderInput&) = delete;
|
||
|
|
FVideoEncoderInput& operator=(const FVideoEncoderInput&) = delete;
|
||
|
|
|
||
|
|
EVideoFrameFormat FrameFormat = EVideoFrameFormat::Undefined;
|
||
|
|
uint32 Width;
|
||
|
|
uint32 Height;
|
||
|
|
|
||
|
|
bool bIsResizable = false;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
// TODO this should go elsewhere and be made cross platform
|
||
|
|
class AVENCODER_API FVideoEncoderInputFrame
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
// Obtain (increase reference count) of this input frame
|
||
|
|
const FVideoEncoderInputFrame* Obtain() const { NumReferences.Increment(); return this; }
|
||
|
|
// Release (decrease reference count) of this input frame
|
||
|
|
virtual void Release() const = 0;
|
||
|
|
|
||
|
|
// the callback type used to create a registered encoder
|
||
|
|
using FCloneDestroyedCallback = TFunction<void(const FVideoEncoderInputFrame* /* InCloneAboutToBeDestroyed */)>;
|
||
|
|
|
||
|
|
// Clone frame - this will create a copy that references the original until destroyed
|
||
|
|
virtual const FVideoEncoderInputFrame* Clone(FCloneDestroyedCallback InCloneDestroyedCallback) const = 0;
|
||
|
|
|
||
|
|
// an ID that will stay constant as long as the frame buffer exists
|
||
|
|
uint32 GetFrameID() const { return FrameID; }
|
||
|
|
|
||
|
|
// current format of frame
|
||
|
|
EVideoFrameFormat GetFormat() const { return Format; }
|
||
|
|
// width of frame buffer
|
||
|
|
uint32 GetWidth() const { return Width; }
|
||
|
|
// height of frame buffer
|
||
|
|
uint32 GetHeight() const { return Height; }
|
||
|
|
|
||
|
|
TFunction<void()> OnTextureEncode;
|
||
|
|
|
||
|
|
int64 PTS = 0; // presentation time stamp (within TimeBase)
|
||
|
|
|
||
|
|
// --- YUV420P
|
||
|
|
|
||
|
|
struct FYUV420P
|
||
|
|
{
|
||
|
|
const uint8* Data[3] = { nullptr, nullptr, nullptr };
|
||
|
|
uint32 StrideY = 0;
|
||
|
|
uint32 StrideU = 0;
|
||
|
|
uint32 StrideV = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
const FYUV420P& GetYUV420P() const { return YUV420P; }
|
||
|
|
FYUV420P& GetYUV420P() { return YUV420P; }
|
||
|
|
void SetYUV420P(const uint8* InDataY, const uint8* InDataU, const uint8* InDataV, uint32 InStrideY, uint32 InStrideU, uint32 InStrideV);
|
||
|
|
|
||
|
|
#if PLATFORM_WINDOWS
|
||
|
|
// --- D3D11
|
||
|
|
|
||
|
|
struct FD3D11
|
||
|
|
{
|
||
|
|
ID3D11Texture2D* Texture = nullptr;
|
||
|
|
ID3D11Device* EncoderDevice = nullptr;
|
||
|
|
ID3D11Texture2D* EncoderTexture = nullptr;
|
||
|
|
void* SharedHandle = nullptr;
|
||
|
|
};
|
||
|
|
|
||
|
|
const FD3D11& GetD3D11() const { return D3D11; }
|
||
|
|
FD3D11& GetD3D11() { return D3D11; }
|
||
|
|
|
||
|
|
// the callback type used to create a registered encoder
|
||
|
|
using FReleaseD3D11TextureCallback = TFunction<void(ID3D11Texture2D*)>;
|
||
|
|
|
||
|
|
void SetTexture(ID3D11Texture2D* InTexture, FReleaseD3D11TextureCallback InOnReleaseD3D11Texture);
|
||
|
|
|
||
|
|
// --- D3D12
|
||
|
|
|
||
|
|
struct FD3D12
|
||
|
|
{
|
||
|
|
ID3D12Resource* Texture = nullptr;
|
||
|
|
ID3D12Device* EncoderDevice = nullptr;
|
||
|
|
ID3D12Resource* EncoderTexture = nullptr;
|
||
|
|
};
|
||
|
|
|
||
|
|
const FD3D12& GetD3D12() const { return D3D12; }
|
||
|
|
FD3D12& GetD3D12() { return D3D12; }
|
||
|
|
|
||
|
|
// the callback type used to create a registered encoder
|
||
|
|
using FReleaseD3D12TextureCallback = TFunction<void(ID3D12Resource*)>;
|
||
|
|
|
||
|
|
void SetTexture(ID3D12Resource* InTexture, FReleaseD3D12TextureCallback InOnReleaseD3D11Texture);
|
||
|
|
|
||
|
|
#endif // PLATFORM_WINDOWS
|
||
|
|
|
||
|
|
#if WITH_CUDA
|
||
|
|
|
||
|
|
// --- CUDA
|
||
|
|
struct FCUDA
|
||
|
|
{
|
||
|
|
CUarray EncoderTexture;
|
||
|
|
CUcontext EncoderDevice;
|
||
|
|
};
|
||
|
|
|
||
|
|
const FCUDA& GetCUDA() const { return CUDA; }
|
||
|
|
FCUDA& GetCUDA() { return CUDA; }
|
||
|
|
|
||
|
|
// the callback type used to create a registered encoder
|
||
|
|
using FReleaseCUDATextureCallback = TFunction<void(CUarray)>;
|
||
|
|
|
||
|
|
void SetTexture(CUarray InTexture, FReleaseCUDATextureCallback InOnReleaseTexture);
|
||
|
|
|
||
|
|
#endif // WITH_CUDA
|
||
|
|
|
||
|
|
protected:
|
||
|
|
FVideoEncoderInputFrame();
|
||
|
|
explicit FVideoEncoderInputFrame(const FVideoEncoderInputFrame& CloneFrom);
|
||
|
|
virtual ~FVideoEncoderInputFrame();
|
||
|
|
|
||
|
|
uint32 FrameID;
|
||
|
|
mutable FThreadSafeCounter NumReferences;
|
||
|
|
EVideoFrameFormat Format;
|
||
|
|
uint32 Width;
|
||
|
|
uint32 Height;
|
||
|
|
FYUV420P YUV420P;
|
||
|
|
bool bFreeYUV420PData;
|
||
|
|
#if PLATFORM_WINDOWS
|
||
|
|
FD3D11 D3D11;
|
||
|
|
FReleaseD3D11TextureCallback OnReleaseD3D11Texture;
|
||
|
|
FD3D12 D3D12;
|
||
|
|
FReleaseD3D12TextureCallback OnReleaseD3D12Texture;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if WITH_CUDA
|
||
|
|
FCUDA CUDA;
|
||
|
|
FReleaseCUDATextureCallback OnReleaseCUDATexture;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
} /* namespace AVEncoder */
|