rvxvdfmt.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,012 行 · 第 1/2 页
CPP
1,012 行
if (m_pRVXVideoRenderer->IsActive() ||
(((LONG32) (pCodecPacket->timestamp - GetStartTime())) > 0))
{
m_pRVXVideoRenderer->ReportDroppedFrame(uFramesDropped);
}
}
}
m_ulLastSequenceNumber = (ULONG32) pCodecPacket->sequenceNum;
}
m_pRVXVideoRenderer->BltIfNeeded();
pCodecPacket = NULL;
m_pRssm->CreateHXCodecPacket(pCodecPacket);
if (pCodecPacket)
{
ReturnAssembledPacket(pFramePacket);
pFramePacket = NULL;
}
}
return pFramePacket;
}
/****************************************************************************
* Method:
* CRVXVideoFormat::Reset
*/
void CRVXVideoFormat::Reset()
{
_Reset();
CVideoFormat::Reset();
}
void CRVXVideoFormat::_Reset(void)
{
if (m_pRssm)
{
m_pRssm->Reset();
}
m_bFirstDecode = TRUE;
m_ulWidthContainedInSegment = 0;
m_ulHeightContainedInSegment = 0;
m_ulLastSequenceNumber = UNINITIALIZED_SEQ_NUMBER;
}
void CRVXVideoFormat::FlushDecodedRngBuf(void)
{
if (m_pDecodedRngBuf)
{
HXCODEC_DATA* pFrame;
while (pFrame = ((HXCODEC_DATA*) m_pDecodedRngBuf->Get()))
{
ReleaseDecodedPacket(pFrame);
}
}
}
void CRVXVideoFormat::ReleaseDecodedPacket(HXCODEC_DATA* &pDecodedPacket)
{
HX_ASSERT(pDecodedPacket);
if (pDecodedPacket)
{
ULONG32* pFrameData = (ULONG32*) pDecodedPacket;
if (pDecodedPacket->data &&
m_pRVXVideoRenderer &&
m_pRVXVideoRenderer->m_pOutputAllocator)
{
m_pRVXVideoRenderer->m_pOutputAllocator->ReleasePacketPtr(pDecodedPacket->data);
}
delete [] pFrameData;
pDecodedPacket = NULL;
}
}
/****************************************************************************
* Method:
* CRVXVideoFormat::CreateDecodedPacket
*
*/
CMediaPacket* CRVXVideoFormat::CreateDecodedPacket(CMediaPacket* pFrameToDecode)
{
HXCODEC_DATA* pDecodedPacket = NULL;
CMediaPacket* pDecodedFrame = NULL;
UINT8* pData = NULL;
BOOL bFrameDecoded = FALSE;
HX_ASSERT(pFrameToDecode);
#if defined(HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES)
// discard late frames before they are decoded
BOOL bDecodeThisOne = TRUE;
if (m_pRVXVideoRenderer->IsActive()) // if playing
{
LONG32 lTimeAhead = m_pRVXVideoRenderer->ComputeTimeAhead(
pFrameToDecode->m_ulTime, 0);
if (pFrameToDecode->m_ulFlags & HX_KEYFRAME_FLAG)
{
if (lTimeAhead < MAX_KEY_CODED_FRAME_FALLBEHIND)
{
// Treat it as non key-frame: drop it
bDecodeThisOne = FALSE;
m_bFlushingToKeyFrame = TRUE;
}
else
{ // we're going to display this key frame, so stop flushing
m_bFlushingToKeyFrame = FALSE;
}
}
else
{
if (lTimeAhead < MAX_NONKEY_CODED_FRAME_FALLBEHIND)
{ // discard this frame and all frames to the next key frame
bDecodeThisOne = FALSE;
m_bFlushingToKeyFrame = TRUE;
}
else
{
}
}
}
else
{ // we're not playing, so decode when we start playing
m_bFlushingToKeyFrame = FALSE;
}
if (bDecodeThisOne && !m_bFlushingToKeyFrame)
{ // decode and display this frame
;
}
else
{ // discard this frame before decode
pFrameToDecode->Clear();
delete pFrameToDecode;
m_pRVXVideoRenderer->ReportDroppedFrame();
return NULL;
}
#endif // HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES
if (m_bFirstDecode)
{
m_bFirstDecode = FALSE;
FlushDecodedRngBuf();
m_pDecoder->ResetSequence(GetStartTime());
}
pDecodedPacket = (HXCODEC_DATA*) m_pDecodedRngBuf->Get();
m_pRVXVideoRenderer->BltIfNeeded();
HX_RESULT retVal = m_pDecoder->Decode(pFrameToDecode, MAX_DECODE_QUALITY);
if( retVal == HXR_OUTOFMEMORY )
{
m_LastError = HXR_OUTOFMEMORY;
return NULL;
}
else
{
do
{
if (pDecodedPacket == NULL)
{
pDecodedPacket = (HXCODEC_DATA*) m_pDecodedRngBuf->Get();
}
bFrameDecoded = (pDecodedPacket != NULL);
#if !defined(HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES)
// don't discard decoded frames
if (pDecodedPacket)
{
if (m_pRVXVideoRenderer->IsActive() &&
(m_pRVXVideoRenderer->ComputeTimeAhead(
pDecodedPacket->timestamp,
0)
< -NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD))
{
ReleaseDecodedPacket(pDecodedPacket);
m_pRVXVideoRenderer->ReportDroppedFrame();
}
}
#endif // HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES
} while ((!pDecodedPacket) && bFrameDecoded);
if (pDecodedPacket)
{
CMediaPacket* pVideoPacket = NULL;
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,
pDecodedPacket); // sample description
// Data is now linked through VideoPacket
pDecodedPacket->data = NULL;
pDecodedPacket->dataLength = 0;
pVideoPacket->SetBufferKiller(KillOutputBuffer);
pVideoPacket->SetSampleDescKiller(KillRVXSampleDesc);
pVideoPacket->m_pUserData = m_pRVXVideoRenderer;
pDecodedPacket = NULL;
pDecodedFrame = pVideoPacket;
pVideoPacket = NULL;
}
if (pVideoPacket)
{
delete pVideoPacket;
}
}
}
if (pFrameToDecode != NULL)
{
pFrameToDecode->Clear();
delete pFrameToDecode;
}
if (pDecodedPacket)
{
ReleaseDecodedPacket(pDecodedPacket);
}
return pDecodedFrame;
}
CRVXVDecoder* CRVXVideoFormat::CreateDecoder()
{
return new CRVXVDecoder();
}
/****************************************************************************
* Method:
* CRVXVideoFormat::DecodeDone
*/
HX_RESULT CRVXVideoFormat::DecodeDone(HXCODEC_DATA* pData)
{
HX_RESULT retVal = HXR_OK;
m_pRVXVideoRenderer->BltIfNeeded();
if (pData)
{
ULONG32 ulFrameSize = HXCODEC_PTR_POPULATED_SIZE(pData);
HXCODEC_DATA* pFrame = (HXCODEC_DATA*) new ULONG32[ulFrameSize / 4 + 1];
if (pFrame)
{
memcpy(pFrame, pData, ulFrameSize); /* Flawfinder: ignore */
if (!m_pDecodedRngBuf->Put(pFrame))
{
ReleaseDecodedPacket(pFrame);
m_pRVXVideoRenderer->ReportDroppedFrame();
}
}
else
{
if (pData->data)
{
m_pRVXVideoRenderer->m_pOutputAllocator->ReleasePacketPtr(
pData->data);
m_pRVXVideoRenderer->ReportDroppedFrame();
}
}
}
return retVal;
}
/****************************************************************************
* Method:
* CRVXVideoFormat::IsBitmapFormatChanged
*
*/
BOOL CRVXVideoFormat::IsBitmapFormatChanged(
HXBitmapInfoHeader &BitmapInfoHeader,
CMediaPacket* pVideoPacket)
{
BOOL bRetVal = (m_ulWidthContainedInSegment == 0);
HXCODEC_DATA* pData = (HXCODEC_DATA*) pVideoPacket->m_pSampleDesc;
if (pData &&
(pData->flags & HX_SEGMENT_CONTAINS_OUTPUT_SIZE_FLAG))
{
bRetVal = (bRetVal ||
((m_ulWidthContainedInSegment != pData->Segments[1].ulSegmentOffset) ||
(m_ulHeightContainedInSegment != ((ULONG32) pData->Segments[1].bIsValid))));
}
return bRetVal;
}
/****************************************************************************
* Method:
* CRVXVideoFormat::InitBitmapInfoHeader
*/
HX_RESULT CRVXVideoFormat::InitBitmapInfoHeader(
HXBitmapInfoHeader &bitmapInfoHeader,
CMediaPacket* pVideoPacket)
{
if (m_pCodecOutputBIH)
{
HXCODEC_DATA* pData = (HXCODEC_DATA*) pVideoPacket->m_pSampleDesc;
if (pData && (pData->flags & HX_SEGMENT_CONTAINS_OUTPUT_SIZE_FLAG))
{
if ((m_ulWidthContainedInSegment != pData->Segments[1].ulSegmentOffset) ||
(m_ulHeightContainedInSegment != ((ULONG32) pData->Segments[1].bIsValid)))
{
m_pCodecOutputBIH->biWidth = m_ulWidthContainedInSegment =
pData->Segments[1].ulSegmentOffset;
m_pCodecOutputBIH->biHeight = m_ulHeightContainedInSegment =
((ULONG32) pData->Segments[1].bIsValid);
m_pCodecOutputBIH->biWidth += (m_pRVXVideoRenderer->m_ulPadWidthLeft +
m_pRVXVideoRenderer->m_ulPadWidthRight);
m_pCodecOutputBIH->biHeight += (m_pRVXVideoRenderer->m_ulPadHeightTop +
m_pRVXVideoRenderer->m_ulPadHeightBottom);
m_pCodecOutputBIH->biSizeImage =
m_pCodecOutputBIH->biWidth * m_pCodecOutputBIH->biBitCount *
m_pCodecOutputBIH->biHeight / 8;
}
}
else
{
m_ulWidthContainedInSegment = m_pCodecOutputBIH->biWidth;
m_ulHeightContainedInSegment = m_pCodecOutputBIH->biHeight;
}
bitmapInfoHeader = *m_pCodecOutputBIH;
}
return HXR_OK;
}
/****************************************************************************
* Method:
* CRVXVideoFormat::CreateAllocators()
*/
HX_RESULT CRVXVideoFormat::CreateAllocators(void)
{
HX_RESULT retVal = HXR_OK;
HX20ALLOCPROPS allocRequest, allocActual;
if (m_pInputAllocator)
{
m_pInputAllocator->Release();
m_pInputAllocator = NULL;
}
if (m_pRVXVideoRenderer->m_pOutputAllocator)
{
m_pRVXVideoRenderer->m_pOutputAllocator->Release();
m_pRVXVideoRenderer->m_pOutputAllocator = NULL;
}
// setup the input allocator for the codec
if (retVal == HXR_OK)
{
m_pInputAllocator = new CHXMemoryAllocator(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_pRVXVideoRenderer->m_pOutputAllocator = new CHXMemoryAllocator(TRUE);
retVal = HXR_OUTOFMEMORY;
if (m_pRVXVideoRenderer->m_pOutputAllocator)
{
m_pRVXVideoRenderer->m_pOutputAllocator->AddRef();
m_pRVXVideoRenderer->m_pOutputAllocator->GetProperties(&allocRequest);
allocRequest.nNumBuffers = GetMaxDecodedFrames() * 2;
m_pRVXVideoRenderer->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::KillRVXSampleDesc
*
*/
void CRVXVideoFormat::KillRVXSampleDesc(void* pSampleDesc, void* pUserData)
{
if (pSampleDesc)
{
HXCODEC_DATA* pFrame = (HXCODEC_DATA*) pSampleDesc;
ULONG32* pFrameData = (ULONG32*) pFrame;
if (pFrame->data)
{
KillOutputBuffer(pFrame->data, pUserData);
}
delete [] pFrameData;
}
}
/****************************************************************************
* Method:
* CRVXVideoFormat::KillInputBuffer
*
*/
void CRVXVideoFormat::KillInputBuffer(void* pBuffer, void* pUserData)
{
if (pBuffer)
{
HXCODEC_DATA* pDeadData = (HXCODEC_DATA*) pBuffer;
CRVXVideoFormat* pVidFmt = (CRVXVideoFormat*) pUserData;
HX_ASSERT(pUserData);
if (pDeadData->data)
{
pVidFmt->m_pInputAllocator->ReleasePacketPtr(pDeadData->data);
pDeadData->data = NULL;
}
if (pVidFmt->m_pRssm)
{
pVidFmt->m_pRssm->DisposeHXCodecPacket(pDeadData);
}
}
}
/****************************************************************************
* Method:
* CRVXVideoFormat::KillOutputBuffer
*
*/
void CRVXVideoFormat::KillOutputBuffer(void* pBuffer, void* pUserData)
{
if (pBuffer)
{
CRVXVideoRenderer* pVidRnd = (CRVXVideoRenderer*) pUserData;
HX_ASSERT(pUserData);
if (NULL == pVidRnd || NULL == pVidRnd->m_pOutputAllocator)
return;
pVidRnd->m_pOutputAllocator->ReleasePacketPtr((UINT8*) pBuffer);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?