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

Symbian

开发平台:

Visual 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 _OVERALLOC_CODEC_DATA 3
  39. #define FLUSH_ALL_PACKETS   0xFFFFFFFF
  40. #define CHAR_LF 0x0a
  41. #define CHAR_CR 0x0d
  42. /****************************************************************************
  43.  *  Includes
  44.  */
  45. #include "hxtypes.h"
  46. #include "hxwintyp.h"
  47. #include "hxcom.h"
  48. #include "hxcomm.h"
  49. #include "hxassert.h"
  50. #include "hxslist.h"
  51. #include "hxstrutl.h"
  52. #include "hxcomm.h"
  53. #include "ihxpckts.h"
  54. #include "hxformt.h"
  55. #include "hxrendr.h"
  56. #include "hxformt.h"
  57. #include "hxengin.h"
  58. #include "mp4-latm-depack.h"
  59. #include "mp4desc.h"
  60. #include "mp4apyld.h"
  61. #include "mp4pyldutil.h"
  62. MP4APayloadFormat::MP4APayloadFormat()
  63.     : m_lRefCount     (0)
  64.     , m_pClassFactory     (NULL)
  65.     , m_pStreamHeader     (NULL)
  66.     , m_bFlushed     (FALSE)
  67.     , m_bUsesRTPPackets     (FALSE)
  68.     , m_bRTPPacketTested    (FALSE)
  69.     , m_bPacketize     (FALSE)
  70.     , m_pAudioConfig     (NULL)
  71.     , m_ulAudioConfigSize   (0)
  72.     , m_unAudioConfigType   (2)
  73.     , m_ulSamplesPerSecond  (1000)
  74.     , m_ulRTPSamplesPerSecond(0)
  75.     , m_PayloadID     (PYID_X_HX_MP4_RAWAU)
  76.     , m_bPriorLoss     (FALSE)
  77.     , m_pLATMDepack     (NULL)
  78. {
  79.     ;
  80. }
  81. MP4APayloadFormat::~MP4APayloadFormat()
  82. {
  83.     FlushPackets(FLUSH_ALL_PACKETS);
  84.     HX_VECTOR_DELETE(m_pAudioConfig);
  85.     HX_DELETE(m_pLATMDepack);
  86.     HX_RELEASE(m_pClassFactory);
  87.     HX_RELEASE(m_pStreamHeader);
  88. }
  89. HX_RESULT MP4APayloadFormat::Build(REF(IMP4APayloadFormat*) pFmt)
  90. {
  91.     pFmt = new MP4APayloadFormat();
  92.     HX_RESULT res = HXR_OUTOFMEMORY;
  93.     if (pFmt)
  94.     {
  95. pFmt->AddRef();
  96. res = HXR_OK;
  97.     }
  98.     return res;
  99. }
  100. // *** IUnknown methods ***
  101. /////////////////////////////////////////////////////////////////////////
  102. //  Method:
  103. // IUnknown::QueryInterface
  104. //  Purpose:
  105. // Implement this to export the interfaces supported by your
  106. // object.
  107. //
  108. STDMETHODIMP
  109. MP4APayloadFormat::QueryInterface(REFIID riid, void** ppvObj)
  110. {
  111.     QInterfaceList qiList[] =
  112.     {
  113. { GET_IIDHANDLE(IID_IUnknown), this },
  114. { GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
  115.     };
  116.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  117. }
  118. /////////////////////////////////////////////////////////////////////////
  119. //  Method:
  120. // IUnknown::AddRef
  121. //  Purpose:
  122. // Everyone usually implements this the same... feel free to use
  123. // this implementation.
  124. //
  125. STDMETHODIMP_(ULONG32)
  126. MP4APayloadFormat::AddRef()
  127. {
  128.     return InterlockedIncrement(&m_lRefCount);
  129. }
  130. /////////////////////////////////////////////////////////////////////////
  131. //  Method:
  132. // IUnknown::Release
  133. //  Purpose:
  134. // Everyone usually implements this the same... feel free to use
  135. // this implementation.
  136. //
  137. STDMETHODIMP_(ULONG32)
  138. MP4APayloadFormat::Release()
  139. {
  140.     if (InterlockedDecrement(&m_lRefCount) > 0)
  141.     {
  142.         return m_lRefCount;
  143.     }
  144.     delete this;
  145.     return 0;
  146. }
  147. STDMETHODIMP
  148. MP4APayloadFormat::Init(IUnknown* pContext,
  149. BOOL bPacketize)
  150. {
  151.     HX_RESULT retVal = HXR_OK;
  152.     HX_RELEASE(m_pClassFactory);
  153.     m_bPacketize = bPacketize;
  154.     if (SUCCEEDED(retVal))
  155.     {
  156. retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
  157.   (void**) &m_pClassFactory);
  158.     }
  159.     return retVal;
  160. }
  161. STDMETHODIMP
  162. MP4APayloadFormat::Reset()
  163. {
  164.     // Release all input packets we have stored
  165.     FlushPackets(FLUSH_ALL_PACKETS);
  166.     m_bFlushed = FALSE;
  167.     m_bPriorLoss = FALSE;
  168.     if (m_pLATMDepack)
  169.     {
  170. m_pLATMDepack->Reset();
  171.     }
  172.     m_TSConverter.Reset();
  173.     return HXR_OK;
  174. }
  175. STDMETHODIMP
  176. MP4APayloadFormat::SetStreamHeader(IHXValues* pHeader)
  177. {
  178.     HX_RESULT retVal;
  179.     if (pHeader)
  180.     {
  181. m_pStreamHeader = pHeader;
  182. m_pStreamHeader->AddRef();
  183.     }
  184.     if (m_bPacketize)
  185.     {
  186. retVal = SetPacketizerHeader(pHeader);
  187.     }
  188.     else
  189.     {
  190. retVal = SetAssemblerHeader(pHeader);
  191.     }
  192.     return retVal;
  193. }
  194. HX_RESULT MP4APayloadFormat::SetPacketizerHeader(IHXValues* pHeader)
  195. {
  196.     return HXR_OK;
  197. }
  198. HX_RESULT MP4APayloadFormat::SetAssemblerHeader(IHXValues* pHeader)
  199. {
  200.     IHXBuffer* pMimeType = NULL;
  201.     const char* pMimeTypeData = NULL;
  202.     HX_RESULT retVal = HXR_INVALID_PARAMETER;
  203.     if (pHeader)
  204.     {
  205. retVal = HXR_OK;
  206.     }
  207.     if (SUCCEEDED(retVal))
  208.     {
  209. retVal = pHeader->GetPropertyCString("MimeType", pMimeType);
  210.     }
  211.     if (SUCCEEDED(retVal))
  212.     {
  213. pMimeTypeData = (char*) pMimeType->GetBuffer();
  214. retVal = HXR_FAIL;
  215. if (pMimeTypeData)
  216. {
  217.     retVal = HXR_OK;
  218. }
  219.     }
  220.     // Determine payload type here based on mime type
  221.     if (SUCCEEDED(retVal))
  222.     {
  223. if (strcasecmp(pMimeTypeData, "audio/X-RN-MP4-RAWAU") == 0)
  224. {
  225.     m_PayloadID = PYID_X_HX_MP4_RAWAU;
  226. }
  227. else if (strcasecmp(pMimeTypeData, "audio/mpeg4-simple-A2") == 0)
  228. {
  229.     m_PayloadID = PYID_MPEG4_SIMPLE_A2;
  230. }
  231. else if (strcasecmp(pMimeTypeData, "audio/MP4A-LATM") == 0)
  232. {
  233.     m_PayloadID = PYID_MP4A_LATM;
  234. }
  235. else if (strcasecmp(pMimeTypeData, "audio/X-HX-AAC-GENERIC") == 0)
  236. {
  237.     m_PayloadID = PYID_X_HX_AAC_GENERIC;
  238. }
  239. else
  240. {
  241.     retVal = HXR_FAIL;
  242. }
  243.     }
  244.     if (SUCCEEDED(retVal))
  245.     {
  246. switch (m_PayloadID)
  247. {
  248. case PYID_X_HX_MP4_RAWAU:
  249.     retVal = SetAssemblerHXHeader(pHeader);
  250.     break;
  251. case PYID_MP4A_LATM:
  252.     retVal = SetAssemblerLATMHeader(pHeader);
  253.     break;
  254. case PYID_X_HX_AAC_GENERIC:
  255.     retVal = SetAssemblerAACGenericHeader(pHeader);
  256.     break;
  257. default:
  258.     retVal = HXR_NOTIMPL;
  259.     break;
  260. }
  261.     }
  262.     if (SUCCEEDED(retVal))
  263.     {
  264. m_ulSamplesPerSecond = 0;
  265. m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
  266.     m_ulRTPSamplesPerSecond);
  267.     }
  268.     HX_RELEASE(pMimeType);
  269.     return retVal;
  270. }
  271. HX_RESULT MP4APayloadFormat::SetAssemblerAACGenericHeader(IHXValues* pHeader)
  272. {
  273.     IHXBuffer *pBuffer = NULL;
  274.     UCHAR *pBuf = NULL;
  275.     HX_RESULT retVal = HXR_FAIL;
  276.     retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
  277. pBuffer);
  278.     if (SUCCEEDED(retVal))
  279.     {
  280.         m_pAudioConfig = NULL;
  281.         m_ulAudioConfigSize = pBuffer->GetSize();
  282.         if (m_ulAudioConfigSize)
  283.         {
  284.             pBuf = pBuffer->GetBuffer();
  285.             m_unAudioConfigType = pBuf[0];
  286.             if (--m_ulAudioConfigSize)
  287.             {
  288.                 m_pAudioConfig = new UINT8[m_ulAudioConfigSize];
  289.                 if (!m_pAudioConfig)
  290.                 {
  291.                     retVal = HXR_OUTOFMEMORY;
  292.                 }
  293.                 else
  294.                 {
  295.                     memcpy(m_pAudioConfig, &pBuf[1], m_ulAudioConfigSize);
  296.                 }
  297.             }
  298.         }
  299.         else
  300.         {
  301.             m_unAudioConfigType = 0; 
  302.         }
  303.     }
  304.     HX_RELEASE(pBuffer);
  305.     return retVal;
  306. }
  307. HX_RESULT MP4APayloadFormat::SetAssemblerHXHeader(IHXValues* pHeader)
  308. {
  309.     ES_Descriptor ESDesc;
  310.     DecoderConfigDescriptor* pDCDesc = NULL;
  311.     DecoderSpecifcInfo* pDSIDesc = NULL;
  312.     IHXBuffer* pESDescriptor = NULL;
  313.     UINT8* pESDescData;
  314.     ULONG32 ulESDescSize;
  315.     HX_RESULT retVal = HXR_OK;
  316.     HX_VECTOR_DELETE(m_pAudioConfig);
  317.     m_ulAudioConfigSize = 0;
  318.     retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
  319. pESDescriptor);
  320.     if (SUCCEEDED(retVal))
  321.     {
  322. retVal = HXR_INVALID_PARAMETER;
  323. if (pESDescriptor)
  324. {
  325.     retVal = HXR_OK;
  326. }
  327.     }
  328.     if (SUCCEEDED(retVal))
  329.     {
  330. pESDescData = pESDescriptor->GetBuffer();
  331. ulESDescSize = pESDescriptor->GetSize();
  332. retVal = ESDesc.Unpack(pESDescData, ulESDescSize);
  333.     }
  334.     HX_RELEASE(pESDescriptor);
  335.     if (SUCCEEDED(retVal))
  336.     {
  337. retVal = HXR_FAIL;
  338. pDCDesc = ESDesc.m_pDecConfigDescr;
  339. if (pDCDesc)
  340. {
  341.     pDSIDesc = pDCDesc->m_pDecSpecificInfo;
  342.     retVal = HXR_OK;
  343. }
  344.     }
  345.     if (SUCCEEDED(retVal) && pDSIDesc)
  346.     {
  347. m_ulAudioConfigSize = pDSIDesc->m_ulLength;
  348. if (m_ulAudioConfigSize > 0)
  349. {
  350.     m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
  351.     if (m_pAudioConfig == NULL)
  352.     {
  353. m_ulAudioConfigSize = 0;
  354. retVal = HXR_OUTOFMEMORY;
  355.     }
  356. }
  357.     }
  358.     if (SUCCEEDED(retVal))
  359.     {
  360. if (m_ulAudioConfigSize > 0)
  361. {
  362.     memcpy(m_pAudioConfig, pDSIDesc->m_pData, m_ulAudioConfigSize); /* Flawfinder: ignore */
  363. }
  364.     }
  365.     return retVal;
  366. }
  367. HX_RESULT MP4APayloadFormat::SetAssemblerLATMHeader(IHXValues* pHeader)
  368. {
  369.     HX_RESULT retVal = SetAssemblerLATMConfig(pHeader);
  370.     if (SUCCEEDED(retVal))
  371.     {
  372. m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
  373.     m_ulRTPSamplesPerSecond);
  374.     }
  375.     return retVal;
  376. }
  377. HX_RESULT MP4APayloadFormat::SetAssemblerLATMConfig(IHXValues* pFMTParams)
  378. {
  379.     IHXBuffer* pConfigBuffer = NULL;
  380.     ULONG32 ulObject = 0;
  381.     ULONG32 ulProfileID = 0;
  382.     ULONG32 ulBitrate = 0;
  383.     ULONG32 bConfigPresent = TRUE;
  384.     HX_RESULT retVal = HXR_OK;
  385.     HX_ASSERT(pFMTParams);
  386.     // Obtain Required parameters
  387.     retVal = CHXMP4PayloadUtil::GetFMTPConfig(pFMTParams, m_pClassFactory,
  388.       pConfigBuffer);
  389.     // Obtain optional parameters
  390.     if (SUCCEEDED(retVal))
  391.     {
  392. ULONG32 ulVal = 0;
  393. pFMTParams->GetPropertyULONG32("FMTPobject", ulObject);
  394. pFMTParams->GetPropertyULONG32("FMTPprofile-level-id", ulProfileID);
  395. if (SUCCEEDED(pFMTParams->GetPropertyULONG32("FMTPcpresent", ulVal)))
  396. {
  397.     bConfigPresent = (ulVal != 0);
  398. }
  399. pFMTParams->GetPropertyULONG32("FMTPbitrate", ulBitrate);
  400.     }
  401.     // Create and initialize the MP4A-LATM depacketizer
  402.     if (SUCCEEDED(retVal))
  403.     {
  404. HX_DELETE(m_pLATMDepack);
  405. m_pLATMDepack = new MP4LATMDepack;
  406. retVal = HXR_OUTOFMEMORY;
  407. if (m_pLATMDepack)
  408. {
  409.     retVal = HXR_OK;
  410. }
  411.     }
  412.     if (SUCCEEDED(retVal))
  413.     {
  414. UINT8* pStreamMuxConfig = NULL;
  415. ULONG32 ulMuxConfigSize = 0;
  416. const UINT8* pCodecConfig = NULL;
  417. ULONG32 ulConfigSize = 0;
  418. if (pConfigBuffer)
  419. {
  420.     pStreamMuxConfig = pConfigBuffer->GetBuffer();
  421.     ulMuxConfigSize = pConfigBuffer->GetSize();
  422. }
  423. retVal = HXR_FAIL;
  424. if (m_pLATMDepack->Init(ulProfileID,
  425. ulObject,
  426. ulBitrate,
  427. bConfigPresent,
  428. pStreamMuxConfig,
  429. ulMuxConfigSize,
  430. OnFrameCallback,
  431. this))
  432. {
  433.     retVal = HXR_OK;
  434. }
  435. if (SUCCEEDED(retVal))
  436. {
  437.     if (!m_pLATMDepack->GetCodecConfig(pCodecConfig,
  438.        ulConfigSize))
  439.     {
  440. pCodecConfig = NULL;
  441. ulConfigSize = 0;
  442.     }
  443. }
  444. if (SUCCEEDED(retVal))
  445. {
  446.     m_ulAudioConfigSize = ulConfigSize;
  447.     if (m_ulAudioConfigSize > 0)
  448.     {
  449. m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
  450. if (m_pAudioConfig == NULL)
  451. {
  452.     m_ulAudioConfigSize = 0;
  453.     retVal = HXR_OUTOFMEMORY;
  454. }
  455.     }
  456. }
  457. if (SUCCEEDED(retVal))
  458. {
  459.     if (m_ulAudioConfigSize > 0)
  460.     {
  461. memcpy(m_pAudioConfig, pCodecConfig, m_ulAudioConfigSize); /* Flawfinder: ignore */
  462.     }
  463. }
  464.     }
  465.     HX_RELEASE(pConfigBuffer);
  466.     return retVal;
  467. }
  468. STDMETHODIMP
  469. MP4APayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
  470. {
  471.     HX_RESULT retVal = HXR_FAIL;
  472.     if (m_pStreamHeader)
  473.     {
  474. retVal = HXR_OK;
  475. pHeader = m_pStreamHeader;
  476. pHeader->AddRef();
  477.     }
  478.     return retVal;
  479. }
  480. STDMETHODIMP
  481. MP4APayloadFormat::SetPacket(IHXPacket* pPacket)
  482. {
  483.     HX_RESULT retVal = HXR_OK;
  484.     HX_ASSERT(pPacket);
  485.     if (!m_bRTPPacketTested)
  486.     {
  487. IHXRTPPacket* pRTPPacket = NULL;
  488. m_bUsesRTPPackets = (pPacket->QueryInterface(
  489. IID_IHXRTPPacket,
  490. (void**) &pRTPPacket)
  491.     == HXR_OK);
  492. m_bRTPPacketTested = TRUE;
  493. HX_RELEASE(pRTPPacket);
  494. if (m_bUsesRTPPackets)
  495. {
  496.     if (m_ulRTPSamplesPerSecond == 0)
  497.     {
  498. m_ulRTPSamplesPerSecond = m_ulSamplesPerSecond;
  499.     }
  500. }
  501. else
  502. {
  503.     m_ulRTPSamplesPerSecond = 1000; // RDT time stamp
  504. }
  505. m_TSConverter.SetBase(m_ulRTPSamplesPerSecond,
  506.       m_ulSamplesPerSecond);
  507.     }
  508.     // Add this packet to our list of input packets
  509.     switch (m_PayloadID)
  510.     {
  511.     case PYID_X_HX_AAC_GENERIC:
  512.     case PYID_X_HX_MP4_RAWAU:
  513. pPacket->AddRef();
  514. m_InputPackets.AddTail(pPacket);
  515. break;
  516.     case PYID_MP4A_LATM:
  517. retVal = HXR_FAIL;
  518. if (m_pLATMDepack)
  519. {
  520.     if (pPacket->IsLost())
  521.     {
  522. if (m_pLATMDepack->OnLoss(1))
  523. {
  524.     retVal = HXR_OK;
  525. }
  526.     }
  527.     else
  528.     {
  529. IHXBuffer* pBuffer = pPacket->GetBuffer();
  530. if (pBuffer &&
  531.     m_pLATMDepack->OnPacket(GetPacketTime(pPacket),
  532.     pBuffer->GetBuffer(),
  533.     pBuffer->GetSize(),
  534.     (pPacket->GetASMRuleNumber() == 1)))
  535. {
  536.     retVal = HXR_OK;
  537.     pBuffer->Release();
  538. }
  539.     }
  540. }
  541. break;
  542.     default:
  543. retVal = HXR_NOTIMPL;
  544. break;
  545.     }
  546.     return retVal;
  547. }
  548. STDMETHODIMP
  549. MP4APayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
  550. {
  551.     HX_RESULT retVal = HXR_OK;
  552.     if (m_bPacketize)
  553.     {
  554. retVal = GetPacketizerPacket(pOutPacket);
  555.     }
  556.     else
  557.     {
  558. retVal = GetAssemblerPacket(pOutPacket);
  559.     }
  560.     return retVal;
  561. }
  562. HX_RESULT MP4APayloadFormat::GetPacketizerPacket(IHXPacket* &pOutPacket)
  563. {
  564.     HX_RESULT retVal = HXR_INCOMPLETE;
  565.     if (!m_InputPackets.IsEmpty())
  566.     {
  567. pOutPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  568. retVal = HXR_OK;
  569.     }
  570.     else if (m_bFlushed)
  571.     {
  572. retVal = HXR_STREAM_DONE;
  573.     }
  574.     return retVal;
  575. }
  576. HX_RESULT MP4APayloadFormat::GetAssemblerPacket(IHXPacket* &pOutPacket)
  577. {
  578.     HX_RESULT retVal = HXR_NOTIMPL;
  579.     return retVal;
  580. }
  581. HX_RESULT MP4APayloadFormat::SetSamplingRate(ULONG32 ulSamplesPerSecond)
  582. {
  583.     HX_RESULT retVal = HXR_UNEXPECTED;
  584.     if (!m_bRTPPacketTested)
  585.     {
  586. m_ulSamplesPerSecond = ulSamplesPerSecond;
  587. retVal = HXR_OK;
  588.     }
  589.     return HXR_OK;
  590. }
  591. ULONG32 MP4APayloadFormat::GetTimeBase(void)
  592. {
  593.     return m_ulSamplesPerSecond;
  594. }
  595. HX_RESULT MP4APayloadFormat::SetAUDuration(ULONG32 ulAUDuration)
  596. {
  597.     HX_RESULT retVal = HXR_UNEXPECTED;
  598.     if (!m_bRTPPacketTested)
  599.     {
  600. switch (m_PayloadID)
  601. {
  602. case PYID_MP4A_LATM:
  603.     retVal = HXR_FAIL;
  604.     
  605.     if (m_pLATMDepack &&
  606. m_pLATMDepack->SetFrameDuration(ulAUDuration))
  607.     {
  608. retVal = HXR_OK;
  609.     }
  610.     break;
  611.     
  612. default:
  613.     retVal = HXR_NOTIMPL;
  614.     break;
  615. }
  616.     }
  617.     return retVal;
  618. }
  619. HX_RESULT MP4APayloadFormat::SetTimeAnchor(ULONG32 ulTimeMs)
  620. {
  621.     CTSConverter tempConverter;
  622.     ULONG32 ulSamplesAnchor;
  623.     ULONG32 ulRTPSamplesAnchor;
  624.     tempConverter.SetBase(1000, m_ulSamplesPerSecond);
  625.     ulSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);
  626.     tempConverter.SetBase(1000, m_ulRTPSamplesPerSecond);
  627.     ulRTPSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);
  628.     m_TSConverter.SetAnchor(ulRTPSamplesAnchor, ulSamplesAnchor);
  629.     return HXR_OK;
  630. }
  631. HX_RESULT MP4APayloadFormat::CreateMediaPacket(CMediaPacket* &pOutMediaPacket)
  632. {
  633.     HX_RESULT retVal = HXR_OK;
  634.     switch (m_PayloadID)
  635.     {
  636.     case PYID_X_HX_AAC_GENERIC:
  637.     case PYID_X_HX_MP4_RAWAU:
  638. retVal = CreateRawAUMediaPacket(pOutMediaPacket);
  639. break;
  640.     case PYID_MP4A_LATM:
  641. if (m_OutMediaPacketQueue.IsEmpty())
  642. {
  643.     if (m_bFlushed)
  644.     {
  645. // We have used up all available input
  646. retVal = HXR_STREAM_DONE;
  647.     }
  648.     else
  649.     {
  650. // We don't have enough input
  651. // data to produce a packet
  652. retVal = HXR_INCOMPLETE;
  653.     }
  654. }
  655. else
  656. {
  657.     pOutMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
  658. }
  659. break;
  660.     default:
  661. retVal = HXR_NOTIMPL;
  662. break;
  663.     }
  664.     return retVal;
  665. }
  666. HX_RESULT MP4APayloadFormat::OnFrame(ULONG32 ulTime,
  667.      const UINT8* pData,
  668.      ULONG32 ulSize,
  669.      BOOL bPreviousLoss)
  670. {
  671.     ULONG32 ulFlags = 0;
  672.     CMediaPacket* pMediaPacket = NULL;
  673.     HX_RESULT retVal = HXR_OK;
  674.     if (pData && (ulSize != 0))
  675.     {
  676. ULONG32 ulNewSize;
  677. if (bPreviousLoss)
  678. {
  679.     ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
  680. }
  681. #ifdef _OVERALLOC_CODEC_DATA
  682. ulNewSize = ulSize + _OVERALLOC_CODEC_DATA;
  683. #else // _OVERALLOC_CODEC_DATA
  684. ulNewSize = ulSize;
  685. #endif // _OVERALLOC_CODEC_DATA
  686. UINT8* pNewData = new UINT8 [ulNewSize];
  687. if (pData)
  688. {
  689.     memcpy(pNewData, pData, ulSize); /* Flawfinder: ignore */
  690.     pMediaPacket = new CMediaPacket(pNewData,
  691.     pNewData,
  692.     ulNewSize,
  693.     ulSize,
  694.     ulTime,
  695.     ulFlags,
  696.     NULL);
  697. }
  698.     }
  699.     if (pMediaPacket)
  700.     {
  701. m_OutMediaPacketQueue.AddTail(pMediaPacket);
  702.     }
  703.     return retVal;
  704. }
  705. void MP4APayloadFormat::OnFrameCallback(void* pUserData,
  706. ULONG32 ulTime,
  707. const UINT8* pData,
  708. ULONG32 ulSize,
  709. BOOL bPreviousLoss)
  710. {
  711.     MP4APayloadFormat* pObject = (MP4APayloadFormat*) pUserData;
  712.     pObject->OnFrame(ulTime, pData, ulSize, bPreviousLoss);
  713. }
  714. HX_RESULT MP4APayloadFormat::CreateRawAUMediaPacket(CMediaPacket* &pOutMediaPacket)
  715. {
  716.     CMediaPacket* pMediaPacket;
  717.     IHXPacket* pPacket = NULL;
  718.     HX_RESULT retVal = HXR_OK;
  719.     if (m_InputPackets.IsEmpty())
  720.     {
  721. if (m_bFlushed)
  722. {
  723.     // We have used up all available input
  724.     retVal = HXR_STREAM_DONE;
  725. }
  726. else
  727. {
  728.     // We don't have enough input
  729.     // data to produce a packet
  730.     retVal = HXR_INCOMPLETE;
  731. }
  732.     }
  733.     else
  734.     {
  735. ULONG32 ulFlags = MDPCKT_USES_IHXBUFFER_FLAG;
  736. IHXBuffer* pBuffer = NULL;
  737. pPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  738. if (!pPacket->IsLost())
  739. {
  740.     pBuffer = pPacket->GetBuffer();
  741.     if (pBuffer)
  742.     {
  743. if (m_bPriorLoss)
  744. {
  745.     ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
  746.     m_bPriorLoss = FALSE;
  747. }
  748. pMediaPacket = BuildMediaPacket(pBuffer,
  749. GetPacketTime(pPacket),
  750. ulFlags);
  751. retVal = HXR_OUTOFMEMORY;
  752. if (pMediaPacket)
  753. {
  754.     pOutMediaPacket = pMediaPacket;
  755.     retVal = HXR_OK;
  756. }
  757. pBuffer->Release();
  758.     }
  759.     else
  760.     {
  761. m_bPriorLoss = TRUE;
  762. retVal = HXR_INCOMPLETE;
  763.     }
  764.     pPacket->Release();
  765. }
  766. else
  767. {
  768.     m_bPriorLoss = TRUE;
  769.     retVal = HXR_INCOMPLETE;
  770. }
  771.     }
  772.     return retVal;
  773. }
  774. CMediaPacket* MP4APayloadFormat::BuildMediaPacket(IHXBuffer* pBuffer,
  775.   ULONG32 ulTime,
  776.   ULONG32 ulFlags)
  777. {
  778.     CMediaPacket* pMediaPacket = NULL;
  779. #ifdef _OVERALLOC_CODEC_DATA
  780.     UINT8* pData = new UINT8 [pBuffer->GetSize() + _OVERALLOC_CODEC_DATA];
  781.     if (pData)
  782.     {
  783. memcpy(pData, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  784. ulFlags &= (~MDPCKT_USES_IHXBUFFER_FLAG);
  785. pMediaPacket = new CMediaPacket(pData,
  786. pData,
  787. pBuffer->GetSize() + 3,
  788. pBuffer->GetSize(),
  789. ulTime,
  790. ulFlags,
  791. NULL);
  792.     }
  793. #else // _OVERALLOC_CODEC_DATA
  794.     pMediaPacket = new CMediaPacket(pBuffer,
  795.     pBuffer->GetBuffer(),
  796.     pBuffer->GetSize(),
  797.     pBuffer->GetSize(),
  798.     ulTime,
  799.     ulFlags,
  800.     NULL);
  801. #endif // _OVERALLOC_CODEC_DATA
  802.     return pMediaPacket;
  803. }
  804. STDMETHODIMP
  805. MP4APayloadFormat::Flush()
  806. {
  807.     if (m_pLATMDepack)
  808.     {
  809. m_pLATMDepack->Flush();
  810.     }
  811.     m_bFlushed = TRUE;
  812.     return HXR_OK;
  813. }
  814. void MP4APayloadFormat::FlushPackets(ULONG32 ulCount)
  815. {
  816.     IHXPacket* pDeadPacket;
  817.     CMediaPacket* pDeadMediaPacket;
  818.     while ((ulCount > 0) && (!m_InputPackets.IsEmpty()))
  819.     {
  820. pDeadPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  821. HX_RELEASE(pDeadPacket);
  822. if (ulCount != FLUSH_ALL_PACKETS)
  823. {
  824.     ulCount--;
  825. }
  826.     }
  827.     while ((ulCount > 0) && (!m_OutMediaPacketQueue.IsEmpty()))
  828.     {
  829. pDeadMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
  830. HX_DELETE(pDeadMediaPacket);
  831. if (ulCount != FLUSH_ALL_PACKETS)
  832. {
  833.     ulCount--;
  834. }
  835.     }
  836. }
  837. ULONG32 MP4APayloadFormat::GetPacketTime(IHXPacket* pPacket)
  838. {
  839.     ULONG32 ulTime;
  840.     HX_ASSERT(pPacket);
  841.     if (m_bUsesRTPPackets)
  842.     {
  843. ulTime = ((IHXRTPPacket*) pPacket)->GetRTPTime();
  844.     }
  845.     else
  846.     {
  847. ulTime = pPacket->GetTime();
  848.     }
  849.     ulTime = m_TSConverter.Convert(ulTime);
  850.     return ulTime;
  851. }