Files
UnrealEngine/Engine/Source/Runtime/AVEncoder/Private/Decoders/vdecmpeg4/M4Vid.cpp
2025-05-18 13:04:45 +08:00

200 lines
4.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include <stdio.h>
#include "vdecmpeg4.h"
#include "M4Decoder.h"
#include "M4Image.h"
namespace vdecmpeg4
{
// ----------------------------------------------------------------------------
/**
* Create new decoder instance based on setup parameters
*
* @param setup
* @param pNewDecoder
*
* @return
*/
VIDError VIDCreateDecoder(const VIDDecoderSetup* setup, VIDDecoder* pNewDecoder)
{
M4CHECK(pNewDecoder);
M4CHECK(setup);
M4CHECK(setup->cbMemAlloc);
M4CHECK(setup->cbMemFree);
M4MemHandler tmpHandler;
M4Decoder* decoder;
VIDError error = VID_OK;
*pNewDecoder = nullptr;
int16 sw = setup->width;
int16 sh = setup->height;
// Do some checks about the size of the input image
if (((sw & 0xf) != 0) || ((sh & 0xf) != 0))
{
return VID_ERROR_WIDTH_OR_HEIGHT_NOT_MULTIPLE_OF_16;
}
if ((sw>0 && sw<32) || (sh>0 && sh<32))
{
return VID_ERROR_WIDTH_OR_HEIGHT_LESS_THAN_32;
}
if (sw>1920 || sh>1088)
{
return VID_ERROR_INVALID_WIDTH_OR_HEIGHT;
}
tmpHandler.init(setup->cbMemAlloc, setup->cbMemFree);
if ((decoder = M4Decoder::create(tmpHandler)) == nullptr)
{
return VID_ERROR_OUT_OF_MEMORY;
}
decoder->mCbPrintf = setup->cbReport;
// Init decoder
error = decoder->init(setup);
if (error == VID_OK)
{
// If we have some initial size we perform a full buffer alloc here. Otherwise this is delayed
// until we know this data from the stream
if (sw != 0 && sh != 0)
{
error = decoder->initBuffers(sw, sh);
}
if (error == VID_OK)
{
*pNewDecoder = decoder;
return VID_OK;
}
}
M4Decoder::destroy(decoder, tmpHandler);
return error;
}
// ----------------------------------------------------------------------------
/**
* Destroy decoder instance
*
* @param dec
*/
void VIDDestroyDecoder(VIDDecoder dec)
{
M4CHECK(dec);
M4Decoder* decoder = (M4Decoder*)dec;
M4MemHandler tmpHandler = decoder->mMemSys;
M4Decoder::destroy(decoder, tmpHandler);
}
// ----------------------------------------------------------------------------
/**
* Return frame info
*
* @param _pImage
*
* @return
*/
const VIDImageInfo* VIDGetFrameInfo(const VIDImage* _pImage)
{
M4CHECK(_pImage);
M4Image* pImage = (M4Image*)_pImage->_private;
return &pImage->mImageInfo;
}
// ----------------------------------------------------------------------------
/**
* Enable bmp output of decoded frames
*
* @param dec
* @param pBaseName
*/
void VIDDebugVideoOutToBMP(VIDDecoder dec, const char *pBaseName)
{
#ifdef _M4_ENABLE_BMP_OUT
M4CHECK(dec);
M4Decoder* decoder = (M4Decoder*)dec;
decoder->SetVideoOutToBMP(pBaseName);
#else
(void)dec;
(void)pBaseName;
#endif
}
// ----------------------------------------------------------------------------
/**
* Attach a stream to the decoder
*
* @param decoder
* @param pStream
* @param pEvents
*
* @return none
*/
VIDError VIDStreamSet(VIDDecoder decoder, VIDStreamIO* pStream, VIDStreamEvents* pEvents)
{
M4Decoder* pDecoder = (M4Decoder*)decoder;
M4CHECK(pDecoder);
return pDecoder->StreamSet(pStream, pEvents);
}
// ----------------------------------------------------------------------------
/**
* Handle stream processing
*
* @param decoder
* @param time
* @param result
*
* @return none
*/
VIDError VIDStreamDecode(VIDDecoder decoder, float time, const VIDImage** result)
{
M4Decoder* pDecoder = (M4Decoder*)decoder;
M4CHECK(pDecoder);
return pDecoder->StreamDecode(time, result);
}
// ----------------------------------------------------------------------------
/**
* Set event sink explicitely
*
* @param decoder
* @param pEvents
*
* @return none
*/
VIDError VIDStreamEventsSet(VIDDecoder decoder, VIDStreamEvents* pEvents)
{
M4Decoder* pDecoder = (M4Decoder*)decoder;
M4CHECK(pDecoder);
return pDecoder->StreamEventsSet(pEvents);
}
// ----------------------------------------------------------------------------
/**
* Handle seek notify
*
* @param decoder
*
* @return none
*/
VIDError VIDStreamSeekNotify(VIDDecoder decoder)
{
M4Decoder* pDecoder = (M4Decoder*)decoder;
M4CHECK(pDecoder);
return pDecoder->StreamSeekNotify();
}
}