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

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 _BYPASS_DECODER
  39. // #define _SILENT_PLAY
  40. // #define ENABLE_FRAME_TRACE
  41. #define _IGNORE_UNSUPPORTED // must be defined if _BYPASS_DECODER is defined
  42. #define MIN_ACCEPTBALE_DATA_REMAINDER 1 // in bytes
  43. #define MP4_DEFAULT_AUDIO_PREROLL 2000 // in milliseconds
  44. #define MAX_TOLERABLE_TIME_GAP 5 // in milliseconds
  45. /****************************************************************************
  46.  *  Includes
  47.  */
  48. #include "mp4afmt.h"
  49. #include "mp4adec.h"
  50. #include "hxtick.h"
  51. #include "hxassert.h"
  52. #include "hxstrutl.h"
  53. #include "mp4audio.h"
  54. #include "mp4apyld.h"
  55. #include "mp4gpyld.h"
  56. #include "amrpyld.h"
  57. #include "hxamrpyld.h"
  58. #if defined(HELIX_FEATURE_AUDIO_CODEC_MP3)
  59. #include "mp3draft.h"
  60. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_MP3) */
  61. /****************************************************************************
  62.  *  Debug
  63.  */
  64. #ifdef ENABLE_FRAME_TRACE
  65. #define MAX_FRAME_TRACE_ENTRIES 100000
  66. ULONG32 ulFrameTraceIdx = 0;
  67. LONG32 frameTraceArray[MAX_FRAME_TRACE_ENTRIES][4];
  68. void DumpFrameEntries(void)
  69. {
  70.     FILE* pFile = NULL;
  71.     ULONG32 ulIdx;
  72.     if (ulFrameTraceIdx > 0)
  73.     {
  74. pFile = fopen("c:\mp4a.txt", "wb");
  75.     }
  76.     if (pFile)
  77.     {
  78. for (ulIdx = 0; ulIdx < ulFrameTraceIdx; ulIdx++)
  79. {
  80.     fprintf(pFile, "%c(%d=%d) = %dn", (char) frameTraceArray[ulIdx][1], 
  81.    frameTraceArray[ulIdx][2],
  82.    frameTraceArray[ulIdx][3],
  83.    frameTraceArray[ulIdx][0]);
  84. }
  85. fclose(pFile);
  86.     }
  87.     ulFrameTraceIdx = 0;
  88. }
  89. #endif // ENABLE_FRAME_TRACE
  90. /****************************************************************************
  91.  *  Locals
  92.  */
  93. /****************************************************************************
  94.  *  Method:
  95.  *    CMP4AudioFormat::CMP4AudioFormat
  96.  *
  97.  */
  98. CMP4AudioFormat::CMP4AudioFormat(IHXCommonClassFactory* pCommonClassFactory,
  99.  CMP4AudioRenderer* pMP4AudioRenderer)
  100.     : CAudioFormat(pCommonClassFactory, pMP4AudioRenderer)
  101.     , m_pRssm(NULL)
  102.     , m_bNewAssembledFrame(TRUE)
  103.     , m_ulAUDuration(0)
  104.     , m_ulLastDecodedEndTime(0)
  105.     , m_ulLastFrameTime(0)
  106.     , m_ulCodecDelayMs(0)
  107.     , m_bCanChangeAudioStream(FALSE)
  108.     , m_ulMaxDecoderOutputBytes(0)
  109.     , m_ulMaxDecoderOutputSamples(0)
  110.     , m_pDecoderBuffer(NULL)
  111.     , m_ulDecoderBufferSize(0)
  112.     , m_pDecoderModule(NULL)
  113.     , m_pDecoderInstance(NULL)
  114.     , m_pMP4AudioRenderer(pMP4AudioRenderer)
  115. {
  116.     // Register the payload format builders with m_fmtFactory
  117.     RegisterPayloadFormats();
  118.     HX_ASSERT(m_pCommonClassFactory);
  119. }
  120. /****************************************************************************
  121.  *  Method:
  122.  *    CMP4AudioFormat::~CMP4AudioFormat
  123.  *
  124.  */
  125. CMP4AudioFormat::~CMP4AudioFormat()
  126. {
  127.     _Reset();
  128.     HX_RELEASE(m_pDecoderInstance);
  129.     HX_DELETE(m_pDecoderModule);
  130.     HX_VECTOR_DELETE(m_pDecoderBuffer);
  131.     HX_RELEASE(m_pRssm);
  132. #ifdef ENABLE_FRAME_TRACE
  133.     DumpFrameEntries();
  134. #endif // ENABLE_FRAME_TRACE
  135. }
  136. /****************************************************************************
  137.  *  Method:
  138.  *    CMP4AudioFormat::Init
  139.  *
  140.  */
  141. HX_RESULT CMP4AudioFormat::Init(IHXValues* pHeader)
  142. {
  143.     HX_RESULT retVal = CAudioFormat::Init(pHeader);
  144.     // Open the Decoder Module
  145.     if (SUCCEEDED(retVal))
  146.     {
  147. m_pDecoderModule = CreateDecoder();
  148. retVal = HXR_OUTOFMEMORY;
  149. if (m_pDecoderModule)
  150. {
  151.     retVal = HXR_OK;
  152. }
  153.     }
  154.     if (SUCCEEDED(retVal))
  155.     {
  156. retVal = m_pDecoderModule->Open(pHeader, 
  157. &m_pDecoderInstance,
  158. m_pContext);
  159. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  160.         if (FAILED(retVal) && retVal == HXR_REQUEST_UPGRADE)
  161.         {
  162.             // If we returned a HXR_REQUEST_UPGRADE, then we 
  163.             // failed to load the decoder binary. Therefore, we
  164.             // will copy the decoder's AU string into our
  165.             // own AU String
  166.             SafeStrCpy(m_szAUStr, // m_szAUStr is from our parent class
  167.                        m_pDecoderModule->GetAutoUpgradeString(),
  168.                        MAX_AUSTR_SIZE);
  169.         }
  170. #endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */
  171.     }
  172. #if defined(HELIX_FEATURE_STATS)
  173.     if (SUCCEEDED(retVal))
  174.     {
  175. char* pVal = (char*) m_pDecoderModule->GetCodecName();
  176. if (pVal)
  177. {
  178.     m_pMP4AudioRenderer->ReportStat(AS_CODEC_NAME, pVal);
  179. }
  180. pVal = (char*) m_pDecoderModule->GetCodecFourCC();
  181. if (pVal)
  182. {
  183.     m_pMP4AudioRenderer->ReportStat(AS_CODEC_4CC, pVal);
  184. }
  185.     }
  186. #endif /* #if defined(HELIX_FEATURE_STATS) */
  187.     // Create Packet Assembler
  188.     if (SUCCEEDED(retVal))
  189.     {
  190.         retVal = m_fmtFactory.BuildFormat(m_pCommonClassFactory, FALSE, 
  191.                                           pHeader, m_pRssm);
  192. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  193.         if (FAILED(retVal) && retVal == HXR_REQUEST_UPGRADE)
  194.         {
  195.             // If BuildFormat returns HXR_REQUEST_UPGRADE, then
  196.             // it means that no depacketizer had successful calls
  197.             // to Init() and SetStreamHeader(), but at least one
  198.             // of the depacketizers returned HXR_REQUEST_UPGRADE.
  199.             //
  200.             // Copy our own mime type into the AU string
  201.             IHXBuffer* pMimeTypeStr = NULL;
  202.             pHeader->GetPropertyCString("MimeType", pMimeTypeStr);
  203.             if (pMimeTypeStr)
  204.             {
  205.                 SafeStrCpy(m_szAUStr, // m_szAUStr is from our parent class
  206.                            (const char*) pMimeTypeStr->GetBuffer(),
  207.                            MAX_AUSTR_SIZE);
  208.             }
  209.             HX_RELEASE(pMimeTypeStr);
  210.         }
  211. #endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */
  212. #ifdef _IGNORE_UNSUPPORTED
  213. if (FAILED(retVal))
  214. {
  215.     HX_RELEASE(m_pDecoderInstance);
  216.     retVal = HXR_OK;
  217. }
  218. #endif // _IGNORE_UNSUPPORTED
  219.     }
  220.     
  221.     // Open Codec Instance
  222.     if (SUCCEEDED(retVal) && m_pDecoderInstance)
  223.     {
  224. HX_ASSERT(m_pDecoderModule);
  225. ULONG32 ulBitstreamHeaderSize;
  226. const UINT8* pBitstreamHeader;
  227.         UINT8 unBitstreamType;
  228. ulBitstreamHeaderSize = m_pRssm->GetBitstreamHeaderSize();
  229. pBitstreamHeader = m_pRssm->GetBitstreamHeader();
  230. unBitstreamType = m_pRssm->GetBitstreamType();
  231. retVal = HXR_FAIL;
  232. if (pBitstreamHeader && (ulBitstreamHeaderSize > 0))
  233. {
  234.     retVal = HXR_OK;
  235. }
  236. if (SUCCEEDED(retVal))
  237. {
  238.     retVal = m_pDecoderInstance->OpenDecoder(unBitstreamType, // eCfgDesc
  239.      pBitstreamHeader,
  240.      ulBitstreamHeaderSize);
  241.             if (FAILED(retVal))
  242.             {
  243. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  244.                 // If we failed in our OpenDecoder() call, then the
  245.                 // decoder must be a version which does not support the
  246.                 // particular profile which we passed in. Therefore,
  247.                 // we will AU with the "qtplayer" string to instruct
  248.                 // the TLC to attempt to play this file other means.
  249.                 //
  250.                 // Copy into our parent class's AU string buffer
  251.                 SafeStrCpy(m_szAUStr, // m_szAUStr is from our parent class
  252.                            "qtplayer",
  253.                            MAX_AUSTR_SIZE);
  254. #endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */
  255.                 // When CAudioFormat::Init() returns to where it was called
  256.                 // from CAudioRenderer::OnHeader(), then if the return code
  257.                 // is HXR_REQUEST_UPGRADE, then it will assume it needs
  258.                 // to AU, and will look for an AU string from CAudioFormat.
  259.                 // So we need to return HXR_REQUEST_UPGRADE.
  260.                 retVal = HXR_REQUEST_UPGRADE;
  261.             }
  262. }
  263. #ifdef _IGNORE_UNSUPPORTED
  264. if (FAILED(retVal) && retVal != HXR_REQUEST_UPGRADE)
  265. {
  266.     HX_RELEASE(m_pDecoderInstance);
  267.     retVal = HXR_OK;
  268. }
  269. #endif // _IGNORE_UNSUPPORTED
  270.     }
  271.     // Inquire and set Audio data parameters
  272.     if (SUCCEEDED(retVal) && m_pDecoderInstance)
  273.     {
  274.         retVal = UpdateAudioFormat(m_ulLastDecodedEndTime, TRUE);
  275.     }
  276.     if (SUCCEEDED(retVal))
  277.     {
  278. m_bCanChangeAudioStream = CanChangeAudioStream();
  279.     }
  280. #ifdef _BYPASS_DECODER
  281.     HX_RELEASE(m_pDecoderInstance);
  282. #endif // _BYPASS_DECODER
  283.     return retVal;
  284. }
  285. /****************************************************************************
  286.  *    CMP4AudioFormat::GetDefaultPreroll
  287.  */
  288. ULONG32 CMP4AudioFormat::GetDefaultPreroll(IHXValues* pValues)
  289. {
  290.     return MP4_DEFAULT_AUDIO_PREROLL;
  291. }
  292. HX_RESULT CMP4AudioFormat::UpdateAudioFormat(ULONG32& ulAnchorTime, 
  293.      BOOL bForceUpdate)
  294. {
  295.     HX_RESULT retVal = HXR_FAIL;
  296.     if (m_pDecoderInstance && m_pAudioFmt && m_pRssm)
  297.     {
  298. UINT32 ulChannels = 0;
  299. BOOL bFormatChanged = FALSE;
  300.         // Set the bits per sample (always 16 bits per sample)
  301.         m_pAudioFmt->uBitsPerSample = 16;                 
  302.         // Set number of channels
  303.         retVal = m_pDecoderInstance->GetNChannels(ulChannels);
  304.         if (SUCCEEDED(retVal))
  305.         {
  306.             retVal = HXR_FAIL;
  307.     if (ulChannels)
  308.     {
  309. retVal = HXR_OK;
  310. if ((ulChannels != m_pAudioFmt->uChannels) || bForceUpdate)
  311. {
  312.     bFormatChanged = TRUE;
  313. }
  314.     }
  315.         }
  316.         // Set the sample rate
  317.         if (SUCCEEDED(retVal))
  318.         {
  319.             UINT32 ulSampleRate = 0;
  320.             retVal = m_pDecoderInstance->GetSampleRate(ulSampleRate);
  321.             if (SUCCEEDED(retVal))
  322.             {
  323.                 retVal = HXR_FAIL;
  324.                 if (ulSampleRate)
  325.                 {
  326.     retVal = HXR_OK;
  327.     if ((m_pAudioFmt->ulSamplesPerSec != ulSampleRate) || 
  328. bForceUpdate)
  329.     {
  330. ULONG32 ulAnchorInMs = m_TSConverter.Convert(ulAnchorTime);
  331. m_pAudioFmt->uChannels = (UINT16) ulChannels;
  332. m_pAudioFmt->ulSamplesPerSec = ulSampleRate;
  333. ulAnchorTime =  ConvertMsToTime(ulAnchorInMs);
  334. ConfigureRssm(ulAnchorInMs);
  335. m_TSConverter.SetBase(ulSampleRate, 1000);
  336. m_TSConverter.SetOffset(ulAnchorInMs);
  337. bFormatChanged = TRUE;
  338.     }
  339.     else
  340.     {
  341. m_pAudioFmt->uChannels = (UINT16) ulChannels;
  342.     }  
  343.                 }
  344.             }
  345.         }
  346.         // Set the max samples out
  347.         if (SUCCEEDED(retVal))
  348.         {
  349.             UINT32 ulMaxSamplesOut = 0;
  350.             retVal = m_pDecoderInstance->GetMaxSamplesOut(ulMaxSamplesOut);
  351.             if (SUCCEEDED(retVal))
  352.             {
  353.                 retVal = HXR_FAIL;
  354.                 if (ulMaxSamplesOut)
  355.                 {
  356.                     retVal = HXR_OK;
  357.     if ((ulMaxSamplesOut != m_ulMaxDecoderOutputSamples) || 
  358. bForceUpdate)
  359.     {
  360. // Save the max samples out
  361. m_ulMaxDecoderOutputSamples = ulMaxSamplesOut;
  362. // Compute and set the AU duration
  363. m_ulAUDuration = m_ulMaxDecoderOutputSamples / m_pAudioFmt->uChannels;
  364. m_pRssm->SetAUDuration(m_ulAUDuration);
  365. // Compute the max output in bytes
  366. m_ulMaxDecoderOutputBytes = CAudioFormat::ConvertSamplesToBytes(m_ulMaxDecoderOutputSamples);
  367. // Save the max block size
  368. m_pAudioFmt->uMaxBlockSize = (UINT16) m_ulMaxDecoderOutputBytes;
  369. bFormatChanged = TRUE;
  370.     }
  371.                 }
  372.             }
  373.         }
  374.         // Set the codec delay in samples
  375.         if (bFormatChanged && SUCCEEDED(retVal))
  376.         {
  377.             UINT32 ulCodecDelaySamples = 0;
  378.             retVal = m_pDecoderInstance->GetDelay(ulCodecDelaySamples);
  379.             if (SUCCEEDED(retVal))
  380.             {
  381.                 // Compute and save the codec delay in ms
  382.                 m_ulCodecDelayMs = CAudioFormat::ConvertSamplesToMs(ulCodecDelaySamples);
  383.             }
  384.         }
  385.         // Allocate Decoder Buffer
  386.         if (SUCCEEDED(retVal))
  387.         {
  388.             // Did the size change?
  389.             if (m_ulDecoderBufferSize != m_ulMaxDecoderOutputBytes)
  390.             {
  391.                 retVal = HXR_OUTOFMEMORY;
  392.                 HX_VECTOR_DELETE(m_pDecoderBuffer);
  393.                 m_pDecoderBuffer = new UINT8 [m_ulMaxDecoderOutputBytes];
  394.                 if (m_pDecoderBuffer)
  395.                 {
  396.     retVal = HXR_OK;
  397.                     m_ulDecoderBufferSize = m_ulMaxDecoderOutputBytes;
  398.                 }
  399.             }
  400.         }
  401.     }
  402.     return retVal;
  403. }
  404. HX_RESULT CMP4AudioFormat::ConfigureRssm(ULONG32 ulAnchorInMs)
  405. {
  406.     HX_RESULT retVal = HXR_UNEXPECTED;
  407.     if (m_pRssm)
  408.     {
  409. CTSConverter tempConverter;
  410. ULONG32 ulRssmTimeBase;
  411. ULONG32 ulRssmAnchor;
  412. ULONG32 ulDecoderAnchor;
  413. ULONG32 ulSamplingRate = m_pAudioFmt->ulSamplesPerSec;
  414. retVal = HXR_OK;
  415. if (ulSamplingRate == 0)
  416. {
  417.     ulSamplingRate = 1000;
  418. }
  419. m_pRssm->SetSamplingRate(ulSamplingRate);
  420. m_pRssm->SetTimeAnchor(ulAnchorInMs);
  421. ulRssmTimeBase = m_pRssm->GetTimeBase();
  422. if (ulRssmTimeBase == 0)
  423. {
  424.     ulRssmTimeBase = m_pAudioFmt->ulSamplesPerSec;
  425. }
  426. m_InputTSConverter.SetBase(ulRssmTimeBase, 
  427.    m_pAudioFmt->ulSamplesPerSec);
  428. tempConverter.SetBase(1000, ulRssmTimeBase);
  429. ulRssmAnchor = tempConverter.ConvertVector(ulAnchorInMs);
  430. tempConverter.SetBase(1000, m_pAudioFmt->ulSamplesPerSec);
  431. ulDecoderAnchor = tempConverter.ConvertVector(ulAnchorInMs);
  432. m_InputTSConverter.SetAnchor(ulRssmAnchor, ulDecoderAnchor);
  433.     }
  434.     return retVal;
  435. }
  436. /****************************************************************************
  437.  *  Method:
  438.  *    CMP4AudioFormat::CreateAssembledPacket
  439.  *
  440.  */
  441. CMediaPacket* CMP4AudioFormat::CreateAssembledPacket(IHXPacket* pPacket)
  442. {
  443.     CMediaPacket* pLastFramePacket = NULL;
  444.     CMediaPacket* pFramePacket = NULL;
  445.     if (m_pRssm)
  446.     {
  447. if (pPacket)
  448. {
  449.     m_pRssm->SetPacket(pPacket);
  450. }
  451. else
  452. {
  453.     m_pRssm->Flush();
  454. }
  455. if (m_pRssm->CreateMediaPacket(pLastFramePacket) == HXR_OK)
  456. {
  457.     HX_ASSERT(pLastFramePacket);
  458.     
  459.     do
  460.     {
  461. pFramePacket = NULL;
  462. if (m_pRssm->CreateMediaPacket(pFramePacket) == HXR_OK)
  463. {
  464.     HX_ASSERT(pFramePacket);
  465.     
  466.     if (pLastFramePacket)
  467.     {
  468. CAudioFormat::PutAudioPacket(pLastFramePacket);
  469.     }
  470.     
  471.     pLastFramePacket = pFramePacket;
  472. }
  473.     } while (pFramePacket);
  474. }
  475.     }
  476.     return pLastFramePacket;
  477. }
  478. /****************************************************************************
  479.  *  Method:
  480.  *    CMP4AudioFormat::DecodeAudioData
  481.  *
  482.  */
  483. HX_RESULT CMP4AudioFormat::DecodeAudioData(HXAudioData& audioData,
  484.    BOOL bFlushCodec)
  485. {
  486.     ULONG32 ulBytesDecoded;
  487.     ULONG32 ulSamplesProduced;
  488.     ULONG32 ulBytesProduced;
  489.     ULONG32 ulNextDecodeStartTime;
  490.     ULONG32 ulPacketBasedNextDecodeStartTime;
  491.     HX_RESULT retVal = HXR_NO_DATA;
  492.     HX_RESULT checkStatus;
  493.     CMediaPacket* pAssembledFrame = NULL;
  494.     if (bFlushCodec)
  495.     {
  496. pAssembledFrame = CreateAssembledPacket(NULL);
  497.         if (pAssembledFrame)
  498.         {
  499.             CAudioFormat::PutAudioPacket(pAssembledFrame);
  500.         }
  501.     }
  502.     while ((pAssembledFrame = CAudioFormat::PeekAudioPacket()) &&
  503.    (retVal == HXR_NO_DATA))
  504.     {
  505. ulBytesDecoded = 0;
  506. ulSamplesProduced = 0;
  507. ulBytesProduced = 0;
  508. ulNextDecodeStartTime = m_ulLastDecodedEndTime;
  509. if (m_bNewAssembledFrame)
  510. {
  511.     LONG32 lDecodeStartOffset;
  512.     m_bNewAssembledFrame = FALSE;
  513.     // Filter uot fluctuations in time-stamps present in some poorly generated audio streams.
  514.     ulPacketBasedNextDecodeStartTime = m_InputTSConverter.Convert(pAssembledFrame->m_ulTime);
  515.     lDecodeStartOffset = ulPacketBasedNextDecodeStartTime - ulNextDecodeStartTime;
  516.     if (lDecodeStartOffset >= ((LONG32) m_ulLastFrameTime))
  517.     {
  518. ulNextDecodeStartTime = ulPacketBasedNextDecodeStartTime;
  519.     }
  520.     // Estimate audio frame time if unknown
  521.     if (pAssembledFrame->m_ulFlags & MDPCKT_HAS_UKNOWN_TIME_FLAG)
  522.     {
  523. if (CAudioRenderer::CmpTime(m_ulLastDecodedEndTime, ulNextDecodeStartTime) >= 0)
  524. {
  525.     ulNextDecodeStartTime = m_ulLastDecodedEndTime;
  526.     if (pAssembledFrame->m_ulFlags & MDPCKT_FOLLOWS_LOSS_FLAG)
  527.     {
  528. ulNextDecodeStartTime += m_ulLastFrameTime;
  529.     }
  530. }
  531.     }
  532.     // See if there was loss we need to conceal
  533.     if (pAssembledFrame->m_ulFlags & MDPCKT_FOLLOWS_LOSS_FLAG)
  534.     {
  535. if (CAudioRenderer::CmpTime(ulNextDecodeStartTime, m_ulLastDecodedEndTime) > 0)
  536. {
  537.     ULONG32 ulTimeLost = ulNextDecodeStartTime - 
  538.  m_ulLastDecodedEndTime;
  539.     if (CAudioFormat::ConvertTimeToMs(ulTimeLost) > MAX_TOLERABLE_TIME_GAP)
  540.     {
  541. ULONG32 ulSamplesLost = CAudioFormat::ConvertTimeToSamples(ulTimeLost);
  542. #ifdef ENABLE_FRAME_TRACE
  543. if (ulFrameTraceIdx < MAX_FRAME_TRACE_ENTRIES)
  544. {
  545.     frameTraceArray[ulFrameTraceIdx][2] = m_ulLastDecodedEndTime;
  546.     frameTraceArray[ulFrameTraceIdx][3] = CAudioFormat::ConvertTimeToMs(frameTraceArray[ulFrameTraceIdx][2]);
  547.     frameTraceArray[ulFrameTraceIdx][0] = 
  548. (LONG32) ulTimeLost;
  549.     frameTraceArray[ulFrameTraceIdx++][1] = 'G';
  550. }
  551. #endif // ENABLE_FRAME_TRACE
  552. // Conceal the lost samples
  553. if (m_pDecoderInstance)
  554. {
  555.     m_pDecoderInstance->Conceal(ulSamplesLost);
  556.     ulNextDecodeStartTime = m_ulLastDecodedEndTime;
  557. #ifdef ENABLE_FRAME_TRACE
  558.     if (ulFrameTraceIdx < MAX_FRAME_TRACE_ENTRIES)
  559.     {
  560. frameTraceArray[ulFrameTraceIdx][2] = ulNextDecodeStartTime;
  561. frameTraceArray[ulFrameTraceIdx][3] = CAudioFormat::ConvertTimeToMs(frameTraceArray[ulFrameTraceIdx][2]);
  562. frameTraceArray[ulFrameTraceIdx][0] = 
  563.     (LONG32) ulSamplesLost;
  564. frameTraceArray[ulFrameTraceIdx++][1] = 'C';
  565.     }
  566. #endif // ENABLE_FRAME_TRACE
  567. }
  568.     }
  569. }
  570.     }
  571. }
  572. checkStatus = CheckDecoderInstance(m_pDecoderInstance);
  573. if (FAILED(checkStatus))
  574. {
  575.     return checkStatus;
  576. }
  577.     // Decode some samples
  578. if (((CMediaPacket::GetBufferSize(pAssembledFrame) != 
  579.       pAssembledFrame->m_ulDataSize) &&
  580.      (pAssembledFrame->m_ulDataSize < MIN_ACCEPTBALE_DATA_REMAINDER))
  581. #ifdef _IGNORE_UNSUPPORTED
  582.     || (!m_pDecoderInstance)
  583. #endif // _IGNORE_UNSUPPORTED
  584.    )
  585. {
  586.     ulSamplesProduced = 0;
  587.     ulBytesDecoded = pAssembledFrame->m_ulDataSize;
  588. }
  589. else
  590. {
  591.     ulSamplesProduced = m_ulMaxDecoderOutputSamples;
  592.     ProcessAssembledFrame(pAssembledFrame);
  593.     retVal = m_pDecoderInstance->Decode(pAssembledFrame->m_pData,
  594. pAssembledFrame->m_ulDataSize,
  595. ulBytesDecoded,
  596. (INT16*) m_pDecoderBuffer,
  597. ulSamplesProduced,
  598. bFlushCodec);
  599.     if (retVal != HXR_OK)
  600.     {
  601. ulBytesDecoded = 0;
  602. ulSamplesProduced = 0;
  603.     }
  604. #ifdef ENABLE_FRAME_TRACE
  605.     if (ulFrameTraceIdx < MAX_FRAME_TRACE_ENTRIES)
  606.     {
  607. frameTraceArray[ulFrameTraceIdx][2] = ulNextDecodeStartTime;
  608. frameTraceArray[ulFrameTraceIdx][3] = CAudioFormat::ConvertTimeToMs(frameTraceArray[ulFrameTraceIdx][2]);
  609. frameTraceArray[ulFrameTraceIdx][0] = 
  610.     (LONG32) ulBytesDecoded;
  611. frameTraceArray[ulFrameTraceIdx++][1] = 'B';
  612.     }
  613.     if (ulFrameTraceIdx < MAX_FRAME_TRACE_ENTRIES)
  614.     {
  615. frameTraceArray[ulFrameTraceIdx][2] = ulNextDecodeStartTime;
  616. frameTraceArray[ulFrameTraceIdx][3] = CAudioFormat::ConvertTimeToMs(frameTraceArray[ulFrameTraceIdx][2]);
  617. frameTraceArray[ulFrameTraceIdx][0] = 
  618.     (LONG32) ulSamplesProduced;
  619. frameTraceArray[ulFrameTraceIdx++][1] = 'D';
  620.     }
  621. #endif // ENABLE_FRAME_TRACE
  622. }
  623. // Adjust ramaining data pointers based on bytes consumed
  624. HX_ASSERT(ulBytesDecoded <= pAssembledFrame->m_ulDataSize);
  625. if (ulBytesDecoded <= pAssembledFrame->m_ulDataSize)
  626. {
  627.     pAssembledFrame->m_ulDataSize -= ulBytesDecoded;
  628. }
  629. else
  630. {
  631.     pAssembledFrame->m_ulDataSize = 0;
  632. }
  633. pAssembledFrame->m_pData += ulBytesDecoded;
  634. // Place decoded data into the audio buffer
  635. if (ulSamplesProduced > 0)
  636. {
  637.     if (m_bCanChangeAudioStream && m_pDecoderInstance)
  638.     {
  639. retVal = UpdateAudioFormat(ulNextDecodeStartTime);
  640. if (FAILED(checkStatus))
  641. {
  642.     retVal = checkStatus;
  643. }
  644.     }
  645. #ifndef _SILENT_PLAY
  646.     if (SUCCEEDED(retVal))
  647.     {
  648. retVal = HXR_OK;
  649. ulBytesProduced = CAudioFormat::ConvertSamplesToBytes(ulSamplesProduced);
  650. if (retVal == HXR_OK)
  651. {
  652.     retVal = m_pCommonClassFactory->CreateInstance(
  653.     CLSID_IHXBuffer, 
  654.     (void**) &audioData.pData);
  655. }
  656. if (retVal == HXR_OK)
  657. {
  658.     retVal = audioData.pData->Set(
  659.     m_pDecoderBuffer,
  660.     ulBytesProduced);
  661. }
  662. if (retVal == HXR_OK)
  663. {
  664.     audioData.ulAudioTime = m_TSConverter.Convert(ulNextDecodeStartTime) -
  665.     m_ulCodecDelayMs;
  666. }
  667.     }
  668. #endif // _SILENT_PLAY
  669. }
  670. m_ulLastFrameTime = CAudioFormat::ConvertSamplesToTime(ulSamplesProduced);
  671. m_ulLastDecodedEndTime = ulNextDecodeStartTime + m_ulLastFrameTime;
  672.  
  673. if ((pAssembledFrame->m_ulDataSize == 0) ||
  674.     ((ulSamplesProduced == 0) && (ulBytesDecoded == 0)))
  675. {
  676.     CMediaPacket* pDeadAssembledFrame = CAudioFormat::GetAudioPacket();
  677.     HX_ASSERT(pAssembledFrame == pDeadAssembledFrame);
  678.     CMediaPacket::DeletePacket(pDeadAssembledFrame);
  679.     m_bNewAssembledFrame = TRUE;
  680. }
  681. if (ulSamplesProduced > 0)
  682. {
  683.     break;
  684. }
  685.     }
  686.     return retVal;
  687. }
  688. /****************************************************************************
  689.  *  Method:
  690.  *    CMP4AudioFormat::Reset
  691.  *
  692.  */
  693. void CMP4AudioFormat::Reset()
  694. {
  695.     _Reset();
  696.     CAudioFormat::Reset();
  697. }
  698. BOOL CMP4AudioFormat::CanChangeAudioStream()
  699. {
  700.     BOOL bRet = FALSE;
  701.     if (m_pDecoderModule)
  702.     {
  703.         bRet = m_pDecoderModule->CanChangeAudioStream();
  704.     }
  705.     return bRet;
  706. }
  707. void CMP4AudioFormat::RegisterPayloadFormats()
  708. {
  709.     // Register the various payload format builder functions
  710.     // with the payload format factory
  711. #if defined(HELIX_FEATURE_AUDIO_CODEC_AAC) || defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  712.     // MPEG4 audio formats
  713.     m_fmtFactory.RegisterBuilder(&MP4APayloadFormat::Build);
  714. #endif // defined(HELIX_FEATURE_AUDIO_CODEC_AAC)
  715. #if defined(HELIX_FEATURE_ISMA) || defined(HELIX_FEATURE_AUDIO_RALF)
  716.     m_fmtFactory.RegisterBuilder(&MP4GPayloadFormat::Build);
  717. #endif // defined(HELIX_FEATURE_ISMA) || defined(HELIX_FEATURE_AUDIO_RALF)
  718.     // AMR formats
  719. #if defined(HELIX_FEATURE_AUDIO_CODEC_AMRNB) || defined(HELIX_FEATURE_AUDIO_CODEC_AMRWB)
  720.     m_fmtFactory.RegisterBuilder(&CAMRPayloadFormat::Build);
  721.     m_fmtFactory.RegisterBuilder(&CHXAMRPayloadFormat::Build);
  722. #endif // defined(HELIX_FEATURE_AUDIO_CODEC_AMRNB) || defined(HELIX_FEATURE_AUDIO_CODEC_AMRWB)
  723. #if defined(HELIX_FEATURE_AUDIO_CODEC_MP3)
  724.     // MP3 format
  725.     m_fmtFactory.RegisterBuilder(&CMP3DraftPayloadFormat::Build);
  726. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_MP3) */
  727. }
  728. void CMP4AudioFormat::_Reset(void)
  729. {
  730.     if (m_pRssm)
  731.     {
  732. m_pRssm->Reset();
  733. m_pRssm->SetTimeAnchor(GetStartTime());
  734. ConfigureRssm(GetStartTime());
  735.     }
  736.     if (m_pDecoderInstance)
  737.     {
  738. m_pDecoderInstance->Reset();
  739.     }
  740.     m_ulLastDecodedEndTime = 0;
  741.     m_ulLastFrameTime = 0;
  742.     m_bNewAssembledFrame = TRUE;
  743.     m_TSConverter.Reset();
  744.     m_TSConverter.SetOffset(GetStartTime());
  745. }