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