rvxvdec.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: RCSL 1.0/RPSL 1.0
  3.  *
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
  5.  *
  6.  * The contents of this file, and the files included with this file, are
  7.  * subject to the current version of the RealNetworks Public Source License
  8.  * Version 1.0 (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the RealNetworks Community Source License Version 1.0
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
  12.  * in which case the RCSL will apply. You may also obtain the license terms
  13.  * directly from RealNetworks.  You may not use this file except in
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or
  16.  * RCSL for the rights, obligations and limitations governing use of the
  17.  * contents of the file.
  18.  *
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the
  20.  * developer of the Original Code and owns the copyrights in the portions
  21.  * it created.
  22.  *
  23.  * This file, and the files included with this file, is distributed and made
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  28.  *
  29.  * Technology Compatibility Kit Test Suite(s) Location:
  30.  *    http://www.helixcommunity.org/content/tck
  31.  *
  32.  * Contributor(s):
  33.  *
  34.  * ***** END LICENSE BLOCK ***** */
  35. // #define _DRY_RUN
  36. // #define _TRACK_CODEC_INPUT
  37. /****************************************************************************
  38.  *  Includes
  39.  */
  40. #include "hxtypes.h"
  41. #include "hxresult.h"
  42. #include "hxassert.h"
  43. #include "hxwintyp.h"
  44. #include "hxcom.h"
  45. #include "hxmtypes.h"
  46. #include "hxcomm.h"
  47. #include "ihxpckts.h"
  48. #include "hxplugn.h"
  49. #include "hxengin.h"
  50. #include "hxerror.h"
  51. #include "hxformt.h"
  52. #include "hxprefs.h"
  53. #include "rvxvdec.h"
  54. #include "rvxvdfmt.h"
  55. #include "rvxvideo.h"
  56. #ifdef _TRACK_CODEC_INPUT
  57. #include "errdbg.h"
  58. #endif // _TRACK_CODEC_INPUT
  59. #include "hxheap.h"
  60. #ifdef _DEBUG
  61. #undef HX_THIS_FILE
  62. static const char HX_THIS_FILE[] = __FILE__;
  63. #endif
  64. #if defined(HELIX_FEATURE_PREFERENCES)
  65. #include "hxprefs.h"
  66. #include "hxprefutil.h"
  67. #endif /* HELIX_FEATURE_PREFERENCES */
  68. /****************************************************************************
  69.  *  Statics
  70.  */
  71. /****************************************************************************
  72.  *  Method:
  73.  *    CRVXVDecoder::CRVXVDecoder
  74.  */
  75. /****************************************************************************
  76.  *  Constructor/Destructor
  77.  */
  78. CRVXVDecoder::CRVXVDecoder()
  79.     : m_pContext(NULL)
  80.     , m_pVideoFormat(NULL)
  81.     , m_pCodecLib(NULL)
  82.     , m_pCodec(NULL)
  83.     , m_pStream(NULL)
  84.     , m_pCodecId(NULL)
  85.     , m_pInputAllocator(NULL)
  86.     , m_pOutputAllocator(NULL)
  87.     , m_moftagOut(0)
  88.     , m_ulLastTimeStamp(0)
  89.     , m_pImageInfoBuffer(NULL)
  90.     , m_ulSequenceStartTS(0)
  91.     , m_bNewSequence(FALSE)
  92. {
  93.     ;
  94. }
  95. CRVXVDecoder::~CRVXVDecoder()
  96. {
  97.     Close();
  98. }
  99. /****************************************************************************
  100.  *  Method:
  101.  *    CRVXVDecoder::Close
  102.  */
  103. HX_RESULT CRVXVDecoder::Close(void)
  104. {
  105.     if (m_pStream != NULL)
  106.     {
  107. m_pCodecLib->PNStream_Close(m_pStream);
  108. m_pStream = NULL;
  109.     }
  110.     if (m_pCodec != NULL)
  111.     {
  112. m_pCodecLib->PNCodec_Close(m_pCodec);
  113. m_pCodec = NULL;
  114.     }
  115.     HX_DELETE(m_pCodecLib);
  116.     if (m_pInputAllocator)
  117.     {
  118.         m_pInputAllocator->Release();
  119.         m_pInputAllocator = NULL;
  120.     }
  121.     if (m_pOutputAllocator)
  122.     {
  123.         m_pOutputAllocator->Release();
  124.         m_pOutputAllocator = NULL;
  125.     }
  126.     HX_VECTOR_DELETE(m_pImageInfoBuffer);
  127.     return HXR_OK;
  128. }
  129. /****************************************************************************
  130.  *  Method:
  131.  *    CRVXVDecoder::CRVXVDecoder
  132.  */
  133. HX_RESULT CRVXVDecoder::Init(IUnknown* pContext,
  134.      CRVXVideoFormat* pVideoFormat,
  135.      HXxSize* pSize,
  136.      IHX20MemoryAllocator* pInputAllocator,
  137.      IHX20MemoryAllocator* pOutputAllocator)
  138. {
  139.     HX_RESULT retVal = HXR_INVALID_PARAMETER;
  140.     ULONG32 ulMofInSize = 0;
  141.     const HX_MOF* pMofIn = NULL;
  142.     HX_RELEASE(m_pContext);
  143.     m_pContext = pContext;
  144.     HX_ASSERT(m_pContext);
  145.     if (m_pContext)
  146.     {
  147. retVal = HXR_OK;
  148.     }
  149.     if (SUCCEEDED(retVal))
  150.     {
  151. m_pVideoFormat = pVideoFormat;
  152. retVal = HXR_INVALID_PARAMETER;
  153. if (m_pVideoFormat)
  154. {
  155.     retVal = HXR_OK;
  156. }
  157.     }
  158.     if (SUCCEEDED(retVal))
  159.     {
  160. m_pInputAllocator = pInputAllocator;
  161. if (m_pInputAllocator)
  162. {
  163.     m_pInputAllocator->AddRef();
  164. }
  165. m_pOutputAllocator = pOutputAllocator;
  166. if (m_pOutputAllocator)
  167. {
  168.     m_pOutputAllocator->AddRef();
  169. }
  170. retVal = HXR_INVALID_PARAMETER;
  171. if (m_pInputAllocator && m_pOutputAllocator)
  172. {
  173.     retVal = HXR_OK;
  174. }
  175.     }
  176. #ifndef _DRY_RUN
  177.     if (SUCCEEDED(retVal))
  178.     {
  179. ulMofInSize = m_pVideoFormat->GetBitstreamHeaderSize();
  180. retVal = HXR_FAIL;
  181. if (ulMofInSize >= sizeof(HX_MOF))
  182. {
  183.     retVal = HXR_OK;
  184. }
  185.     }
  186.     if (SUCCEEDED(retVal))
  187.     {
  188. pMofIn = m_pVideoFormat->GetBitstreamHeader();
  189. retVal = HXR_FAIL;
  190. if (pMofIn)
  191. {
  192.     retVal = HXR_OK;
  193. }
  194.     }
  195.     // Open the codec
  196.     if (SUCCEEDED(retVal))
  197.     {
  198. retVal = OpenCodec((HX_MOF*) pMofIn);
  199.     }
  200.     if (SUCCEEDED(retVal))
  201.     {
  202. retVal = OpenStream((HX_MOF*) pMofIn);
  203.     }
  204. #endif // _DRY_RUN
  205.     return retVal;
  206. }
  207. /****************************************************************************
  208.  *  Method:
  209.  *    CRVXVDecoder::Decode()
  210.  */
  211. HX_RESULT CRVXVDecoder::Decode(CMediaPacket* pFrameToDecode,
  212.        ULONG32 ulQuality)
  213. {
  214.     ULONG32 ulFirstTimeStamp = m_ulLastTimeStamp;
  215.     HX_OQS2 theOutputQueueStatus;
  216.     HX_RESULT retVal = HXR_OK;
  217.     if (m_bNewSequence)
  218.     {
  219. // tell the codec the seek occured
  220. m_pCodecLib->PNStream_SetProperty(m_pStream,
  221.   SP_SEEK,
  222.   &m_ulSequenceStartTS);
  223. m_ulLastTimeStamp = m_ulSequenceStartTS;
  224. ulFirstTimeStamp = m_ulLastTimeStamp;
  225. m_bNewSequence = FALSE;
  226.     }
  227.     theOutputQueueStatus.maxQueueDepth = m_pVideoFormat->m_ulMaxDecodedFrames;
  228.     theOutputQueueStatus.queueDepth = theOutputQueueStatus.maxQueueDepth;
  229.     // tell the stream about renderer status so it can scale its processing
  230. #ifdef _DISABLE_CPU_SCALABILITY_ON_START
  231.     if (m_pVideoFormat->m_pRVXVideoRenderer->IsActive())
  232. #endif //_DISABLE_CPU_SCALABILITY_ON_START
  233.     {
  234. theOutputQueueStatus.queueDepth = m_pVideoFormat->GetDecodedFrameQueueDepth();
  235.     }
  236.     theOutputQueueStatus.newestQueueElementTimeStamp = m_ulLastTimeStamp;
  237.     m_pVideoFormat->GetNextFrameTime(ulFirstTimeStamp);
  238.     theOutputQueueStatus.oldestQueueElementTimeStamp = ulFirstTimeStamp;
  239.     theOutputQueueStatus.currentTimeStamp = -m_pVideoFormat->m_pRVXVideoRenderer->ComputeTimeAhead(0, 0);
  240.     theOutputQueueStatus.nonFRUDroppedFrames = 0;
  241.     theOutputQueueStatus.TotalDroppedFrames = 0;
  242.     // this is for Beta 2 codecs
  243. #ifdef _DRY_RUN
  244.     m_pInputAllocator->ReleasePacketPtr(((HXCODEC_DATA*) pFrameToDecode->m_pData)->data);
  245.     ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
  246.     retVal = DecodeDone(NULL);
  247. #else // _DRY_RUN
  248.     m_pCodecLib->PNStream_SetProperty(m_pStream,
  249.       SP_OUPUT_QUEUE_STATUS,
  250.       &theOutputQueueStatus);
  251.     // this is for > beta 2 codecs
  252.     m_pCodecLib->PNStream_SetProperty(m_pStream,
  253.       SP_OUPUT_QUEUE_STATUS2,
  254.       &theOutputQueueStatus);
  255. #ifdef _TRACK_CODEC_INPUT
  256.     {
  257. ULONG32 i;
  258. HXCODEC_DATA* pCodecData;
  259. pCodecData = (HXCODEC_DATA*) pFrameToDecode->m_pData;
  260. DEBUG_OUTF("C:\RVX.TXT",
  261.     (s, "Codec Frame: Size=%d NumOffsets=%dn", pCodecData->dataLength, pCodecData->numSegments));
  262. for (i = 0; i < pCodecData->numSegments; i++)
  263. {
  264.     DEBUG_OUTF("C:\RVX.TXT",
  265. (s, "     Segment%2d: Valid=%s Offset=%dn",
  266.     i,
  267.     pCodecData->Segments[i].bIsValid ? "T" : "F",
  268.     pCodecData->Segments[i].ulSegmentOffset));
  269.     HX_ASSERT(pCodecData->Segments[i].ulSegmentOffset < pCodecData->dataLength);
  270.     HX_ASSERT(pCodecData->Segments[i].ulSegmentOffset < 100000);
  271. }
  272.     }
  273. #endif // _TRACK_CODEC_INPUT
  274.     retVal = CheckCallback(m_pStream);
  275.     if (SUCCEEDED(retVal))
  276.     {
  277.         retVal = m_pCodecLib->PNStream_Input(m_pStream, NULL,
  278.                                     (HXCODEC_DATA*) pFrameToDecode->m_pData);
  279.         if(pFrameToDecode->m_pData)
  280.         {
  281.             ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
  282.         }
  283.     }
  284. #endif // _DRY_RUN
  285.     return retVal;
  286. }
  287. /****************************************************************************
  288.  *  Method:
  289.  *    CRVDecoder::DecodeDone
  290.  */
  291. HX_RESULT CRVXVDecoder::DecodeDone(HXCODEC_DATA* pData)
  292. {
  293.     if (pData)
  294.     {
  295. m_ulLastTimeStamp = pData->timestamp;
  296.     }
  297.     return m_pVideoFormat->DecodeDone(pData);
  298. }
  299. /****************************************************************************
  300.  *  Method:
  301.  *    CRVDecoder::GetImageInfo
  302.  */
  303. HX_RESULT CRVXVDecoder::GetImageInfo(HX_MOF* &pImageInfo)
  304. {
  305.     ULONG32 ulSize;
  306.     ULONG32* pMofBuf = NULL;
  307.     HX_RESULT retVal = HXR_OK;
  308.     HX_VECTOR_DELETE(m_pImageInfoBuffer);
  309.     retVal = m_pCodecLib->PNStream_GetStreamHeaderSize(m_pStream,
  310.        &ulSize);
  311.     if (retVal == HXR_OK)
  312.     {
  313. HX_ASSERT((ulSize == sizeof(HX_FORMAT_IMAGE)) ||
  314.   (ulSize == sizeof(HX_FORMAT_IMAGE2)));
  315. pMofBuf = new ULONG32[ulSize / 4 + 1];
  316. retVal = HXR_FAIL;
  317. if (pMofBuf && (ulSize >= sizeof(HX_MOF)))
  318. {
  319.     retVal = HXR_OK;
  320. }
  321.     }
  322.     if (retVal == HXR_OK)
  323.     {
  324. retVal = m_pCodecLib->PNStream_GetStreamHeader(m_pStream,
  325.        (HX_MOF *) pMofBuf);
  326.     }
  327.     if (retVal == HXR_OK)
  328.     {
  329. m_pImageInfoBuffer = pMofBuf;
  330. pMofBuf = NULL;
  331. pImageInfo = (HX_MOF*) m_pImageInfoBuffer;
  332.     }
  333.     HX_VECTOR_DELETE(pMofBuf);
  334.     return retVal;
  335. }
  336. /****************************************************************************
  337.  *  Method:
  338.  *    CRVDecoder::OnNewImage
  339.  */
  340. HX_RESULT CRVXVDecoder::OnNewImage(HXSTREAM streamRef,
  341.    HXSTREAM fromStreamRef,
  342.    HXCODEC_DATA* pData)
  343. {
  344.     CRVXVDecoder* pDecoder = (CRVXVDecoder*) streamRef;
  345.     return pDecoder->DecodeDone(pData);
  346. }
  347. /****************************************************************************
  348.  *  Method:
  349.  *    CRVXVDecoder::ResetSequence()
  350.  */
  351. void CRVXVDecoder::ResetSequence(ULONG32 ulNewSequenceStartTS)
  352. {
  353.     m_ulSequenceStartTS = ulNewSequenceStartTS;
  354.     m_bNewSequence = TRUE;
  355. }
  356. CRADynamicCodecLibrary* CRVXVDecoder::CreateCodecLibrary()
  357. {
  358.     return new CRADynamicCodecLibrary(m_pContext);
  359. }
  360. /****************************************************************************
  361.  *  Private Methods
  362.  */
  363. /****************************************************************************
  364.  *  Method:
  365.  *    CRVXVDecoder::OpenCodec()
  366.  */
  367. HX_RESULT CRVXVDecoder::OpenCodec(const HX_MOF* pMofIn)
  368. {
  369.     HX_MOFTAG mofTag = 0;
  370.     HX_RESULT retVal = HXR_OK;
  371.     HX_ASSERT(pMofIn);
  372.     mofTag = pMofIn->submoftag;
  373.     m_moftagIn = mofTag;
  374.     HX_DELETE(m_pCodecLib);
  375.     // Create Codec Library
  376.     m_pCodecLib = CreateCodecLibrary();
  377.     retVal = HXR_OUTOFMEMORY;
  378.     if (m_pCodecLib != NULL)
  379.     {
  380. retVal = HXR_OK;
  381.     }
  382.     // Load Codec into library
  383.     if (SUCCEEDED(retVal))
  384.     {
  385. retVal = m_pCodecLib->LoadCodecLib(mofTag);
  386.     }
  387.     // Open the codec
  388.     if (SUCCEEDED(retVal))
  389.     {
  390. retVal = m_pCodecLib->PNCodec_Open(mofTag, &m_pCodec);
  391. if (FAILED(retVal))
  392. {
  393.     retVal = HXR_REQUEST_UPGRADE;
  394. }
  395.     }
  396.     return retVal;
  397. }
  398. /****************************************************************************
  399.  *  Method:
  400.  *    CRVXVDecoder::OpenStream
  401.  */
  402. HX_RESULT CRVXVDecoder::OpenStream(const HX_MOF* pMofIn)
  403. {
  404.     ULONG32 ulMofInDataSize = 0;
  405.     ULONG32* pMofInData = NULL;
  406.     HX_FORMAT_IMAGE2 mofOut;
  407.     HXCODEC_INIT codecInit;
  408.     HX_RESULT retVal = HXR_OK;
  409.     HX_ASSERT(pMofIn);
  410.     // Open Stream in some format: try most preferred first
  411.     if (SUCCEEDED(retVal))
  412.     {
  413. mofOut.cbLength = sizeof(HX_FORMAT_IMAGE2);
  414. mofOut.moftag = HX_MEDIA_IMAGE2;
  415. mofOut.submoftag = HX_YUV420_ID;
  416. m_moftagOut = HX_YUV420_ID;
  417.     }
  418.     if (SUCCEEDED(retVal))
  419.     {
  420. codecInit.pInMof = (HX_MOF*) pMofIn;
  421. codecInit.pOutMof = (HX_MOF*) &mofOut;
  422. codecInit.memoryRef = (HXMEMORY) m_pInputAllocator;
  423. codecInit.pContext = m_pContext;
  424.     }
  425.     if (retVal == HXR_OK)
  426.     {
  427. retVal = m_pCodecLib->PNCodec_StreamOpen(m_pCodec,
  428.  &m_pStream,
  429.  &codecInit);
  430. // TODO: If this fails, try other formats...
  431.     }
  432.     if (retVal == HXR_OK)
  433.     {
  434. retVal = m_pCodecLib->PNStream_SetDataCallback(
  435.     m_pStream,
  436.     this,
  437.     (HXMEMORY) m_pOutputAllocator,
  438.     OnNewImage);
  439.     }
  440.     if (retVal == HXR_OK)
  441.     {
  442. SetCodecQuality();
  443.     }
  444.     if (retVal == HXR_OK)
  445.     {
  446. BOOL bAllowDifferentOutputSizes = TRUE;
  447. //  tell codec we can handle different output sizes
  448. m_pCodecLib->PNStream_SetProperty(m_pStream,
  449.   SP_ALLOW_DIFFERENT_OUPUT_SIZES,
  450.   &bAllowDifferentOutputSizes);
  451.     }
  452.     // TODO: Setup image format based on codec output format
  453.     return retVal;
  454. }
  455. /****************************************************************************
  456.  *  Method:
  457.  *    CRVXVDecoder::GetQualityPreference
  458.  */
  459. HX_RESULT CRVXVDecoder::GetQualityPreference(UINT16 &usQuality)
  460. {
  461.     HX_RESULT pnr = HXR_OK;
  462. #if defined(HELIX_FEATURE_PREFERENCES)
  463.     IHXBuffer* pBuffer = NULL;
  464.     IHXPreferences* pPreferences = 0;
  465.     if (!m_pContext ||
  466. (m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences) !=
  467.  HXR_OK))
  468.     {
  469. pnr = HXR_INVALID_PARAMETER;
  470.     }
  471.     else
  472.     {
  473. ReadPrefINT16(pPreferences, "Quality", usQuality);
  474.     }
  475.     HX_RELEASE(pPreferences);
  476. #endif
  477.     return pnr;
  478. }
  479. /****************************************************************************
  480.  *  Method:
  481.  *    CRVXVDecoder::GetQualityPreference
  482.  */
  483. void CRVXVDecoder::SetCodecQuality(void)
  484. {
  485.     BOOL bOn, bOff;
  486.     UINT16 usQualityPreference = 4;
  487.     GetQualityPreference(usQualityPreference);
  488.     // Turn on or off post filter based on flags in source URL
  489.     // if the URL turns off post filter or the TLC quality
  490.     // preference is < 4 we turn off the post filter
  491.     bOn = (usQualityPreference >= 4);
  492.     m_pCodecLib->PNStream_SetProperty (m_pStream, SP_POSTFILTER, &bOn);
  493.     // Turn on or off FRU based on flags in source URL
  494.     bOn = (usQualityPreference >= 4);
  495.     m_pCodecLib->PNStream_SetProperty (m_pStream, SP_TEMPORALINTERP, &bOn);
  496.     // Turn on or off full decoding of B frames (reverse switch)
  497.     bOff = (usQualityPreference < 2);
  498.     m_pCodecLib->PNStream_SetProperty (m_pStream, SP_NOFULLDECODE, &bOff);
  499.     // Turn on or off deblocking of B frames (reverse switch)
  500.     bOff = (usQualityPreference < 3);
  501.     m_pCodecLib->PNStream_SetProperty (m_pStream, SP_NODEBLOCKBFRAMES, &bOff);
  502.     // Turn on or off decode of B-frames based on flags in source URL
  503.     bOn = (usQualityPreference >= 1);
  504.     m_pCodecLib->PNStream_SetProperty (m_pStream, SP_DECODE_B_FRAMES, &bOn);
  505. }