mp4vdfmt.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 719 行 · 第 1/2 页
CPP
719 行
pDecodedPacket->dataLength = NULL;
}
}
/****************************************************************************
* Method:
* CMP4VideoFormat::CreateDecodedPacket
*
*/
CMediaPacket* CMP4VideoFormat::CreateDecodedPacket(CMediaPacket* pFrameToDecode)
{
HXCODEC_DATA oldDecodedPacket;
HXCODEC_DATA* pDecodedPacket = NULL;
CMediaPacket* pDecodedFrame = NULL;
UINT8* pData = NULL;
HX_ASSERT(pFrameToDecode);
#if defined(HELIX_FEATURE_VIDEO_MPEG4_DISCARD_LATE_ENCODED_FRAMES)
// discard late frames before they are decoded
if (m_pMP4VideoRenderer->IsActive())
{
LONG32 lTimeAhead;
lTimeAhead = m_pMP4VideoRenderer->ComputeTimeAhead(
pFrameToDecode->m_ulTime,
0);
if (lTimeAhead < MAX_NONKEY_CODED_FRAME_FALLBEHIND)
{
// Throw away this frame
pFrameToDecode->Clear();
delete pFrameToDecode;
pFrameToDecode = NULL;
#if defined(HELIX_FEATURE_STATS)
m_pMP4VideoRenderer->ReportDroppedFrame();
#endif /* #if defined(HELIX_FEATURE_STATS) */
}
}
#endif // HELIX_FEATURE_VIDEO_MPEG4_DISCARD_LATE_ENCODED_FRAMES
if (m_DecodedPacket.data)
{
oldDecodedPacket = m_DecodedPacket;
m_DecodedPacket.data = NULL;
m_DecodedPacket.dataLength = 0;
pDecodedPacket = &oldDecodedPacket;
}
m_pMP4VideoRenderer->BltIfNeeded();
if (pFrameToDecode)
ProcessAssembledFrame(pFrameToDecode);
if (pFrameToDecode &&
m_pDecoder->Decode(pFrameToDecode, MAX_DECODE_QUALITY) == HXR_OK)
{
if ((pDecodedPacket == NULL) && (m_DecodedPacket.data))
{
pDecodedPacket = &m_DecodedPacket;
}
#if !defined(HELIX_FEATURE_VIDEO_MPEG4_DISCARD_LATE_ENCODED_FRAMES)
if (pDecodedPacket)
{
if (m_pMP4VideoRenderer->ComputeTimeAhead(
pDecodedPacket->timestamp,
0)
< NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD)
{
ReleaseDecodedPacket(pDecodedPacket);
pDecodedPacket = NULL;
}
}
#endif // HELIX_FEATURE_VIDEO_MPEG4_DISCARD_LATE_ENCODED_FRAMES
if (pDecodedPacket)
{
CMediaPacket* pVideoPacket = NULL;
HXxSize* pSampleDesc = NULL;
// Obtain frame dimensions if not set
if (m_DecoderDims.cx == 0)
{
HX_FORMAT_IMAGE imageInfo;
if (m_pDecoder->GetImageInfo(imageInfo) == HXR_OK)
{
pSampleDesc = new HXxSize;
if (pSampleDesc)
{
pSampleDesc->cx = m_DecoderDims.cx = imageInfo.uiWidth;
pSampleDesc->cy = m_DecoderDims.cy = imageInfo.uiHeight;
m_pMP4VideoRenderer->ResizeViewFrame(m_DecoderDims);
}
}
}
// Form decoded media packets if dimensions set
if (m_DecoderDims.cx != 0)
{
pVideoPacket = (CMediaPacket*) m_pFramePool->Get(0);
if (pVideoPacket == NULL)
{
pVideoPacket = pFrameToDecode;
pFrameToDecode = NULL;
}
if (pVideoPacket)
{
pVideoPacket->SetBuffer(pDecodedPacket->data,
pDecodedPacket->data,
pDecodedPacket->dataLength,
pDecodedPacket->dataLength,
FALSE);
pVideoPacket->Init(pDecodedPacket->data,
pDecodedPacket->dataLength,
pDecodedPacket->timestamp,
pDecodedPacket->flags,
pSampleDesc);
pVideoPacket->SetSampleDescKiller(KillMP4VSampleDesc);
pVideoPacket->SetBufferKiller(KillOutputBuffer);
pVideoPacket->m_pUserData = m_pMP4VideoRenderer;
pDecodedPacket->data = NULL;
pDecodedPacket->dataLength = 0;
pDecodedPacket = NULL;
pSampleDesc = NULL;
pDecodedFrame = pVideoPacket;
pVideoPacket = NULL;
}
}
if (pVideoPacket)
{
delete pVideoPacket;
}
if (pSampleDesc)
{
delete pSampleDesc;
}
}
}
if (pFrameToDecode != NULL)
{
pFrameToDecode->Clear();
delete pFrameToDecode;
}
if (pDecodedPacket)
{
ReleaseDecodedPacket(pDecodedPacket);
}
return pDecodedFrame;
}
CMP4VDecoder* CMP4VideoFormat::CreateDecoder()
{
return new CMP4VDecoder();
}
/****************************************************************************
* Method:
* CMP4VideoFormat::DecodeDone
*/
HX_RESULT CMP4VideoFormat::DecodeDone(HXCODEC_DATA* pData)
{
HX_RESULT retVal = HXR_OK;
m_pMP4VideoRenderer->BltIfNeeded();
if (pData)
{
HX_ASSERT(m_DecodedPacket.data == NULL);
retVal = HXR_UNEXPECTED;
if (m_DecodedPacket.data == NULL)
{
m_DecodedPacket = *pData;
retVal = HXR_OK;
}
}
return retVal;
}
/****************************************************************************
* Method:
* CMP4VideoFormat::IsBitmapFormatChanged
*
*/
BOOL CMP4VideoFormat::IsBitmapFormatChanged(
HXBitmapInfoHeader &BitmapInfoHeader,
CMediaPacket* pVideoPacket)
{
if (pVideoPacket->m_pSampleDesc != NULL)
{
HXxSize* pDims = (HXxSize*) pVideoPacket->m_pSampleDesc;
if ((BitmapInfoHeader.biWidth != pDims->cx) ||
(BitmapInfoHeader.biHeight != pDims->cy))
{
return TRUE;
}
}
return FALSE;
}
/****************************************************************************
* Method:
* CMP4VideoFormat::InitBitmapInfoHeader
*/
HX_RESULT CMP4VideoFormat::InitBitmapInfoHeader(
HXBitmapInfoHeader &bitmapInfoHeader,
CMediaPacket* pVideoPacket)
{
HXxSize* pDims = (HXxSize*) pVideoPacket->m_pSampleDesc;
if (pDims)
{
bitmapInfoHeader.biWidth = pDims->cx;
bitmapInfoHeader.biHeight = pDims->cy;
bitmapInfoHeader.biSizeImage = bitmapInfoHeader.biWidth *
bitmapInfoHeader.biHeight *
bitmapInfoHeader.biBitCount /
8;
}
return HXR_OK;
}
/****************************************************************************
* Method:
* CMP4VideoFormat::CreateAllocators()
*/
HX_RESULT CMP4VideoFormat::CreateAllocators(void)
{
HX_RESULT retVal = HXR_OK;
HX20ALLOCPROPS allocRequest, allocActual;
HX_RELEASE(m_pInputAllocator);
HX_DELETE(m_pMP4VideoRenderer->m_pOutputAllocator);
// setup the input allocator for the codec
if (retVal == HXR_OK)
{
m_pInputAllocator = new CHXBufferMemoryAllocator(TRUE);
retVal = HXR_OUTOFMEMORY;
if (m_pInputAllocator)
{
m_pInputAllocator->AddRef();
m_pInputAllocator->GetProperties(&allocRequest);
allocRequest.nNumBuffers = 0; // No retention
m_pInputAllocator->SetProperties(&allocRequest,
&allocActual);
retVal = HXR_OK;
}
}
// setup the output allocator for the codec
if (retVal == HXR_OK)
{
m_pMP4VideoRenderer->m_pOutputAllocator = new CHXMemoryAllocator(TRUE);
retVal = HXR_OUTOFMEMORY;
if (m_pMP4VideoRenderer->m_pOutputAllocator)
{
m_pMP4VideoRenderer->m_pOutputAllocator->AddRef();
m_pMP4VideoRenderer->m_pOutputAllocator->GetProperties(&allocRequest);
allocRequest.nNumBuffers = GetMaxDecodedFrames() * 2;
m_pMP4VideoRenderer->m_pOutputAllocator->SetProperties(&allocRequest,
&allocActual);
retVal = HXR_OK;
}
}
#if _MACINTOSH
// TODO: we want to pre-allocate the output buffers here so they come
// from the standard memory pools instead of the interrupt memory
// pools.
#endif // _MACINTOSH
return retVal;
}
/****************************************************************************
* Method:
* CMP4VideoFormat::KillMP4VSampleDesc
*
*/
void CMP4VideoFormat::KillMP4VSampleDesc(void* pSampleDesc, void* pUserData)
{
if (pSampleDesc)
{
HXxSize* pFrameDims = (HXxSize*) pSampleDesc;
delete pFrameDims;
}
}
/****************************************************************************
* Method:
* CMP4VideoFormat::KillInputBuffer
*
*/
void CMP4VideoFormat::KillInputBuffer(void* pBuffer, void* pUserData)
{
if (pBuffer)
{
HXCODEC_DATA* pDeadData = (HXCODEC_DATA*) pBuffer;
CMP4VideoFormat* pVidFmt = (CMP4VideoFormat*) pUserData;
HX_ASSERT(pUserData);
if (pDeadData->data)
{
pVidFmt->m_pInputAllocator->ReleasePacketPtr(pDeadData->data);
}
delete[] ((ULONG32*) pDeadData);
}
}
/****************************************************************************
* Method:
* CMP4VideoFormat::KillOutputBuffer
*
*/
void CMP4VideoFormat::KillOutputBuffer(void* pBuffer, void* pUserData)
{
if (pBuffer)
{
CMP4VideoRenderer* pVidRnd = (CMP4VideoRenderer*) pUserData;
HX_ASSERT(pUserData);
pVidRnd->m_pOutputAllocator->ReleasePacketPtr((UINT8*) pBuffer);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?