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

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. /****************************************************************************
  36.  *  Defines
  37.  */
  38. #define _IGNORE_UNSUPPORTED
  39. #if !defined(HELIX_FEATURE_MIN_HEAP)
  40. #define MAX_BUFFERED_DECODED_RV_FRAMES 15
  41. #else // HELIX_FEATURE_MIN_HEAP
  42. #define MAX_BUFFERED_DECODED_RV_FRAMES 2
  43. #endif // HELIX_FEATURE_MIN_HEAP
  44. #define NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD  66 // in milliseconds
  45. #if defined(HELIX_FEATURE_MIN_HEAP)
  46. #define RVXV_DEFAULT_PREROLL     2000 // in milliseconds
  47. #else
  48. #define RVXV_DEFAULT_PREROLL     3500 // in milliseconds
  49. #endif
  50. #define IMG_FORMAT_POSSIBLE_CHANGE     1
  51. #define IMG_FORMAT_FORCED_CHANGE     2
  52. #define DECODE_CALLBACK_RNGBUF_SIZE     10
  53. #define UNINITIALIZED_SEQ_NUMBER     0xFFFFFFFF
  54. #define MAX_KEY_CODED_FRAME_FALLBEHIND -1200
  55. #define MAX_NONKEY_CODED_FRAME_FALLBEHIND -800
  56. /****************************************************************************
  57.  *  Includes
  58.  */
  59. #include "rvxvdfmt.h"
  60. #include "hxasm.h"
  61. #include "hxwin.h"
  62. #include "hxvsurf.h"
  63. #include "hxvctrl.h"
  64. #include "hxsite2.h"
  65. #include "hxthread.h"
  66. #include "hxtick.h"
  67. #include "hxassert.h"
  68. #include "hxstrutl.h"
  69. #include "unkimp.h"
  70. #include "timeval.h"
  71. #include "cttime.h"
  72. #include "hxcodec.h"
  73. #include "hxmtypes.h"
  74. #include "rvxvideo.h"
  75. /****************************************************************************
  76.  *  Locals
  77.  */
  78. /****************************************************************************
  79.  *  Method:
  80.  *    CRVXVideoFormat::CQTVideoFormat
  81.  *
  82.  */
  83. CRVXVideoFormat::CRVXVideoFormat(IHXCommonClassFactory* pCommonClassFactory,
  84.  CRVXVideoRenderer* pRVXVideoRenderer)
  85.     : CVideoFormat(pCommonClassFactory, pRVXVideoRenderer)
  86.     , m_pRVXVideoRenderer(pRVXVideoRenderer)
  87.     , m_pRssm(NULL)
  88.     , m_pDecoder(NULL)
  89.     , m_pInputAllocator(NULL)
  90.     , m_ulMaxDecodedFrames(0)
  91.     , m_ulWidthContainedInSegment(0)
  92.     , m_ulHeightContainedInSegment(0)
  93.     , m_pCodecOutputBIH(NULL)
  94.     , m_pDecodedRngBuf(NULL)
  95.     , m_bFirstDecode(TRUE)
  96.     , m_ulLastSequenceNumber(UNINITIALIZED_SEQ_NUMBER)
  97.     , m_bFlushingToKeyFrame(FALSE)
  98. {
  99.     HX_ASSERT(m_pCommonClassFactory);
  100.     HX_ASSERT(pRVXVideoRenderer);
  101.     m_sMediaSize.cx = 0;
  102.     m_sMediaSize.cy = 0;
  103.     m_pRVXVideoRenderer->AddRef();
  104. }
  105. /****************************************************************************
  106.  *  Method:
  107.  *    CRVXVideoFormat::~CQTVideoFormat
  108.  *
  109.  */
  110. CRVXVideoFormat::~CRVXVideoFormat()
  111. {
  112.     CVideoFormat::Reset();
  113.     HX_RELEASE(m_pRVXVideoRenderer);
  114.     if (m_pRssm)
  115.     {
  116. m_pRssm->Close();
  117. m_pRssm->Release();
  118. m_pRssm = NULL;
  119.     }
  120.     FlushDecodedRngBuf();
  121.     HX_DELETE(m_pDecodedRngBuf);
  122.     HX_DELETE(m_pDecoder);
  123.     _Reset();
  124.     if (m_pInputAllocator)
  125.     {
  126.         m_pInputAllocator->Release();
  127.         m_pInputAllocator = NULL;
  128.     }
  129.     HX_DELETE(m_pCodecOutputBIH);
  130. }
  131. /****************************************************************************
  132.  *  Method:
  133.  *    CRVXVideoFormat::Init
  134.  */
  135. HX_RESULT CRVXVideoFormat::Init(IHXValues* pHeader)
  136. {
  137.     HX_RESULT retVal = CVideoFormat::Init(pHeader);
  138.     m_bFlushingToKeyFrame = FALSE;
  139.     // Create Decode callback to caller ring buffer
  140.     if (SUCCEEDED(retVal))
  141.     {
  142. m_pDecodedRngBuf = new CRingBuffer(DECODE_CALLBACK_RNGBUF_SIZE);
  143. retVal = HXR_OUTOFMEMORY;
  144. if (m_pDecodedRngBuf)
  145. {
  146.     retVal = HXR_OK;
  147. }
  148.     }
  149.     // Create memory allocators
  150.     if (SUCCEEDED(retVal))
  151.     {
  152. retVal = CreateAllocators();
  153.     }
  154.     // Create Packet Assembler
  155.     if (SUCCEEDED(retVal))
  156.     {
  157. retVal = HXR_OUTOFMEMORY;
  158. m_pRssm = new RVXPayloadFormat(m_pInputAllocator);
  159. if (m_pRssm)
  160. {
  161.     m_pRssm->AddRef();
  162.     retVal = HXR_OK;
  163. }
  164.     }
  165.     
  166.     // Create Decoder
  167.     if (SUCCEEDED(retVal))
  168.     {
  169. retVal = HXR_OUTOFMEMORY;
  170. m_pDecoder = CreateDecoder();
  171. if (m_pDecoder)
  172. {
  173.     retVal = HXR_OK;
  174. }
  175.     }
  176.     // Initialize Assembler
  177.     if (SUCCEEDED(retVal) && m_pRssm)
  178.     {
  179. retVal = m_pRssm->Init(m_pRVXVideoRenderer->GetContext(), 
  180.        FALSE);
  181.     }
  182.     
  183.     if (SUCCEEDED(retVal) && m_pRssm)
  184.     {
  185. retVal = m_pRssm->SetStreamHeader(pHeader);
  186. if (retVal == HXR_NO_DATA)
  187. {
  188.     retVal = HXR_OK;
  189. }
  190. #ifdef _IGNORE_UNSUPPORTED
  191. if (FAILED(retVal))
  192. {
  193.     HXxSize nullViewFrame = {1, 1};
  194.     m_pRVXVideoRenderer->ResizeViewFrame(nullViewFrame);
  195.     HX_RELEASE(m_pRssm);
  196.     retVal = HXR_OK;
  197. }
  198. #endif // _IGNORE_UNSUPPORTED
  199.     }
  200.     // Initialize Decoder
  201.     if (SUCCEEDED(retVal) && m_pRssm)
  202.     {
  203. retVal = m_pDecoder->Init(m_pRVXVideoRenderer->GetContext(),
  204.   this,
  205.   NULL,
  206.   m_pInputAllocator,
  207.   m_pRVXVideoRenderer->m_pOutputAllocator);
  208. if (SUCCEEDED(retVal))
  209. {
  210.     HX_MOF* pImageInfo;
  211.     
  212.     if (m_pDecoder->GetImageInfo(pImageInfo) == HXR_OK)
  213.     {
  214. retVal = SetupOutputFormat(pImageInfo, m_pDecoder->GetMofTagIn());
  215. if (SUCCEEDED(retVal))
  216. {
  217.     if ((m_sMediaSize.cx != 0) && (m_sMediaSize.cy != 0))
  218.     {
  219. m_pRVXVideoRenderer->ResizeViewFrame(m_sMediaSize);
  220.     }
  221. }
  222.     }
  223. }
  224. #ifdef _IGNORE_UNSUPPORTED
  225. if (FAILED(retVal))
  226. {
  227.     HXxSize nullViewFrame = {1, 1};
  228.     m_pRVXVideoRenderer->ResizeViewFrame(nullViewFrame);
  229.     HX_RELEASE(m_pRssm);
  230.     retVal = HXR_OK;
  231. }
  232. #endif // _IGNORE_UNSUPPORTED
  233.     }
  234.     m_bFirstDecode = TRUE;
  235.     m_ulMaxDecodedFrames = GetMaxDecodedFrames();
  236.     return retVal;
  237. }
  238. /****************************************************************************
  239.  *  Method:
  240.  *    CRVXVideoFormat::SetupOutputFormat
  241.  *
  242.  */
  243. HX_RESULT
  244. CRVXVideoFormat::SetupOutputFormat(HX_MOF* pMof, HX_MOFTAG moftagIn)
  245. {
  246.     HX_RESULT pnr = HXR_OK;
  247.     HX_FORMAT_IMAGE* pMofOutI = (HX_FORMAT_IMAGE*) pMof;
  248.     if (!m_pCodecOutputBIH)
  249.     {
  250. m_pCodecOutputBIH = new HXBitmapInfoHeader;
  251. if (!m_pCodecOutputBIH)
  252. {
  253.     return HXR_OUTOFMEMORY;
  254. }
  255.     }
  256.     m_pRVXVideoRenderer->m_ulPadWidthLeft = 0;
  257.     m_pRVXVideoRenderer->m_ulPadWidthRight = 0;
  258.     m_pRVXVideoRenderer->m_ulPadHeightTop = 0;
  259.     m_pRVXVideoRenderer->m_ulPadHeightBottom = 0;
  260.     m_sMediaSize.cy = pMofOutI->uiHeight;
  261.     m_sMediaSize.cx = pMofOutI->uiWidth;
  262.     m_pCodecOutputBIH->biWidth = pMofOutI->uiWidth;
  263.     m_pCodecOutputBIH->biHeight = pMofOutI->uiHeight;
  264.     m_pCodecOutputBIH->biPlanes = 1;
  265.  
  266.     switch(pMofOutI->submoftag)
  267.     {
  268.         case HX_RGB3_ID:
  269.         {
  270.             m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
  271.             m_pCodecOutputBIH->biCompression = BI_RGB;
  272.         }
  273.         break;
  274.         case HX_YUV420_ID:
  275.         {
  276.             // fix up CLV1 screwed up bitcount
  277.             if (moftagIn == HX_CLEARVIDEO_ID)
  278.             {
  279.                 pMofOutI->uiBitCount = 12;
  280.             }
  281.             HX_ASSERT(pMofOutI->uiBitCount == 12);
  282.             m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
  283.             m_pCodecOutputBIH->biCompression = HX_I420;
  284.         
  285.             if (pMofOutI->moftag == HX_MEDIA_IMAGE2)
  286.             {
  287.                 HX_FORMAT_IMAGE2* pMofOutI2 = (HX_FORMAT_IMAGE2*)pMof;
  288.                 // if we are getting YUV out, it is a format image 2 struct
  289.                 // and we need to include padding in this width and height
  290. m_pRVXVideoRenderer->m_ulPadWidthLeft = pMofOutI2->uiPadWidthLeft;
  291. m_pRVXVideoRenderer->m_ulPadWidthRight = pMofOutI2->uiPadWidthRight;
  292. m_pRVXVideoRenderer->m_ulPadHeightTop = pMofOutI2->uiPadHeightTop;
  293. m_pRVXVideoRenderer->m_ulPadHeightBottom = pMofOutI2->uiPadHeightBottom;
  294.             }
  295.         }
  296.         break;
  297. #ifdef _WINDOWS
  298.         case HX_RGB555_ID:
  299.         {
  300.             HX_ASSERT(pMofOutI->uiBitCount == 16);
  301.             m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
  302.             m_pCodecOutputBIH->biCompression = BI_BITFIELDS;
  303.             m_pCodecOutputBIH->rcolor =   0x00007C00; // red
  304.             m_pCodecOutputBIH->gcolor =   0x000003E0; // green
  305.             m_pCodecOutputBIH->bcolor =   0x0000001F; // blue
  306.         }
  307.         break;
  308.         case HX_RGB565_ID:
  309.         {
  310.             HX_ASSERT(pMofOutI->uiBitCount == 16);
  311.             m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
  312.             m_pCodecOutputBIH->biCompression = BI_BITFIELDS;
  313.             m_pCodecOutputBIH->rcolor =    0x0000F800; // red
  314.             m_pCodecOutputBIH->gcolor =    0x000007E0; // green
  315.             m_pCodecOutputBIH->bcolor =    0x0000001F; // blue
  316.         }
  317.         break;
  318. #endif
  319.         default:
  320.             pnr = HXR_DEC_TYPE_MISMATCH;
  321.     }
  322.     m_pCodecOutputBIH->biWidth += (m_pRVXVideoRenderer->m_ulPadWidthLeft + 
  323.    m_pRVXVideoRenderer->m_ulPadWidthRight);
  324.     m_pCodecOutputBIH->biHeight += (m_pRVXVideoRenderer->m_ulPadHeightTop + 
  325.     m_pRVXVideoRenderer->m_ulPadHeightBottom);
  326.     m_pCodecOutputBIH->biSizeImage =
  327. m_pCodecOutputBIH->biWidth * m_pCodecOutputBIH->biBitCount * 
  328. m_pCodecOutputBIH->biHeight / 8;
  329.     return pnr;
  330. }
  331. /****************************************************************************
  332.  *  Method:
  333.  *    CRVXVideoFormat::GetDefaultPreroll
  334.  *
  335.  */
  336. ULONG32 CRVXVideoFormat::GetDefaultPreroll(IHXValues* pValues)
  337. {
  338.     return RVXV_DEFAULT_PREROLL;
  339. }
  340. /****************************************************************************
  341.  *  Method:
  342.  *    CRVXVideoFormat::GetBitstreamHeaderSize
  343.  */
  344. ULONG32 CRVXVideoFormat::GetBitstreamHeaderSize(void)
  345. {
  346.     ULONG32 ulSize = 0;
  347.     if (m_pRssm)
  348.     {
  349. ulSize = m_pRssm->GetBitstreamHeaderSize();
  350.     }
  351.     return ulSize;
  352. }
  353. /****************************************************************************
  354.  *  Method:
  355.  *    CRVXVideoFormat::GetBitstreamHeader
  356.  */
  357. const HX_MOF* CRVXVideoFormat::GetBitstreamHeader(void)
  358. {
  359.     const HX_MOF* pHeader = NULL;
  360.     if (m_pRssm)
  361.     {
  362. pHeader = m_pRssm->GetBitstreamHeader();
  363.     }
  364.     return pHeader;
  365. }
  366. /****************************************************************************
  367.  *  Method:
  368.  *    CVideoFormat::GetMaxDecodedFrames
  369.  *
  370.  */
  371. ULONG32 CRVXVideoFormat::GetMaxDecodedFrames(void)
  372. {
  373.     return MAX_BUFFERED_DECODED_RV_FRAMES;
  374. }
  375. /****************************************************************************
  376.  *  Method:
  377.  *    CRVXVideoFormat::CreateAssembledPacket
  378.  */
  379. CMediaPacket* CRVXVideoFormat::CreateAssembledPacket(IHXPacket* pCodecData)
  380. {
  381.     HXCODEC_DATA* pCodecPacket = NULL;
  382.     CMediaPacket* pFramePacket = NULL;
  383.     IHXPacket* pPacket = NULL;
  384.     HX_RESULT retVal = HXR_OK;
  385. #ifdef _IGNORE_UNSUPPORTED
  386.     if (!m_pRssm)
  387.     {
  388. return NULL;
  389.     }
  390. #endif // _IGNORE_UNSUPPORTED
  391.     m_pRVXVideoRenderer->BltIfNeeded();
  392.     retVal = m_pRssm->SetPacket(pCodecData);
  393.     if( retVal == HXR_OUTOFMEMORY )
  394.     {
  395.         m_LastError = HXR_OUTOFMEMORY;
  396.         return NULL;
  397.     }
  398.     m_pRssm->CreateHXCodecPacket(pCodecPacket);
  399.     
  400.     while (pCodecPacket)
  401.     {
  402.         CheckPacketBuffer(pCodecPacket);
  403. pFramePacket = new CMediaPacket(
  404. pCodecPacket,
  405. (UINT8*) pCodecPacket, 
  406. pCodecPacket->dataLength,
  407. pCodecPacket->dataLength,
  408. pCodecPacket->timestamp,
  409. pCodecPacket->flags, //0,
  410. NULL);
  411. if (pFramePacket == NULL)
  412. {
  413.     HX_ASSERT(HXR_OUTOFMEMORY == HXR_OK);
  414.     KillInputBuffer(pCodecPacket, this);
  415.             m_LastError = HXR_OUTOFMEMORY;
  416.             return NULL;
  417. }
  418. else
  419. {
  420.     pFramePacket->SetBufferKiller(KillInputBuffer);
  421.     pFramePacket->m_pUserData = this;
  422.     // Report missing frames as dropped
  423.     if (m_ulLastSequenceNumber != UNINITIALIZED_SEQ_NUMBER)
  424.     {
  425. UINT16 uFramesDropped = pCodecPacket->sequenceNum -
  426. ((UINT16) m_ulLastSequenceNumber) - 1;
  427. if (uFramesDropped != 0)
  428. {
  429.     if (m_pRVXVideoRenderer->IsActive() ||
  430. (((LONG32) (pCodecPacket->timestamp - GetStartTime())) > 0))
  431.     {
  432. m_pRVXVideoRenderer->ReportDroppedFrame(uFramesDropped);
  433.     }
  434. }
  435.     }
  436.     
  437.     m_ulLastSequenceNumber = (ULONG32) pCodecPacket->sequenceNum;
  438. }
  439. m_pRVXVideoRenderer->BltIfNeeded();
  440. pCodecPacket = NULL;
  441. m_pRssm->CreateHXCodecPacket(pCodecPacket);
  442. if (pCodecPacket)
  443. {
  444.     ReturnAssembledPacket(pFramePacket);
  445.     pFramePacket = NULL;
  446. }
  447.     }
  448.     
  449.     return pFramePacket;
  450. }
  451. /****************************************************************************
  452.  *  Method:
  453.  *    CRVXVideoFormat::Reset
  454.  */
  455. void CRVXVideoFormat::Reset()
  456. {
  457.     _Reset();
  458.     CVideoFormat::Reset();
  459. }
  460. void CRVXVideoFormat::_Reset(void)
  461. {
  462.     if (m_pRssm)
  463.     {
  464. m_pRssm->Reset();
  465.     }
  466.     m_bFirstDecode = TRUE;
  467.     m_ulWidthContainedInSegment = 0;
  468.     m_ulHeightContainedInSegment = 0;
  469.     m_ulLastSequenceNumber = UNINITIALIZED_SEQ_NUMBER;
  470. }
  471. void CRVXVideoFormat::FlushDecodedRngBuf(void)
  472. {
  473.     if (m_pDecodedRngBuf)
  474.     {
  475. HXCODEC_DATA* pFrame;
  476. while (pFrame = ((HXCODEC_DATA*) m_pDecodedRngBuf->Get()))
  477. {
  478.     ReleaseDecodedPacket(pFrame);
  479. }
  480.     }
  481. }
  482. void CRVXVideoFormat::ReleaseDecodedPacket(HXCODEC_DATA* &pDecodedPacket)
  483. {
  484.     HX_ASSERT(pDecodedPacket);
  485.     if (pDecodedPacket)
  486.     {
  487. ULONG32* pFrameData = (ULONG32*) pDecodedPacket;
  488. if (pDecodedPacket->data && 
  489.     m_pRVXVideoRenderer && 
  490.     m_pRVXVideoRenderer->m_pOutputAllocator)
  491. {
  492.     m_pRVXVideoRenderer->m_pOutputAllocator->ReleasePacketPtr(pDecodedPacket->data);
  493. }
  494. delete [] pFrameData;
  495. pDecodedPacket = NULL;
  496.     }
  497. }
  498. /****************************************************************************
  499.  *  Method:
  500.  *    CRVXVideoFormat::CreateDecodedPacket
  501.  *
  502.  */
  503. CMediaPacket* CRVXVideoFormat::CreateDecodedPacket(CMediaPacket* pFrameToDecode)
  504. {
  505.     HXCODEC_DATA* pDecodedPacket = NULL;
  506.     CMediaPacket* pDecodedFrame = NULL;
  507.     UINT8* pData = NULL;
  508.     BOOL bFrameDecoded = FALSE;
  509.     HX_ASSERT(pFrameToDecode);
  510. #if defined(HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES)
  511. // discard late frames before they are decoded
  512. BOOL bDecodeThisOne = TRUE;
  513.     if (m_pRVXVideoRenderer->IsActive()) // if playing
  514.     {
  515.         LONG32 lTimeAhead = m_pRVXVideoRenderer->ComputeTimeAhead(
  516.     pFrameToDecode->m_ulTime, 0); 
  517.         if (pFrameToDecode->m_ulFlags & HX_KEYFRAME_FLAG)
  518.         {
  519.             if (lTimeAhead < MAX_KEY_CODED_FRAME_FALLBEHIND)
  520.             {
  521.                 // Treat it as non key-frame: drop it
  522.                 bDecodeThisOne = FALSE;
  523.                 m_bFlushingToKeyFrame = TRUE;
  524.             }
  525.     else
  526.     { // we're going to display this key frame, so stop flushing
  527. m_bFlushingToKeyFrame = FALSE;
  528.     }
  529.         }
  530.         else
  531.         {
  532.             if (lTimeAhead < MAX_NONKEY_CODED_FRAME_FALLBEHIND)
  533.             { // discard this frame and all frames to the next key frame
  534.                 bDecodeThisOne = FALSE;
  535.                 m_bFlushingToKeyFrame = TRUE;
  536.             }
  537.     else
  538.     {
  539.     }
  540.         }
  541.     }
  542.     else
  543.     { // we're not playing, so decode when we start playing
  544. m_bFlushingToKeyFrame = FALSE;
  545.     }
  546.     if (bDecodeThisOne && !m_bFlushingToKeyFrame)
  547.     { // decode and display this frame
  548. ;
  549.     }
  550.     else
  551.     { // discard this frame before decode
  552. pFrameToDecode->Clear();
  553. delete pFrameToDecode; 
  554. m_pRVXVideoRenderer->ReportDroppedFrame();
  555. return NULL;
  556.     }
  557. #endif // HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES
  558.     if (m_bFirstDecode)
  559.     {
  560. m_bFirstDecode = FALSE;
  561. FlushDecodedRngBuf();
  562. m_pDecoder->ResetSequence(GetStartTime());
  563.     }
  564.     pDecodedPacket = (HXCODEC_DATA*) m_pDecodedRngBuf->Get();
  565.     m_pRVXVideoRenderer->BltIfNeeded();
  566.     HX_RESULT retVal = m_pDecoder->Decode(pFrameToDecode, MAX_DECODE_QUALITY);
  567.     if( retVal == HXR_OUTOFMEMORY )
  568.     {
  569.         m_LastError = HXR_OUTOFMEMORY;
  570.         return NULL;
  571.     }
  572.     else
  573.     {
  574. do
  575. {
  576.     if (pDecodedPacket == NULL)
  577.     {
  578. pDecodedPacket = (HXCODEC_DATA*) m_pDecodedRngBuf->Get();
  579.     }
  580.     bFrameDecoded = (pDecodedPacket != NULL);
  581. #if !defined(HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES)
  582. // don't discard decoded frames
  583.     if (pDecodedPacket)
  584.     {
  585. if (m_pRVXVideoRenderer->IsActive() &&
  586.     (m_pRVXVideoRenderer->ComputeTimeAhead(
  587. pDecodedPacket->timestamp, 
  588. 0) 
  589.      < -NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD))
  590. {
  591.     ReleaseDecodedPacket(pDecodedPacket);
  592.     m_pRVXVideoRenderer->ReportDroppedFrame();
  593. }
  594.     }
  595. #endif // HELIX_FEATURE_VIDEO_REAL_DISCARD_LATE_ENCODED_FRAMES
  596. } while ((!pDecodedPacket) && bFrameDecoded);
  597. if (pDecodedPacket)
  598. {
  599.     CMediaPacket* pVideoPacket = NULL;
  600.     pVideoPacket = (CMediaPacket*) m_pFramePool->Get(0);
  601.     if (pVideoPacket == NULL)
  602.     {
  603. pVideoPacket = pFrameToDecode;
  604. pFrameToDecode = NULL;
  605.     }
  606.     if (pVideoPacket)
  607.     {
  608. pVideoPacket->SetBuffer(pDecodedPacket->data,
  609. pDecodedPacket->data,
  610. pDecodedPacket->dataLength,
  611. pDecodedPacket->dataLength,
  612. FALSE);
  613. pVideoPacket->Init(pDecodedPacket->data,
  614.    pDecodedPacket->dataLength,
  615.    pDecodedPacket->timestamp,
  616.    pDecodedPacket->flags,
  617.    pDecodedPacket); // sample description
  618. // Data is now linked through VideoPacket
  619. pDecodedPacket->data = NULL;
  620. pDecodedPacket->dataLength = 0;
  621. pVideoPacket->SetBufferKiller(KillOutputBuffer);
  622. pVideoPacket->SetSampleDescKiller(KillRVXSampleDesc);
  623. pVideoPacket->m_pUserData = m_pRVXVideoRenderer;
  624. pDecodedPacket = NULL;
  625. pDecodedFrame = pVideoPacket;
  626. pVideoPacket = NULL;
  627.     }
  628.     if (pVideoPacket)
  629.     {
  630. delete pVideoPacket;
  631.     }
  632. }
  633.     }
  634.     if (pFrameToDecode != NULL)
  635.     {
  636. pFrameToDecode->Clear(); 
  637. delete pFrameToDecode;
  638.     }
  639.     if (pDecodedPacket)
  640.     {
  641. ReleaseDecodedPacket(pDecodedPacket);
  642.     }
  643.     return pDecodedFrame;
  644. }
  645. CRVXVDecoder* CRVXVideoFormat::CreateDecoder()
  646. {
  647.     return new CRVXVDecoder();
  648. }
  649. /****************************************************************************
  650.  *  Method:
  651.  *    CRVXVideoFormat::DecodeDone
  652.  */
  653. HX_RESULT CRVXVideoFormat::DecodeDone(HXCODEC_DATA* pData)
  654. {
  655.     HX_RESULT retVal = HXR_OK;
  656.     m_pRVXVideoRenderer->BltIfNeeded();
  657.     if (pData)
  658.     {
  659. ULONG32 ulFrameSize = HXCODEC_PTR_POPULATED_SIZE(pData);
  660. HXCODEC_DATA* pFrame = (HXCODEC_DATA*) new ULONG32[ulFrameSize / 4 + 1];
  661. if (pFrame)
  662. {
  663.     memcpy(pFrame, pData, ulFrameSize); /* Flawfinder: ignore */
  664.     if (!m_pDecodedRngBuf->Put(pFrame))
  665.     {
  666. ReleaseDecodedPacket(pFrame);
  667. m_pRVXVideoRenderer->ReportDroppedFrame();
  668.     }
  669. }
  670. else
  671. {
  672.     if (pData->data)
  673.     {
  674. m_pRVXVideoRenderer->m_pOutputAllocator->ReleasePacketPtr(
  675.     pData->data);
  676. m_pRVXVideoRenderer->ReportDroppedFrame();
  677.     }
  678. }
  679.     }
  680.     return retVal;
  681. }
  682. /****************************************************************************
  683.  *  Method:
  684.  *    CRVXVideoFormat::IsBitmapFormatChanged
  685.  *
  686.  */
  687. BOOL CRVXVideoFormat::IsBitmapFormatChanged(
  688.     HXBitmapInfoHeader &BitmapInfoHeader,
  689.     CMediaPacket* pVideoPacket)
  690. {
  691.     BOOL bRetVal = (m_ulWidthContainedInSegment == 0);
  692.     HXCODEC_DATA* pData = (HXCODEC_DATA*) pVideoPacket->m_pSampleDesc;
  693.     if (pData &&
  694. (pData->flags & HX_SEGMENT_CONTAINS_OUTPUT_SIZE_FLAG))
  695.     {
  696. bRetVal = (bRetVal ||
  697.     ((m_ulWidthContainedInSegment != pData->Segments[1].ulSegmentOffset) ||
  698.      (m_ulHeightContainedInSegment != ((ULONG32) pData->Segments[1].bIsValid))));
  699.     }
  700.     return bRetVal;
  701. }
  702. /****************************************************************************
  703.  *  Method:
  704.  *    CRVXVideoFormat::InitBitmapInfoHeader
  705.  */
  706. HX_RESULT CRVXVideoFormat::InitBitmapInfoHeader(
  707.     HXBitmapInfoHeader &bitmapInfoHeader,
  708.     CMediaPacket* pVideoPacket)
  709. {
  710.     if (m_pCodecOutputBIH)
  711.     {
  712. HXCODEC_DATA* pData = (HXCODEC_DATA*) pVideoPacket->m_pSampleDesc;
  713. if (pData && (pData->flags & HX_SEGMENT_CONTAINS_OUTPUT_SIZE_FLAG))
  714. {
  715.     if ((m_ulWidthContainedInSegment != pData->Segments[1].ulSegmentOffset) ||
  716.         (m_ulHeightContainedInSegment != ((ULONG32) pData->Segments[1].bIsValid)))
  717.     {
  718. m_pCodecOutputBIH->biWidth =  m_ulWidthContainedInSegment = 
  719.     pData->Segments[1].ulSegmentOffset;
  720. m_pCodecOutputBIH->biHeight = m_ulHeightContainedInSegment = 
  721.     ((ULONG32) pData->Segments[1].bIsValid);
  722. m_pCodecOutputBIH->biWidth += (m_pRVXVideoRenderer->m_ulPadWidthLeft + 
  723.        m_pRVXVideoRenderer->m_ulPadWidthRight);
  724. m_pCodecOutputBIH->biHeight += (m_pRVXVideoRenderer->m_ulPadHeightTop + 
  725. m_pRVXVideoRenderer->m_ulPadHeightBottom);
  726. m_pCodecOutputBIH->biSizeImage =
  727.     m_pCodecOutputBIH->biWidth * m_pCodecOutputBIH->biBitCount * 
  728.     m_pCodecOutputBIH->biHeight / 8;
  729.     }
  730. }
  731. else
  732. {
  733.     m_ulWidthContainedInSegment = m_pCodecOutputBIH->biWidth;
  734.     m_ulHeightContainedInSegment = m_pCodecOutputBIH->biHeight;
  735. }
  736.          
  737. bitmapInfoHeader = *m_pCodecOutputBIH;
  738.     }
  739.     return HXR_OK;
  740. }
  741. /****************************************************************************
  742.  *  Method:
  743.  *    CRVXVideoFormat::CreateAllocators()
  744.  */
  745. HX_RESULT CRVXVideoFormat::CreateAllocators(void)
  746. {
  747.     HX_RESULT retVal = HXR_OK;
  748.     HX20ALLOCPROPS allocRequest, allocActual;
  749.     if (m_pInputAllocator)
  750.     {
  751.         m_pInputAllocator->Release();
  752.         m_pInputAllocator = NULL;
  753.     }
  754.     if (m_pRVXVideoRenderer->m_pOutputAllocator)
  755.     {
  756.         m_pRVXVideoRenderer->m_pOutputAllocator->Release();
  757.         m_pRVXVideoRenderer->m_pOutputAllocator = NULL;
  758.     }
  759.     
  760.     // setup the input allocator for the codec
  761.     if (retVal == HXR_OK)
  762.     {
  763. m_pInputAllocator = new CHXMemoryAllocator(TRUE);
  764. retVal = HXR_OUTOFMEMORY;
  765. if (m_pInputAllocator)
  766. {
  767.     m_pInputAllocator->AddRef();
  768.     m_pInputAllocator->GetProperties(&allocRequest);
  769.     allocRequest.nNumBuffers = 0;   // No retention
  770.     m_pInputAllocator->SetProperties(&allocRequest, 
  771.      &allocActual);
  772.     retVal = HXR_OK;
  773. }
  774.     }
  775.     // setup the output allocator for the codec
  776.     if (retVal == HXR_OK)
  777.     {
  778. m_pRVXVideoRenderer->m_pOutputAllocator = new CHXMemoryAllocator(TRUE);
  779. retVal = HXR_OUTOFMEMORY;
  780. if (m_pRVXVideoRenderer->m_pOutputAllocator)
  781. {
  782.     m_pRVXVideoRenderer->m_pOutputAllocator->AddRef();
  783.     m_pRVXVideoRenderer->m_pOutputAllocator->GetProperties(&allocRequest);
  784.     allocRequest.nNumBuffers = GetMaxDecodedFrames() * 2;
  785.     m_pRVXVideoRenderer->m_pOutputAllocator->SetProperties(&allocRequest, 
  786. &allocActual);
  787.     retVal = HXR_OK;
  788. }
  789.     }
  790. #if _MACINTOSH
  791.     // TODO: we want to pre-allocate the output buffers here so they come
  792.     // from the standard memory pools instead of the interrupt memory
  793.     // pools.
  794. #endif // _MACINTOSH
  795.     return retVal;
  796. }
  797. /****************************************************************************
  798.  *  Method:
  799.  *    CMP4VideoFormat::KillRVXSampleDesc
  800.  *
  801.  */
  802. void CRVXVideoFormat::KillRVXSampleDesc(void* pSampleDesc, void* pUserData)
  803. {
  804.     if (pSampleDesc)
  805.     {
  806. HXCODEC_DATA* pFrame = (HXCODEC_DATA*) pSampleDesc;
  807. ULONG32* pFrameData = (ULONG32*) pFrame;
  808. if (pFrame->data)
  809. {
  810.     KillOutputBuffer(pFrame->data, pUserData);
  811. }
  812. delete [] pFrameData;
  813.     }
  814. }
  815. /****************************************************************************
  816.  *  Method:
  817.  *    CRVXVideoFormat::KillInputBuffer
  818.  *
  819.  */
  820. void CRVXVideoFormat::KillInputBuffer(void* pBuffer, void* pUserData)
  821. {
  822.     if (pBuffer)
  823.     {
  824. HXCODEC_DATA* pDeadData = (HXCODEC_DATA*) pBuffer;
  825. CRVXVideoFormat* pVidFmt = (CRVXVideoFormat*) pUserData;
  826. HX_ASSERT(pUserData);
  827. if (pDeadData->data)
  828. {
  829.     pVidFmt->m_pInputAllocator->ReleasePacketPtr(pDeadData->data);
  830.     pDeadData->data = NULL;
  831. }
  832. if (pVidFmt->m_pRssm)
  833. {
  834.     pVidFmt->m_pRssm->DisposeHXCodecPacket(pDeadData);
  835. }
  836.     }
  837. }
  838. /****************************************************************************
  839.  *  Method:
  840.  *    CRVXVideoFormat::KillOutputBuffer
  841.  *
  842.  */
  843. void CRVXVideoFormat::KillOutputBuffer(void* pBuffer, void* pUserData)
  844. {
  845.     if (pBuffer)
  846.     {
  847. CRVXVideoRenderer* pVidRnd = (CRVXVideoRenderer*) pUserData;
  848. HX_ASSERT(pUserData);
  849. if (NULL == pVidRnd || NULL == pVidRnd->m_pOutputAllocator)
  850.     return;
  851. pVidRnd->m_pOutputAllocator->ReleasePacketPtr((UINT8*) pBuffer);
  852.     }
  853. }