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

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 _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.     return retVal;
  305. }
  306. HX_RESULT MP4APayloadFormat::SetAssemblerHXHeader(IHXValues* pHeader)
  307. {
  308.     ES_Descriptor ESDesc;
  309.     DecoderConfigDescriptor* pDCDesc = NULL;
  310.     DecoderSpecifcInfo* pDSIDesc = NULL;
  311.     IHXBuffer* pESDescriptor = NULL;
  312.     UINT8* pESDescData;
  313.     ULONG32 ulESDescSize;
  314.     HX_RESULT retVal = HXR_OK;
  315.     HX_VECTOR_DELETE(m_pAudioConfig);
  316.     m_ulAudioConfigSize = 0;
  317.     retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
  318. pESDescriptor);
  319.     if (SUCCEEDED(retVal))
  320.     {
  321. retVal = HXR_INVALID_PARAMETER;
  322. if (pESDescriptor)
  323. {
  324.     retVal = HXR_OK;
  325. }
  326.     }
  327.     if (SUCCEEDED(retVal))
  328.     {
  329. pESDescData = pESDescriptor->GetBuffer();
  330. ulESDescSize = pESDescriptor->GetSize();
  331. retVal = ESDesc.Unpack(pESDescData, ulESDescSize);
  332.     }
  333.     HX_RELEASE(pESDescriptor);
  334.     if (SUCCEEDED(retVal))
  335.     {
  336. retVal = HXR_FAIL;
  337. pDCDesc = ESDesc.m_pDecConfigDescr;
  338. if (pDCDesc)
  339. {
  340.     pDSIDesc = pDCDesc->m_pDecSpecificInfo;
  341.     retVal = HXR_OK;
  342. }
  343.     }
  344.     if (SUCCEEDED(retVal) && pDSIDesc)
  345.     {
  346. m_ulAudioConfigSize = pDSIDesc->m_ulLength;
  347. if (m_ulAudioConfigSize > 0)
  348. {
  349.     m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
  350.     if (m_pAudioConfig == NULL)
  351.     {
  352. m_ulAudioConfigSize = 0;
  353. retVal = HXR_OUTOFMEMORY;
  354.     }
  355. }
  356.     }
  357.     if (SUCCEEDED(retVal))
  358.     {
  359. if (m_ulAudioConfigSize > 0)
  360. {
  361.     memcpy(m_pAudioConfig, pDSIDesc->m_pData, m_ulAudioConfigSize); /* Flawfinder: ignore */
  362. }
  363.     }
  364.     return retVal;
  365. }
  366. HX_RESULT MP4APayloadFormat::SetAssemblerLATMHeader(IHXValues* pHeader)
  367. {
  368.     HX_RESULT retVal = SetAssemblerLATMConfig(pHeader);
  369.     if (SUCCEEDED(retVal))
  370.     {
  371. m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
  372.     m_ulRTPSamplesPerSecond);
  373.     }
  374.     return retVal;
  375. }
  376. HX_RESULT MP4APayloadFormat::SetAssemblerLATMConfig(IHXValues* pFMTParams)
  377. {
  378.     IHXBuffer* pConfigBuffer = NULL;
  379.     ULONG32 ulObject = 0;
  380.     ULONG32 ulProfileID = 0;
  381.     ULONG32 ulBitrate = 0;
  382.     ULONG32 bConfigPresent = TRUE;
  383.     HX_RESULT retVal = HXR_OK;
  384.     HX_ASSERT(pFMTParams);
  385.     // Obtain Required parameters
  386.     retVal = CHXMP4PayloadUtil::GetFMTPConfig(pFMTParams, m_pClassFactory,
  387.       pConfigBuffer);
  388.     // Obtain optional parameters
  389.     if (SUCCEEDED(retVal))
  390.     {
  391. ULONG32 ulVal = 0;
  392. pFMTParams->GetPropertyULONG32("FMTPobject", ulObject);
  393. pFMTParams->GetPropertyULONG32("FMTPprofile-level-id", ulProfileID);
  394. if (SUCCEEDED(pFMTParams->GetPropertyULONG32("FMTPcpresent", ulVal)))
  395. {
  396.     bConfigPresent = (ulVal != 0);
  397. }
  398. pFMTParams->GetPropertyULONG32("FMTPbitrate", ulBitrate);
  399.     }
  400.     // Create and initialize the MP4A-LATM depacketizer
  401.     if (SUCCEEDED(retVal))
  402.     {
  403. HX_DELETE(m_pLATMDepack);
  404. m_pLATMDepack = new MP4LATMDepack;
  405. retVal = HXR_OUTOFMEMORY;
  406. if (m_pLATMDepack)
  407. {
  408.     retVal = HXR_OK;
  409. }
  410.     }
  411.     if (SUCCEEDED(retVal))
  412.     {
  413. UINT8* pStreamMuxConfig = NULL;
  414. ULONG32 ulMuxConfigSize = 0;
  415. const UINT8* pCodecConfig = NULL;
  416. ULONG32 ulConfigSize = 0;
  417. if (pConfigBuffer)
  418. {
  419.     pStreamMuxConfig = pConfigBuffer->GetBuffer();
  420.     ulMuxConfigSize = pConfigBuffer->GetSize();
  421. }
  422. retVal = HXR_FAIL;
  423. if (m_pLATMDepack->Init(ulProfileID,
  424. ulObject,
  425. ulBitrate,
  426. bConfigPresent,
  427. pStreamMuxConfig,
  428. ulMuxConfigSize,
  429. OnFrameCallback,
  430. this))
  431. {
  432.     retVal = HXR_OK;
  433. }
  434. if (SUCCEEDED(retVal))
  435. {
  436.     if (!m_pLATMDepack->GetCodecConfig(pCodecConfig,
  437.        ulConfigSize))
  438.     {
  439. pCodecConfig = NULL;
  440. ulConfigSize = 0;
  441.     }
  442. }
  443. if (SUCCEEDED(retVal))
  444. {
  445.     m_ulAudioConfigSize = ulConfigSize;
  446.     if (m_ulAudioConfigSize > 0)
  447.     {
  448. m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
  449. if (m_pAudioConfig == NULL)
  450. {
  451.     m_ulAudioConfigSize = 0;
  452.     retVal = HXR_OUTOFMEMORY;
  453. }
  454.     }
  455. }
  456. if (SUCCEEDED(retVal))
  457. {
  458.     if (m_ulAudioConfigSize > 0)
  459.     {
  460. memcpy(m_pAudioConfig, pCodecConfig, m_ulAudioConfigSize); /* Flawfinder: ignore */
  461.     }
  462. }
  463.     }
  464.     HX_RELEASE(pConfigBuffer);
  465.     return retVal;
  466. }
  467. STDMETHODIMP
  468. MP4APayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
  469. {
  470.     HX_RESULT retVal = HXR_FAIL;
  471.     if (m_pStreamHeader)
  472.     {
  473. retVal = HXR_OK;
  474. pHeader = m_pStreamHeader;
  475. pHeader->AddRef();
  476.     }
  477.     return retVal;
  478. }
  479. STDMETHODIMP
  480. MP4APayloadFormat::SetPacket(IHXPacket* pPacket)
  481. {
  482.     HX_RESULT retVal = HXR_OK;
  483.     HX_ASSERT(pPacket);
  484.     if (!m_bRTPPacketTested)
  485.     {
  486. IHXRTPPacket* pRTPPacket = NULL;
  487. m_bUsesRTPPackets = (pPacket->QueryInterface(
  488. IID_IHXRTPPacket,
  489. (void**) &pRTPPacket)
  490.     == HXR_OK);
  491. m_bRTPPacketTested = TRUE;
  492. HX_RELEASE(pRTPPacket);
  493. if (m_bUsesRTPPackets)
  494. {
  495.     if (m_ulRTPSamplesPerSecond == 0)
  496.     {
  497. m_ulRTPSamplesPerSecond = m_ulSamplesPerSecond;
  498.     }
  499. }
  500. else
  501. {
  502.     m_ulRTPSamplesPerSecond = 1000; // RDT time stamp
  503. }
  504. m_TSConverter.SetBase(m_ulRTPSamplesPerSecond,
  505.       m_ulSamplesPerSecond);
  506.     }
  507.     // Add this packet to our list of input packets
  508.     switch (m_PayloadID)
  509.     {
  510.     case PYID_X_HX_AAC_GENERIC:
  511.     case PYID_X_HX_MP4_RAWAU:
  512. pPacket->AddRef();
  513. m_InputPackets.AddTail(pPacket);
  514. break;
  515.     case PYID_MP4A_LATM:
  516. retVal = HXR_FAIL;
  517. if (m_pLATMDepack)
  518. {
  519.     if (pPacket->IsLost())
  520.     {
  521. if (m_pLATMDepack->OnLoss(1))
  522. {
  523.     retVal = HXR_OK;
  524. }
  525.     }
  526.     else
  527.     {
  528. IHXBuffer* pBuffer = pPacket->GetBuffer();
  529. if (pBuffer &&
  530.     m_pLATMDepack->OnPacket(GetPacketTime(pPacket),
  531.     pBuffer->GetBuffer(),
  532.     pBuffer->GetSize(),
  533.     (pPacket->GetASMRuleNumber() == 1)))
  534. {
  535.     retVal = HXR_OK;
  536.     pBuffer->Release();
  537. }
  538.     }
  539. }
  540. break;
  541.     default:
  542. retVal = HXR_NOTIMPL;
  543. break;
  544.     }
  545.     return retVal;
  546. }
  547. STDMETHODIMP
  548. MP4APayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
  549. {
  550.     HX_RESULT retVal = HXR_OK;
  551.     if (m_bPacketize)
  552.     {
  553. retVal = GetPacketizerPacket(pOutPacket);
  554.     }
  555.     else
  556.     {
  557. retVal = GetAssemblerPacket(pOutPacket);
  558.     }
  559.     return retVal;
  560. }
  561. HX_RESULT MP4APayloadFormat::GetPacketizerPacket(IHXPacket* &pOutPacket)
  562. {
  563.     HX_RESULT retVal = HXR_INCOMPLETE;
  564.     if (!m_InputPackets.IsEmpty())
  565.     {
  566. pOutPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  567. retVal = HXR_OK;
  568.     }
  569.     else if (m_bFlushed)
  570.     {
  571. retVal = HXR_STREAM_DONE;
  572.     }
  573.     return retVal;
  574. }
  575. HX_RESULT MP4APayloadFormat::GetAssemblerPacket(IHXPacket* &pOutPacket)
  576. {
  577.     HX_RESULT retVal = HXR_NOTIMPL;
  578.     return retVal;
  579. }
  580. HX_RESULT MP4APayloadFormat::SetSamplingRate(ULONG32 ulSamplesPerSecond)
  581. {
  582.     HX_RESULT retVal = HXR_UNEXPECTED;
  583.     if (!m_bRTPPacketTested)
  584.     {
  585. m_ulSamplesPerSecond = ulSamplesPerSecond;
  586. retVal = HXR_OK;
  587.     }
  588.     return HXR_OK;
  589. }
  590. ULONG32 MP4APayloadFormat::GetTimeBase(void)
  591. {
  592.     return m_ulSamplesPerSecond;
  593. }
  594. HX_RESULT MP4APayloadFormat::SetAUDuration(ULONG32 ulAUDuration)
  595. {
  596.     HX_RESULT retVal = HXR_UNEXPECTED;
  597.     if (!m_bRTPPacketTested)
  598.     {
  599. switch (m_PayloadID)
  600. {
  601. case PYID_MP4A_LATM:
  602.     retVal = HXR_FAIL;
  603.     
  604.     if (m_pLATMDepack &&
  605. m_pLATMDepack->SetFrameDuration(ulAUDuration))
  606.     {
  607. retVal = HXR_OK;
  608.     }
  609.     break;
  610.     
  611. default:
  612.     retVal = HXR_NOTIMPL;
  613.     break;
  614. }
  615.     }
  616.     return retVal;
  617. }
  618. HX_RESULT MP4APayloadFormat::SetTimeAnchor(ULONG32 ulTimeMs)
  619. {
  620.     CTSConverter tempConverter;
  621.     ULONG32 ulSamplesAnchor;
  622.     ULONG32 ulRTPSamplesAnchor;
  623.     tempConverter.SetBase(1000, m_ulSamplesPerSecond);
  624.     ulSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);
  625.     tempConverter.SetBase(1000, m_ulRTPSamplesPerSecond);
  626.     ulRTPSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);
  627.     m_TSConverter.SetAnchor(ulRTPSamplesAnchor, ulSamplesAnchor);
  628.     return HXR_OK;
  629. }
  630. HX_RESULT MP4APayloadFormat::CreateMediaPacket(CMediaPacket* &pOutMediaPacket)
  631. {
  632.     HX_RESULT retVal = HXR_OK;
  633.     switch (m_PayloadID)
  634.     {
  635.     case PYID_X_HX_AAC_GENERIC:
  636.     case PYID_X_HX_MP4_RAWAU:
  637. retVal = CreateRawAUMediaPacket(pOutMediaPacket);
  638. break;
  639.     case PYID_MP4A_LATM:
  640. if (m_OutMediaPacketQueue.IsEmpty())
  641. {
  642.     if (m_bFlushed)
  643.     {
  644. // We have used up all available input
  645. retVal = HXR_STREAM_DONE;
  646.     }
  647.     else
  648.     {
  649. // We don't have enough input
  650. // data to produce a packet
  651. retVal = HXR_INCOMPLETE;
  652.     }
  653. }
  654. else
  655. {
  656.     pOutMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
  657. }
  658. break;
  659.     default:
  660. retVal = HXR_NOTIMPL;
  661. break;
  662.     }
  663.     return retVal;
  664. }
  665. HX_RESULT MP4APayloadFormat::OnFrame(ULONG32 ulTime,
  666.      const UINT8* pData,
  667.      ULONG32 ulSize,
  668.      BOOL bPreviousLoss)
  669. {
  670.     ULONG32 ulFlags = 0;
  671.     CMediaPacket* pMediaPacket = NULL;
  672.     HX_RESULT retVal = HXR_OK;
  673.     if (pData && (ulSize != 0))
  674.     {
  675. ULONG32 ulNewSize;
  676. if (bPreviousLoss)
  677. {
  678.     ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
  679. }
  680. #ifdef _OVERALLOC_CODEC_DATA
  681. ulNewSize = ulSize + _OVERALLOC_CODEC_DATA;
  682. #else // _OVERALLOC_CODEC_DATA
  683. ulNewSize = ulSize;
  684. #endif // _OVERALLOC_CODEC_DATA
  685. UINT8* pNewData = new UINT8 [ulNewSize];
  686. if (pData)
  687. {
  688.     memcpy(pNewData, pData, ulSize); /* Flawfinder: ignore */
  689.     pMediaPacket = new CMediaPacket(pNewData,
  690.     pNewData,
  691.     ulNewSize,
  692.     ulSize,
  693.     ulTime,
  694.     ulFlags,
  695.     NULL);
  696. }
  697.     }
  698.     if (pMediaPacket)
  699.     {
  700. m_OutMediaPacketQueue.AddTail(pMediaPacket);
  701.     }
  702.     return retVal;
  703. }
  704. void MP4APayloadFormat::OnFrameCallback(void* pUserData,
  705. ULONG32 ulTime,
  706. const UINT8* pData,
  707. ULONG32 ulSize,
  708. BOOL bPreviousLoss)
  709. {
  710.     MP4APayloadFormat* pObject = (MP4APayloadFormat*) pUserData;
  711.     pObject->OnFrame(ulTime, pData, ulSize, bPreviousLoss);
  712. }
  713. HX_RESULT MP4APayloadFormat::CreateRawAUMediaPacket(CMediaPacket* &pOutMediaPacket)
  714. {
  715.     CMediaPacket* pMediaPacket;
  716.     IHXPacket* pPacket = NULL;
  717.     HX_RESULT retVal = HXR_OK;
  718.     if (m_InputPackets.IsEmpty())
  719.     {
  720. if (m_bFlushed)
  721. {
  722.     // We have used up all available input
  723.     retVal = HXR_STREAM_DONE;
  724. }
  725. else
  726. {
  727.     // We don't have enough input
  728.     // data to produce a packet
  729.     retVal = HXR_INCOMPLETE;
  730. }
  731.     }
  732.     else
  733.     {
  734. ULONG32 ulFlags = MDPCKT_USES_IHXBUFFER_FLAG;
  735. IHXBuffer* pBuffer = NULL;
  736. pPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  737. if (!pPacket->IsLost())
  738. {
  739.     pBuffer = pPacket->GetBuffer();
  740.     if (pBuffer)
  741.     {
  742. if (m_bPriorLoss)
  743. {
  744.     ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
  745.     m_bPriorLoss = FALSE;
  746. }
  747. pMediaPacket = BuildMediaPacket(pBuffer,
  748. GetPacketTime(pPacket),
  749. ulFlags);
  750. retVal = HXR_OUTOFMEMORY;
  751. if (pMediaPacket)
  752. {
  753.     pOutMediaPacket = pMediaPacket;
  754.     retVal = HXR_OK;
  755. }
  756. pBuffer->Release();
  757.     }
  758.     else
  759.     {
  760. m_bPriorLoss = TRUE;
  761. retVal = HXR_INCOMPLETE;
  762.     }
  763.     pPacket->Release();
  764. }
  765. else
  766. {
  767.     m_bPriorLoss = TRUE;
  768.     retVal = HXR_INCOMPLETE;
  769. }
  770.     }
  771.     return retVal;
  772. }
  773. CMediaPacket* MP4APayloadFormat::BuildMediaPacket(IHXBuffer* pBuffer,
  774.   ULONG32 ulTime,
  775.   ULONG32 ulFlags)
  776. {
  777.     CMediaPacket* pMediaPacket = NULL;
  778. #ifdef _OVERALLOC_CODEC_DATA
  779.     UINT8* pData = new UINT8 [pBuffer->GetSize() + _OVERALLOC_CODEC_DATA];
  780.     if (pData)
  781.     {
  782. memcpy(pData, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  783. ulFlags &= (~MDPCKT_USES_IHXBUFFER_FLAG);
  784. pMediaPacket = new CMediaPacket(pData,
  785. pData,
  786. pBuffer->GetSize() + 3,
  787. pBuffer->GetSize(),
  788. ulTime,
  789. ulFlags,
  790. NULL);
  791.     }
  792. #else // _OVERALLOC_CODEC_DATA
  793.     pMediaPacket = new CMediaPacket(pBuffer,
  794.     pBuffer->GetBuffer(),
  795.     pBuffer->GetSize(),
  796.     pBuffer->GetSize(),
  797.     ulTime,
  798.     ulFlags,
  799.     NULL);
  800. #endif // _OVERALLOC_CODEC_DATA
  801.     return pMediaPacket;
  802. }
  803. STDMETHODIMP
  804. MP4APayloadFormat::Flush()
  805. {
  806.     if (m_pLATMDepack)
  807.     {
  808. m_pLATMDepack->Flush();
  809.     }
  810.     m_bFlushed = TRUE;
  811.     return HXR_OK;
  812. }
  813. void MP4APayloadFormat::FlushPackets(ULONG32 ulCount)
  814. {
  815.     IHXPacket* pDeadPacket;
  816.     CMediaPacket* pDeadMediaPacket;
  817.     while ((ulCount > 0) && (!m_InputPackets.IsEmpty()))
  818.     {
  819. pDeadPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  820. HX_RELEASE(pDeadPacket);
  821. if (ulCount != FLUSH_ALL_PACKETS)
  822. {
  823.     ulCount--;
  824. }
  825.     }
  826.     while ((ulCount > 0) && (!m_OutMediaPacketQueue.IsEmpty()))
  827.     {
  828. pDeadMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
  829. HX_DELETE(pDeadMediaPacket);
  830. if (ulCount != FLUSH_ALL_PACKETS)
  831. {
  832.     ulCount--;
  833. }
  834.     }
  835. }
  836. ULONG32 MP4APayloadFormat::GetPacketTime(IHXPacket* pPacket)
  837. {
  838.     ULONG32 ulTime;
  839.     HX_ASSERT(pPacket);
  840.     if (m_bUsesRTPPackets)
  841.     {
  842. ulTime = ((IHXRTPPacket*) pPacket)->GetRTPTime();
  843.     }
  844.     else
  845.     {
  846. ulTime = pPacket->GetTime();
  847.     }
  848.     ulTime = m_TSConverter.Convert(ulTime);
  849.     return ulTime;
  850. }