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 + -
显示快捷键?