mp4vdec.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:14k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0 and Exhibits. 
  3.  * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM 
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. 
  5.  * All Rights Reserved. 
  6.  * 
  7.  * The contents of this file, and the files included with this file, are 
  8.  * subject to the current version of the RealNetworks Community Source 
  9.  * License Version 1.0 (the "RCSL"), including Attachments A though H, 
  10.  * all available at http://www.helixcommunity.org/content/rcsl. 
  11.  * You may also obtain the license terms directly from RealNetworks. 
  12.  * You may not use this file except in compliance with the RCSL and 
  13.  * its Attachments. There are no redistribution rights for the source 
  14.  * code of this file. Please see the applicable RCSL for the rights, 
  15.  * obligations and limitations governing use of the contents of the file. 
  16.  * 
  17.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  18.  * developer of the Original Code and owns the copyrights in the portions 
  19.  * it created. 
  20.  * 
  21.  * This file, and the files included with this file, is distributed and made 
  22.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  23.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  24.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  25.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  26.  * 
  27.  * Technology Compatibility Kit Test Suite(s) Location: 
  28.  * https://rarvcode-tck.helixcommunity.org 
  29.  * 
  30.  * Contributor(s): 
  31.  * 
  32.  * ***** END LICENSE BLOCK ***** */ 
  33. // #define _DRY_RUN
  34. /****************************************************************************
  35.  *  Includes
  36.  */
  37. #include "hxtypes.h"
  38. #include "hxresult.h"
  39. #include "hxassert.h"
  40. #include "hxwintyp.h"
  41. #include "hxcom.h"
  42. #include "hxmtypes.h"
  43. #include "hxcomm.h"
  44. #include "ihxpckts.h"
  45. #include "hxplugn.h"
  46. #include "hxengin.h"
  47. #include "hxerror.h"
  48. #include "hxformt.h"
  49. #include "hxprefs.h"
  50. #include "mp4vdec.h"
  51. #include "mp4vdfmt.h"
  52. #include "mp4video.h"
  53. #include "addupcol.h"
  54. #include "hlxclib/string.h"
  55. #include "hxheap.h"
  56. #ifdef _DEBUG
  57. #undef HX_THIS_FILE
  58. static char HX_THIS_FILE[] = __FILE__;
  59. #endif
  60. /****************************************************************************
  61.  *  Statics
  62.  */
  63. /****************************************************************************
  64.  *  Method:
  65.  *    CMP4VDecoder::CMP4VDecoder
  66.  */
  67. /****************************************************************************
  68.  *  Constructor/Destructor
  69.  */
  70. CMP4VDecoder::CMP4VDecoder()
  71.     : m_pContext(NULL)
  72.     , m_pVideoFormat(NULL)
  73.     , m_pCodecLib(NULL)
  74.     , m_pCodec(NULL)
  75.     , m_pStream(NULL)
  76.     , m_pCodecId(NULL)
  77.     , m_pInputAllocator(NULL)
  78.     , m_pOutputAllocator(NULL)
  79.     , m_moftagOut(0)
  80.     , m_ulLastTimeStamp(0)
  81. {
  82.     ;
  83. }
  84. CMP4VDecoder::~CMP4VDecoder()
  85. {
  86.     Close();
  87. }
  88. /****************************************************************************
  89.  *  Method:
  90.  *    CMP4VDecoder::Close
  91.  */
  92. HX_RESULT CMP4VDecoder::Close(void)
  93. {
  94.     if (m_pStream != NULL)
  95.     {
  96. m_pCodecLib->PNStream_Close(m_pStream);
  97. m_pStream = NULL;
  98.     }
  99.     if (m_pCodec != NULL)
  100.     {
  101. m_pCodecLib->PNCodec_Close(m_pCodec);
  102. m_pCodec = NULL;
  103.     }
  104.     HX_DELETE(m_pCodecLib);
  105.     HX_RELEASE(m_pInputAllocator);
  106.     HX_RELEASE(m_pOutputAllocator);
  107.     return HXR_OK;
  108. }
  109. /****************************************************************************
  110.  *  Method:
  111.  *    CMP4VDecoder::CMP4VDecoder
  112.  */
  113. HX_RESULT CMP4VDecoder::Init(IUnknown* pContext,
  114.      CMP4VideoFormat* pVideoFormat,
  115.      HXxSize* pSize,
  116.      IHX20MemoryAllocator* pInputAllocator,
  117.      IHX20MemoryAllocator* pOutputAllocator)
  118. {
  119.     HX_RESULT retVal = HXR_INVALID_PARAMETER;
  120.     m_pCodecId = "MP4V";
  121.     HX_RELEASE(m_pContext);
  122.     m_pContext = pContext;
  123.     HX_ASSERT(m_pContext);
  124.     if (m_pContext)
  125.     {
  126. retVal = HXR_OK;
  127.     }
  128.     if (SUCCEEDED(retVal))
  129.     {
  130. m_pVideoFormat = pVideoFormat;
  131. retVal = HXR_INVALID_PARAMETER;
  132. if (m_pVideoFormat)
  133. {
  134.     retVal = HXR_OK;
  135. }
  136.     }
  137.     if (SUCCEEDED(retVal))
  138.     {
  139. m_pInputAllocator = pInputAllocator;
  140. if (m_pInputAllocator)
  141. {
  142.     m_pInputAllocator->AddRef();
  143. }
  144. m_pOutputAllocator = pOutputAllocator;
  145. if (m_pOutputAllocator)
  146. {
  147.     m_pOutputAllocator->AddRef();
  148. }
  149. retVal = HXR_INVALID_PARAMETER;
  150. if (m_pInputAllocator && m_pOutputAllocator)
  151. {
  152.     retVal = HXR_OK;
  153. }
  154.     }
  155. #ifndef _DRY_RUN
  156.     // Open the codec
  157.     if (SUCCEEDED(retVal))
  158.     {
  159. retVal = OpenCodec(STRINGTOMOFTAG(m_pCodecId));
  160.     }
  161.     if (SUCCEEDED(retVal))
  162.     {
  163. retVal = OpenStream();
  164.     }
  165. #endif // _DRY_RUN
  166.     return retVal;
  167. }
  168. /****************************************************************************
  169.  *  Method:
  170.  *    CMP4VDecoder::Decode()
  171.  */
  172. HX_RESULT CMP4VDecoder::Decode(CMediaPacket* pFrameToDecode,
  173.        ULONG32 ulQuality) 
  174. {
  175.     ULONG32 ulFirstTimeStamp = 0;
  176.     HX_OQS2 theOutputQueueStatus;
  177.     HX_RESULT retVal = HXR_OK;
  178.     // tell the stream about renderer status so it can scale its processing
  179.     theOutputQueueStatus.queueDepth = m_pVideoFormat->GetDecodedFrameQueueDepth();
  180.     theOutputQueueStatus.newestQueueElementTimeStamp = m_ulLastTimeStamp;
  181.     m_pVideoFormat->GetNextFrameTime(ulFirstTimeStamp);
  182.     theOutputQueueStatus.oldestQueueElementTimeStamp = ulFirstTimeStamp;
  183.     theOutputQueueStatus.maxQueueDepth = m_pVideoFormat->m_ulMaxDecodedFrames; 
  184.     theOutputQueueStatus.currentTimeStamp = -m_pVideoFormat->m_pMP4VideoRenderer->ComputeTimeAhead(0, 0);
  185.     theOutputQueueStatus.nonFRUDroppedFrames = 0;
  186.     theOutputQueueStatus.TotalDroppedFrames = 0; 
  187.     // this is for Beta 2 codecs
  188. #ifdef _DRY_RUN
  189.     m_pInputAllocator->ReleasePacketPtr(((HXCODEC_DATA*) pFrameToDecode->m_pData)->data);
  190.     ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
  191.     retVal = DecodeDone(NULL);
  192. #else // _DRY_RUN
  193.     m_pCodecLib->PNStream_SetProperty(m_pStream, 
  194.       SP_OUPUT_QUEUE_STATUS, 
  195.       &theOutputQueueStatus);
  196.     // this is for > beta 2 codecs
  197.     m_pCodecLib->PNStream_SetProperty(m_pStream, 
  198.       SP_OUPUT_QUEUE_STATUS2, 
  199.       &theOutputQueueStatus);
  200.     m_pCodecLib->PNStream_Input(m_pStream, 
  201. NULL, 
  202. (HXCODEC_DATA*) pFrameToDecode->m_pData);
  203.     ((HXCODEC_DATA*) pFrameToDecode->m_pData)->data = NULL;
  204. #endif // _DRY_RUN
  205.     return retVal;
  206. }
  207. /****************************************************************************
  208.  *  Method:
  209.  *    CRVDecoder::DecodeDone
  210.  */
  211. HX_RESULT CMP4VDecoder::DecodeDone(HXCODEC_DATA* pData)
  212. {
  213.     if (pData)
  214.     {
  215. m_ulLastTimeStamp = pData->timestamp;
  216.     }
  217.     return m_pVideoFormat->DecodeDone(pData);
  218. }
  219. /****************************************************************************
  220.  *  Method:
  221.  *    CRVDecoder::GetImageInfo
  222.  */
  223. HX_RESULT CMP4VDecoder::GetImageInfo(HX_FORMAT_IMAGE &imageInfo)
  224. {
  225.     ULONG32 ulSize;
  226.     ULONG32* pMofBuf = NULL;
  227.     HX_RESULT retVal = HXR_OK;
  228.     retVal = m_pCodecLib->PNStream_GetStreamHeaderSize(m_pStream, 
  229.        &ulSize);
  230.     if (retVal == HXR_OK)
  231.     {
  232. HX_ASSERT((ulSize == sizeof(HX_FORMAT_IMAGE)) || 
  233.   (ulSize == sizeof(HX_FORMAT_IMAGE2)));
  234. pMofBuf = new ULONG32[ulSize / 4 + 1];
  235. retVal = HXR_OUTOFMEMORY;
  236. if (pMofBuf)
  237. {
  238.     retVal = HXR_OK;
  239. }
  240.     }
  241.     if (retVal == HXR_OK)
  242.     {
  243. retVal = m_pCodecLib->PNStream_GetStreamHeader(m_pStream, 
  244.        (HX_MOF *) pMofBuf);
  245.     }
  246.     if (retVal == HXR_OK)
  247.     {
  248. memcpy(&imageInfo, pMofBuf, sizeof(imageInfo));
  249.     }
  250.     HX_VECTOR_DELETE(pMofBuf);
  251.     return retVal;
  252. }
  253. /****************************************************************************
  254.  *  Method:
  255.  *    CRVDecoder::OnNewImage
  256.  */
  257. HX_RESULT CMP4VDecoder::OnNewImage(HXSTREAM streamRef, 
  258.    HXSTREAM fromStreamRef,
  259.    HXCODEC_DATA* pData)
  260. {
  261.     CMP4VDecoder* pDecoder = (CMP4VDecoder*) streamRef;
  262.     
  263.     return pDecoder->DecodeDone(pData);
  264. }
  265. CRADynamicCodecLibrary* CMP4VDecoder::CreateCodecLibrary()
  266. {
  267.     return new CRADynamicCodecLibrary(m_pContext);
  268. }
  269. /****************************************************************************
  270.  *  Private Methods
  271.  */
  272. /****************************************************************************
  273.  *  Method:
  274.  *    CMP4VDecoder::OpenCodec()
  275.  */
  276. HX_RESULT CMP4VDecoder::OpenCodec(HX_MOFTAG mofTag)
  277. {
  278.     HX_RESULT retVal = HXR_OK;
  279.     HX_DELETE(m_pCodecLib);
  280.     // Create Codec Library
  281.     m_pCodecLib = CreateCodecLibrary();
  282.     retVal = HXR_OUTOFMEMORY;
  283.     if (m_pCodecLib != NULL)
  284.     {
  285. retVal = HXR_OK;
  286.     }
  287.     // Load Codec into library
  288.     if (SUCCEEDED(retVal))
  289.     {
  290. retVal = m_pCodecLib->LoadCodecLib(mofTag);
  291.         if (FAILED(retVal))
  292.         {
  293.             // Generate the string
  294.             // XXXMEH - we really should centralize this code
  295.             // into CRADynamicCodecLibrary
  296.             char szAUStr[5]; /* Flawfinder: ignore */
  297.             szAUStr[0] = (char) ((mofTag >> 24) & 0x000000FF);
  298.             szAUStr[1] = (char) ((mofTag >> 16) & 0x000000FF);
  299.             szAUStr[2] = (char) ((mofTag >>  8) & 0x000000FF);
  300.             szAUStr[3] = (char) ( mofTag        & 0x000000FF);
  301.             szAUStr[4] = '';
  302.             // Make sure it's lower-case
  303.             strlwr(szAUStr);
  304.             // We failed to load the codec binary, so
  305.             // we need to add the string to the upgrade collection
  306.             AddToAutoUpgradeCollection(szAUStr, m_pContext);
  307.             // Make sure we return HXR_REQUEST_UPGRADE
  308.             // so that we know we failed due to not being able
  309.             // to load the codec as opposed to some other reason
  310.             retVal = HXR_REQUEST_UPGRADE;
  311.         }
  312.     }
  313.     // Open the codec
  314.     if (SUCCEEDED(retVal))
  315.     {
  316. retVal = m_pCodecLib->PNCodec_Open(mofTag, &m_pCodec);
  317. if (FAILED(retVal))
  318. {
  319.     retVal = HXR_REQUEST_UPGRADE;
  320. }
  321.     }
  322.     return retVal;
  323. }
  324. /****************************************************************************
  325.  *  Method:
  326.  *    CMP4VDecoder::OpenStream
  327.  */
  328. HX_RESULT CMP4VDecoder::OpenStream(void)
  329. {
  330.     ULONG32 ulMofInDataSize = 0;
  331.     ULONG32* pMofInData = NULL;
  332.     HX_FORMAT_NATIVE* pMofIn;
  333.     HX_FORMAT_IMAGE2 mofOut;
  334.     HXCODEC_INIT codecInit;
  335.     HX_RESULT retVal = HXR_OK;
  336.     if (SUCCEEDED(retVal))
  337.     {
  338. ulMofInDataSize = (m_pVideoFormat->GetBitstreamHeaderSize() / 4) + 1;
  339. ulMofInDataSize += sizeof(HX_FORMAT_NATIVE);
  340. pMofInData = new ULONG32 [ulMofInDataSize];
  341.  
  342. retVal = HXR_OUTOFMEMORY;
  343. if (pMofInData)
  344. {
  345.     retVal = HXR_OK;
  346. }
  347.     }
  348.     if (SUCCEEDED(retVal))
  349.     {
  350. pMofIn = (HX_FORMAT_NATIVE*) pMofInData;
  351. pMofIn->cbLength = m_pVideoFormat->GetBitstreamHeaderSize() + 
  352.    (pMofIn->data - ((UINT8*) pMofIn));
  353. pMofIn->moftag = HX_MEDIA_NATIVE;
  354. pMofIn->submoftag = STRINGTOMOFTAG(m_pCodecId);
  355. memcpy(pMofIn->data,
  356.        m_pVideoFormat->GetBitstreamHeader(),
  357.        m_pVideoFormat->GetBitstreamHeaderSize());
  358.     }
  359.     if (SUCCEEDED(retVal))
  360.     {
  361. mofOut.cbLength = sizeof(HX_FORMAT_IMAGE2);
  362. mofOut.moftag = HX_MEDIA_IMAGE2;
  363. mofOut.submoftag = HX_YUV420_ID;
  364. m_moftagOut = HX_YUV420_ID;
  365.     }
  366.     if (SUCCEEDED(retVal))
  367.     {
  368. codecInit.pInMof = (HX_MOF*) pMofIn;
  369. codecInit.pOutMof = (HX_MOF*) &mofOut;
  370. codecInit.memoryRef = (HXMEMORY) m_pInputAllocator;
  371. codecInit.pContext = m_pContext;
  372.     }
  373.     if (retVal == HXR_OK)
  374.     {
  375. retVal = m_pCodecLib->PNCodec_StreamOpen(m_pCodec, 
  376.  &m_pStream,
  377.  &codecInit);
  378.     }
  379.     if (retVal == HXR_OK)
  380.     {
  381. retVal = m_pCodecLib->PNStream_SetDataCallback(
  382.     m_pStream, 
  383.     this,
  384.     (HXMEMORY) m_pOutputAllocator,
  385.     OnNewImage);
  386.     }
  387.     if (retVal == HXR_OK)
  388.     {
  389. SetCodecQuality();
  390.     }
  391.     if (retVal == HXR_OK)
  392.     {
  393. BOOL bAllowDifferentOutputSizes = TRUE; 
  394. //  tell codec we can handle different output sizes
  395. m_pCodecLib->PNStream_SetProperty(m_pStream, 
  396.   SP_ALLOW_DIFFERENT_OUPUT_SIZES, 
  397.   &bAllowDifferentOutputSizes); 
  398.     }
  399.     HX_VECTOR_DELETE(pMofInData);
  400.     return retVal;
  401. }
  402. /****************************************************************************
  403.  *  Method:
  404.  *    CMP4VDecoder::GetQualityPreference
  405.  */
  406. HX_RESULT CMP4VDecoder::GetQualityPreference(UINT16 &usQuality)
  407. {
  408.     HX_RESULT pnr = HXR_OK;
  409.     IHXBuffer* pBuffer = NULL;
  410.     IHXPreferences* pPreferences = 0;
  411.     if (!m_pContext || 
  412. (m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences) !=
  413.  HXR_OK))
  414.     {
  415. pnr = HXR_INVALID_PARAMETER;
  416.     }
  417.     else
  418.     {
  419.         if (pPreferences->ReadPref("Quality", pBuffer) == HXR_OK)
  420. {   
  421.     usQuality = ::atoi((const char*) pBuffer->GetBuffer());
  422.     HX_RELEASE(pBuffer);
  423. }
  424.     }
  425.     HX_RELEASE(pPreferences);
  426.     return pnr;
  427. }
  428. /****************************************************************************
  429.  *  Method:
  430.  *    CMP4VDecoder::GetQualityPreference
  431.  */
  432. void CMP4VDecoder::SetCodecQuality(void)
  433. {
  434.     UINT16 usQualityPreference = 4;
  435.     GetQualityPreference(usQualityPreference);
  436.     
  437.     // Turn on or off post filter based on flags in source URL
  438.     // if the URL turns off post filter or the TLC quality
  439.     // preference is < 2 we turn off the post filter
  440.     BOOL bPostFilter = (usQualityPreference >= 2);
  441.     m_pCodecLib->PNStream_SetProperty(m_pStream, 
  442.       SP_POSTFILTER,
  443.       &bPostFilter);
  444.     // Turn on or off FRU based on flags in source URL
  445.     // BOOL bTemporalInterp = (usQualityPreference >= 2);
  446.     BOOL bTemporalInterp = FALSE;
  447.     m_pCodecLib->PNStream_SetProperty(m_pStream, 
  448.       SP_TEMPORALINTERP,
  449.       &bTemporalInterp);
  450.     // Turn on or off decode of B-frames based on flags in source URL
  451.     // BOOL bDecodeBFrames = (usQualityPreference >= 2);
  452.     BOOL bDecodeBFrames = FALSE;
  453.     m_pCodecLib->PNStream_SetProperty(m_pStream, 
  454.       SP_DECODE_B_FRAMES,
  455.       &bDecodeBFrames);
  456. }