rvxvdec.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- // #define _DRY_RUN
- // #define _TRACK_CODEC_INPUT
- /****************************************************************************
- * Includes
- */
- #include "hxtypes.h"
- #include "hxresult.h"
- #include "hxassert.h"
- #include "hxwintyp.h"
- #include "hxcom.h"
- #include "hxmtypes.h"
- #include "hxcomm.h"
- #include "ihxpckts.h"
- #include "hxplugn.h"
- #include "hxengin.h"
- #include "hxerror.h"
- #include "hxformt.h"
- #include "hxprefs.h"
- #include "rvxvdec.h"
- #include "rvxvdfmt.h"
- #include "rvxvideo.h"
- #ifdef _TRACK_CODEC_INPUT
- #include "errdbg.h"
- #endif // _TRACK_CODEC_INPUT
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #if defined(HELIX_FEATURE_PREFERENCES)
- #include "hxprefs.h"
- #include "hxprefutil.h"
- #endif /* HELIX_FEATURE_PREFERENCES */
- /****************************************************************************
- * Statics
- */
- /****************************************************************************
- * Method:
- * CRVXVDecoder::CRVXVDecoder
- */
- /****************************************************************************
- * Constructor/Destructor
- */
- CRVXVDecoder::CRVXVDecoder()
- : m_pContext(NULL)
- , m_pVideoFormat(NULL)
- , m_pCodecLib(NULL)
- , m_pCodec(NULL)
- , m_pStream(NULL)
- , m_pCodecId(NULL)
- , m_pInputAllocator(NULL)
- , m_pOutputAllocator(NULL)
- , m_moftagOut(0)
- , m_ulLastTimeStamp(0)
- , m_pImageInfoBuffer(NULL)
- , m_ulSequenceStartTS(0)
- , m_bNewSequence(FALSE)
- {
- ;
- }
- CRVXVDecoder::~CRVXVDecoder()
- {
- Close();
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::Close
- */
- HX_RESULT CRVXVDecoder::Close(void)
- {
- if (m_pStream != NULL)
- {
- m_pCodecLib->PNStream_Close(m_pStream);
- m_pStream = NULL;
- }
- if (m_pCodec != NULL)
- {
- m_pCodecLib->PNCodec_Close(m_pCodec);
- m_pCodec = NULL;
- }
- HX_DELETE(m_pCodecLib);
- if (m_pInputAllocator)
- {
- m_pInputAllocator->Release();
- m_pInputAllocator = NULL;
- }
- if (m_pOutputAllocator)
- {
- m_pOutputAllocator->Release();
- m_pOutputAllocator = NULL;
- }
- HX_VECTOR_DELETE(m_pImageInfoBuffer);
- return HXR_OK;
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::CRVXVDecoder
- */
- HX_RESULT CRVXVDecoder::Init(IUnknown* pContext,
- CRVXVideoFormat* pVideoFormat,
- HXxSize* pSize,
- IHX20MemoryAllocator* pInputAllocator,
- IHX20MemoryAllocator* pOutputAllocator)
- {
- HX_RESULT retVal = HXR_INVALID_PARAMETER;
- ULONG32 ulMofInSize = 0;
- const HX_MOF* pMofIn = NULL;
- HX_RELEASE(m_pContext);
- m_pContext = pContext;
- HX_ASSERT(m_pContext);
- if (m_pContext)
- {
- retVal = HXR_OK;
- }
- if (SUCCEEDED(retVal))
- {
- m_pVideoFormat = pVideoFormat;
- retVal = HXR_INVALID_PARAMETER;
- if (m_pVideoFormat)
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- m_pInputAllocator = pInputAllocator;
- if (m_pInputAllocator)
- {
- m_pInputAllocator->AddRef();
- }
- m_pOutputAllocator = pOutputAllocator;
- if (m_pOutputAllocator)
- {
- m_pOutputAllocator->AddRef();
- }
- retVal = HXR_INVALID_PARAMETER;
- if (m_pInputAllocator && m_pOutputAllocator)
- {
- retVal = HXR_OK;
- }
- }
- #ifndef _DRY_RUN
- if (SUCCEEDED(retVal))
- {
- ulMofInSize = m_pVideoFormat->GetBitstreamHeaderSize();
- retVal = HXR_FAIL;
- if (ulMofInSize >= sizeof(HX_MOF))
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- pMofIn = m_pVideoFormat->GetBitstreamHeader();
- retVal = HXR_FAIL;
- if (pMofIn)
- {
- retVal = HXR_OK;
- }
- }
- // Open the codec
- if (SUCCEEDED(retVal))
- {
- retVal = OpenCodec((HX_MOF*) pMofIn);
- }
- if (SUCCEEDED(retVal))
- {
- retVal = OpenStream((HX_MOF*) pMofIn);
- }
- #endif // _DRY_RUN
- return retVal;
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::Decode()
- */
- HX_RESULT CRVXVDecoder::Decode(CMediaPacket* pFrameToDecode,
- ULONG32 ulQuality)
- {
- ULONG32 ulFirstTimeStamp = m_ulLastTimeStamp;
- HX_OQS2 theOutputQueueStatus;
- HX_RESULT retVal = HXR_OK;
- if (m_bNewSequence)
- {
- // tell the codec the seek occured
- m_pCodecLib->PNStream_SetProperty(m_pStream,
- SP_SEEK,
- &m_ulSequenceStartTS);
- m_ulLastTimeStamp = m_ulSequenceStartTS;
- ulFirstTimeStamp = m_ulLastTimeStamp;
- m_bNewSequence = FALSE;
- }
- theOutputQueueStatus.maxQueueDepth = m_pVideoFormat->m_ulMaxDecodedFrames;
- theOutputQueueStatus.queueDepth = theOutputQueueStatus.maxQueueDepth;
- // tell the stream about renderer status so it can scale its processing
- #ifdef _DISABLE_CPU_SCALABILITY_ON_START
- if (m_pVideoFormat->m_pRVXVideoRenderer->IsActive())
- #endif //_DISABLE_CPU_SCALABILITY_ON_START
- {
- theOutputQueueStatus.queueDepth = m_pVideoFormat->GetDecodedFrameQueueDepth();
- }
- theOutputQueueStatus.newestQueueElementTimeStamp = m_ulLastTimeStamp;
- m_pVideoFormat->GetNextFrameTime(ulFirstTimeStamp);
- theOutputQueueStatus.oldestQueueElementTimeStamp = ulFirstTimeStamp;
- theOutputQueueStatus.currentTimeStamp = -m_pVideoFormat->m_pRVXVideoRenderer->ComputeTimeAhead(0, 0);
- theOutputQueueStatus.nonFRUDroppedFrames = 0;
- theOutputQueueStatus.TotalDroppedFrames = 0;
- // this is for Beta 2 codecs
- #ifdef _DRY_RUN
- m_pInputAllocator->ReleasePacketPtr(((HXCODEC_DATA*) pFrameToDecode->m_pData)->data);
- ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
- retVal = DecodeDone(NULL);
- #else // _DRY_RUN
- m_pCodecLib->PNStream_SetProperty(m_pStream,
- SP_OUPUT_QUEUE_STATUS,
- &theOutputQueueStatus);
- // this is for > beta 2 codecs
- m_pCodecLib->PNStream_SetProperty(m_pStream,
- SP_OUPUT_QUEUE_STATUS2,
- &theOutputQueueStatus);
- #ifdef _TRACK_CODEC_INPUT
- {
- ULONG32 i;
- HXCODEC_DATA* pCodecData;
- pCodecData = (HXCODEC_DATA*) pFrameToDecode->m_pData;
- DEBUG_OUTF("C:\RVX.TXT",
- (s, "Codec Frame: Size=%d NumOffsets=%dn", pCodecData->dataLength, pCodecData->numSegments));
- for (i = 0; i < pCodecData->numSegments; i++)
- {
- DEBUG_OUTF("C:\RVX.TXT",
- (s, " Segment%2d: Valid=%s Offset=%dn",
- i,
- pCodecData->Segments[i].bIsValid ? "T" : "F",
- pCodecData->Segments[i].ulSegmentOffset));
- HX_ASSERT(pCodecData->Segments[i].ulSegmentOffset < pCodecData->dataLength);
- HX_ASSERT(pCodecData->Segments[i].ulSegmentOffset < 100000);
- }
- }
- #endif // _TRACK_CODEC_INPUT
- retVal = CheckCallback(m_pStream);
- if (SUCCEEDED(retVal))
- {
- retVal = m_pCodecLib->PNStream_Input(m_pStream, NULL,
- (HXCODEC_DATA*) pFrameToDecode->m_pData);
- if(pFrameToDecode->m_pData)
- {
- ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
- }
- }
- #endif // _DRY_RUN
- return retVal;
- }
- /****************************************************************************
- * Method:
- * CRVDecoder::DecodeDone
- */
- HX_RESULT CRVXVDecoder::DecodeDone(HXCODEC_DATA* pData)
- {
- if (pData)
- {
- m_ulLastTimeStamp = pData->timestamp;
- }
- return m_pVideoFormat->DecodeDone(pData);
- }
- /****************************************************************************
- * Method:
- * CRVDecoder::GetImageInfo
- */
- HX_RESULT CRVXVDecoder::GetImageInfo(HX_MOF* &pImageInfo)
- {
- ULONG32 ulSize;
- ULONG32* pMofBuf = NULL;
- HX_RESULT retVal = HXR_OK;
- HX_VECTOR_DELETE(m_pImageInfoBuffer);
- retVal = m_pCodecLib->PNStream_GetStreamHeaderSize(m_pStream,
- &ulSize);
- if (retVal == HXR_OK)
- {
- HX_ASSERT((ulSize == sizeof(HX_FORMAT_IMAGE)) ||
- (ulSize == sizeof(HX_FORMAT_IMAGE2)));
- pMofBuf = new ULONG32[ulSize / 4 + 1];
- retVal = HXR_FAIL;
- if (pMofBuf && (ulSize >= sizeof(HX_MOF)))
- {
- retVal = HXR_OK;
- }
- }
- if (retVal == HXR_OK)
- {
- retVal = m_pCodecLib->PNStream_GetStreamHeader(m_pStream,
- (HX_MOF *) pMofBuf);
- }
- if (retVal == HXR_OK)
- {
- m_pImageInfoBuffer = pMofBuf;
- pMofBuf = NULL;
- pImageInfo = (HX_MOF*) m_pImageInfoBuffer;
- }
- HX_VECTOR_DELETE(pMofBuf);
- return retVal;
- }
- /****************************************************************************
- * Method:
- * CRVDecoder::OnNewImage
- */
- HX_RESULT CRVXVDecoder::OnNewImage(HXSTREAM streamRef,
- HXSTREAM fromStreamRef,
- HXCODEC_DATA* pData)
- {
- CRVXVDecoder* pDecoder = (CRVXVDecoder*) streamRef;
- return pDecoder->DecodeDone(pData);
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::ResetSequence()
- */
- void CRVXVDecoder::ResetSequence(ULONG32 ulNewSequenceStartTS)
- {
- m_ulSequenceStartTS = ulNewSequenceStartTS;
- m_bNewSequence = TRUE;
- }
- CRADynamicCodecLibrary* CRVXVDecoder::CreateCodecLibrary()
- {
- return new CRADynamicCodecLibrary(m_pContext);
- }
- /****************************************************************************
- * Private Methods
- */
- /****************************************************************************
- * Method:
- * CRVXVDecoder::OpenCodec()
- */
- HX_RESULT CRVXVDecoder::OpenCodec(const HX_MOF* pMofIn)
- {
- HX_MOFTAG mofTag = 0;
- HX_RESULT retVal = HXR_OK;
- HX_ASSERT(pMofIn);
- mofTag = pMofIn->submoftag;
- m_moftagIn = mofTag;
- HX_DELETE(m_pCodecLib);
- // Create Codec Library
- m_pCodecLib = CreateCodecLibrary();
- retVal = HXR_OUTOFMEMORY;
- if (m_pCodecLib != NULL)
- {
- retVal = HXR_OK;
- }
- // Load Codec into library
- if (SUCCEEDED(retVal))
- {
- retVal = m_pCodecLib->LoadCodecLib(mofTag);
- }
- // Open the codec
- if (SUCCEEDED(retVal))
- {
- retVal = m_pCodecLib->PNCodec_Open(mofTag, &m_pCodec);
- if (FAILED(retVal))
- {
- retVal = HXR_REQUEST_UPGRADE;
- }
- }
- return retVal;
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::OpenStream
- */
- HX_RESULT CRVXVDecoder::OpenStream(const HX_MOF* pMofIn)
- {
- ULONG32 ulMofInDataSize = 0;
- ULONG32* pMofInData = NULL;
- HX_FORMAT_IMAGE2 mofOut;
- HXCODEC_INIT codecInit;
- HX_RESULT retVal = HXR_OK;
- HX_ASSERT(pMofIn);
- // Open Stream in some format: try most preferred first
- if (SUCCEEDED(retVal))
- {
- mofOut.cbLength = sizeof(HX_FORMAT_IMAGE2);
- mofOut.moftag = HX_MEDIA_IMAGE2;
- mofOut.submoftag = HX_YUV420_ID;
- m_moftagOut = HX_YUV420_ID;
- }
- if (SUCCEEDED(retVal))
- {
- codecInit.pInMof = (HX_MOF*) pMofIn;
- codecInit.pOutMof = (HX_MOF*) &mofOut;
- codecInit.memoryRef = (HXMEMORY) m_pInputAllocator;
- codecInit.pContext = m_pContext;
- }
- if (retVal == HXR_OK)
- {
- retVal = m_pCodecLib->PNCodec_StreamOpen(m_pCodec,
- &m_pStream,
- &codecInit);
- // TODO: If this fails, try other formats...
- }
- if (retVal == HXR_OK)
- {
- retVal = m_pCodecLib->PNStream_SetDataCallback(
- m_pStream,
- this,
- (HXMEMORY) m_pOutputAllocator,
- OnNewImage);
- }
- if (retVal == HXR_OK)
- {
- SetCodecQuality();
- }
- if (retVal == HXR_OK)
- {
- BOOL bAllowDifferentOutputSizes = TRUE;
- // tell codec we can handle different output sizes
- m_pCodecLib->PNStream_SetProperty(m_pStream,
- SP_ALLOW_DIFFERENT_OUPUT_SIZES,
- &bAllowDifferentOutputSizes);
- }
- // TODO: Setup image format based on codec output format
- return retVal;
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::GetQualityPreference
- */
- HX_RESULT CRVXVDecoder::GetQualityPreference(UINT16 &usQuality)
- {
- HX_RESULT pnr = HXR_OK;
- #if defined(HELIX_FEATURE_PREFERENCES)
- IHXBuffer* pBuffer = NULL;
- IHXPreferences* pPreferences = 0;
- if (!m_pContext ||
- (m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences) !=
- HXR_OK))
- {
- pnr = HXR_INVALID_PARAMETER;
- }
- else
- {
- ReadPrefINT16(pPreferences, "Quality", usQuality);
- }
- HX_RELEASE(pPreferences);
- #endif
- return pnr;
- }
- /****************************************************************************
- * Method:
- * CRVXVDecoder::GetQualityPreference
- */
- void CRVXVDecoder::SetCodecQuality(void)
- {
- BOOL bOn, bOff;
- UINT16 usQualityPreference = 4;
- GetQualityPreference(usQualityPreference);
- // Turn on or off post filter based on flags in source URL
- // if the URL turns off post filter or the TLC quality
- // preference is < 4 we turn off the post filter
- bOn = (usQualityPreference >= 4);
- m_pCodecLib->PNStream_SetProperty (m_pStream, SP_POSTFILTER, &bOn);
- // Turn on or off FRU based on flags in source URL
- bOn = (usQualityPreference >= 4);
- m_pCodecLib->PNStream_SetProperty (m_pStream, SP_TEMPORALINTERP, &bOn);
- // Turn on or off full decoding of B frames (reverse switch)
- bOff = (usQualityPreference < 2);
- m_pCodecLib->PNStream_SetProperty (m_pStream, SP_NOFULLDECODE, &bOff);
- // Turn on or off deblocking of B frames (reverse switch)
- bOff = (usQualityPreference < 3);
- m_pCodecLib->PNStream_SetProperty (m_pStream, SP_NODEBLOCKBFRAMES, &bOff);
- // Turn on or off decode of B-frames based on flags in source URL
- bOn = (usQualityPreference >= 1);
- m_pCodecLib->PNStream_SetProperty (m_pStream, SP_DECODE_B_FRAMES, &bOn);
- }