// Copyright Epic Games, Inc. All Rights Reserved. #include "VideoDecoderH264_Dummy.h" #ifdef AVENCODER_VIDEO_DECODER_AVAILABLE_H264_DUMMY namespace AVEncoder { PRAGMA_DISABLE_DEPRECATION_WARNINGS class FVideoDecoderOutputDummy : public FVideoDecoderOutput PRAGMA_ENABLE_DEPRECATION_WARNINGS { public: PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderOutputDummy(int32 w, int32 h, int64 pts) : Width(w), Height(h), PTS(pts) {} PRAGMA_ENABLE_DEPRECATION_WARNINGS PRAGMA_DISABLE_DEPRECATION_WARNINGS virtual ~FVideoDecoderOutputDummy() { } PRAGMA_ENABLE_DEPRECATION_WARNINGS virtual int32 AddRef() override { return FPlatformAtomics::InterlockedIncrement(&RefCount); } virtual int32 Release() override { int32 c = FPlatformAtomics::InterlockedDecrement(&RefCount); // We do not release the allocated buffer from the application here. // This is meant to release only what the decoder uses internally, but not the // external buffers the application is working with! if (c == 0) { delete this; } return c; } virtual int32 GetWidth() const override { return Width; } virtual int32 GetHeight() const override { return Height; } virtual int64 GetPTS() const override { return PTS; } PRAGMA_DISABLE_DEPRECATION_WARNINGS virtual const FVideoDecoderAllocFrameBufferResult* GetAllocatedBuffer() const PRAGMA_ENABLE_DEPRECATION_WARNINGS { return &Buffer; } virtual int32 GetCropLeft() const override { return 0; } virtual int32 GetCropRight() const override { return 0; } virtual int32 GetCropTop() const override { return 0; } virtual int32 GetCropBottom() const override { return 0; } virtual int32 GetAspectX() const override { return 1; } virtual int32 GetAspectY() const override { return 1; } virtual int32 GetPitchX() const override { return Width; } virtual int32 GetPitchY() const override { return Height; } virtual uint32 GetColorFormat() const override { return 0; } // Internal for allocation. PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderAllocFrameBufferResult* GetBuffer() PRAGMA_ENABLE_DEPRECATION_WARNINGS { return &Buffer; } private: PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderAllocFrameBufferResult Buffer = {}; PRAGMA_ENABLE_DEPRECATION_WARNINGS int32 RefCount = 1; int32 Width = 0; int32 Height = 0; int64 PTS = 0; }; // query whether or not encoder is supported and available // static bool GetIsAvailable(FVideoEncoderInputImpl& InInput, FVideoEncoderInfo& OutEncoderInfo); PRAGMA_DISABLE_DEPRECATION_WARNINGS void FVideoDecoderH264_Dummy::Register(FVideoDecoderFactory& InFactory) PRAGMA_ENABLE_DEPRECATION_WARNINGS { PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderInfo DecoderInfo; DecoderInfo.CodecType = ECodecType::H264; DecoderInfo.MaxWidth = 1920; DecoderInfo.MaxHeight = 1088; PRAGMA_ENABLE_DEPRECATION_WARNINGS PRAGMA_DISABLE_DEPRECATION_WARNINGS InFactory.Register(DecoderInfo, []() { return new FVideoDecoderH264_Dummy(); }); PRAGMA_ENABLE_DEPRECATION_WARNINGS } PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderH264_Dummy::FVideoDecoderH264_Dummy() { } PRAGMA_ENABLE_DEPRECATION_WARNINGS PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoderH264_Dummy::~FVideoDecoderH264_Dummy() { } PRAGMA_ENABLE_DEPRECATION_WARNINGS PRAGMA_DISABLE_DEPRECATION_WARNINGS bool FVideoDecoderH264_Dummy::Setup(const FVideoDecoder::FInit& InInit) PRAGMA_ENABLE_DEPRECATION_WARNINGS { PRAGMA_DISABLE_DEPRECATION_WARNINGS CreateDecoderAllocationInterfaceFN = InInit.CreateDecoderAllocationInterface; ReleaseDecoderAllocationInterfaceFN = InInit.ReleaseDecoderAllocationInterface; PRAGMA_ENABLE_DEPRECATION_WARNINGS return true; } void FVideoDecoderH264_Dummy::Shutdown() { if (bIsInitialized) { PRAGMA_DISABLE_DEPRECATION_WARNINGS ReleaseDecoderAllocationInterface(); PRAGMA_ENABLE_DEPRECATION_WARNINGS bIsInitialized = false; } delete this; } PRAGMA_DISABLE_DEPRECATION_WARNINGS FVideoDecoder::EDecodeResult FVideoDecoderH264_Dummy::Decode(const FVideoDecoderInput* InInput) PRAGMA_ENABLE_DEPRECATION_WARNINGS { // Lazily initialize the decoder. if (!bIsInitialized) { PRAGMA_DISABLE_DEPRECATION_WARNINGS bIsInitialized = CreateDecoderAllocationInterface(); PRAGMA_ENABLE_DEPRECATION_WARNINGS } // PRAGMA_DISABLE_DEPRECATION_WARNINGS if (OnDecodedFrame) PRAGMA_ENABLE_DEPRECATION_WARNINGS { if (bIsInitialized) { PRAGMA_DISABLE_DEPRECATION_WARNINGS int32_t Width = InInput->GetWidth(); int32_t Height = InInput->GetHeight(); TUniquePtr pNew(new FVideoDecoderOutputDummy(Width, Height, InInput->GetPTS())); // Get memory from the application FVideoDecoderAllocFrameBufferParams ap {}; EFrameBufferAllocReturn ar; ap.FrameBufferType = EFrameBufferType::CODEC_RawBuffer; ap.AllocSize = Width * Height * 3 / 2; ap.AllocAlignment = 16; ap.AllocFlags = 0; ap.Width = Width; ap.Height = Height; ap.BytesPerPixel = 1; ar = AllocateOutputFrameBuffer(pNew->GetBuffer(), &ap); if (ar == EFrameBufferAllocReturn::CODEC_Success) { // Got an output buffer. check(pNew->GetBuffer()->AllocatedBuffer); } else if (ar == EFrameBufferAllocReturn::CODEC_TryAgainLater) { check(!"TODO"); return FVideoDecoder::EDecodeResult::Failure; // return FVideoDecoder::EDecodeResult::TryAgainLater; } else { // Error! return FVideoDecoder::EDecodeResult::Failure; } PRAGMA_ENABLE_DEPRECATION_WARNINGS // Buffer needs to contain an NV12 texture. int32 ySize = Width * Height; PRAGMA_DISABLE_DEPRECATION_WARNINGS uint8* pY = (uint8*)pNew->GetBuffer()->AllocatedBuffer; PRAGMA_ENABLE_DEPRECATION_WARNINGS uint8* pUV = pY + ySize; FMemory::Memset(pUV, 128, ySize / 2); int C = ++YOffset; for(int32 y=0,yMax=Height; y