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

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. #include "hxtypes.h"
  36. #include "hxcom.h"
  37. #include "amrpyld.h"
  38. #include <string.h>
  39. #include "hxccf.h"
  40. #include "amr_frame_hdr.h"
  41. #include "amr_mime_info.h"
  42. #include "debug.h"
  43. #define D_AMR 0
  44. // fmtp fields
  45. static const char z_octetAlign[]     = "FMTPoctet-align";
  46. static const char z_modeSet[]        = "FMTPmode-set";
  47. static const char z_changePeriod[]   = "FMTPmode-change-period";
  48. static const char z_changeNeighbor[] = "FMTPmode-change-neighbor";
  49. static const char z_maxPTime[]       = "FMTPmaxptime";
  50. static const char z_crc[]            = "FMTPcrc";
  51. static const char z_robustSort[]     = "FMTProbust-sorting";
  52. static const char z_interleaving[]   = "FMTPinterleaving";
  53. static const char z_ptime[]          = "FMTPptime";
  54. static const char z_channels[]       = "FMTPchannels";
  55. CAMRPayloadFormat::CAMRPayloadFormat() :
  56.     m_lRefCount(0),
  57.     m_pCCF(0),
  58.     m_ulSampleRate(0),
  59.     m_ulAUDuration(0)
  60. {
  61. #ifdef DEBUG
  62.     debug_level() |= D_AMR;
  63. #endif
  64. }
  65. CAMRPayloadFormat::~CAMRPayloadFormat()
  66. {
  67.     DPRINTF(D_AMR,("CAMRPayloadFormat::~CAMRPayloadFormat()n"));
  68.     FlushOutput();
  69.     HX_RELEASE(m_pCCF);
  70. }
  71. HX_RESULT CAMRPayloadFormat::Build(REF(IMP4APayloadFormat*) pFmt)
  72. {
  73.     pFmt = new CAMRPayloadFormat();
  74.     HX_RESULT res = HXR_OUTOFMEMORY;
  75.     if (pFmt)
  76.     {
  77. pFmt->AddRef();
  78. res = HXR_OK;
  79.     }
  80.     return res;
  81. }
  82. // *** IUnknown methods ***
  83. STDMETHODIMP CAMRPayloadFormat::QueryInterface (THIS_
  84.        REFIID riid,
  85.        void** ppvObj)
  86. {
  87.     QInterfaceList qiList[] =
  88.     {
  89. { GET_IIDHANDLE(IID_IUnknown), this },
  90. { GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
  91.     };
  92.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  93. }
  94. STDMETHODIMP_(ULONG32) CAMRPayloadFormat::AddRef()
  95. {
  96.     return InterlockedIncrement(&m_lRefCount);
  97. }
  98. STDMETHODIMP_(ULONG32) CAMRPayloadFormat::Release()
  99. {
  100.     if (InterlockedDecrement(&m_lRefCount) > 0)
  101.     {
  102.         return m_lRefCount;
  103.     }
  104.     delete this;
  105.     return 0;
  106. }
  107. /*
  108.  * IHXPayloadFormatObject methods
  109.  */
  110. STDMETHODIMP CAMRPayloadFormat::Init(IUnknown* pContext, BOOL bPacketize)
  111. {
  112.     DPRINTF(D_AMR,("CAMRPayloadFormat::Init()n"));
  113.     HX_RESULT res = HXR_UNEXPECTED;
  114.     if (!bPacketize)
  115.     {
  116. res = pContext->QueryInterface(IID_IHXCommonClassFactory,
  117.        (void**)&m_pCCF);
  118. res = HXR_OK;
  119.     }
  120.     return res;
  121. }
  122. STDMETHODIMP CAMRPayloadFormat::Close()
  123. {
  124.     DPRINTF(D_AMR,("CAMRPayloadFormat::Close()n"));
  125.     return HXR_NOTIMPL;
  126. }
  127. STDMETHODIMP CAMRPayloadFormat::Reset()
  128. {
  129.     DPRINTF(D_AMR,("CAMRPayloadFormat::Reset()n"));
  130.     m_depack.Reset();
  131.     FlushOutput();
  132.     return HXR_OK;
  133. }
  134. STDMETHODIMP CAMRPayloadFormat::SetStreamHeader(IHXValues* pHeader)
  135. {
  136.     DPRINTF(D_AMR,("CAMRPayloadFormat::SetStreamHeader()n"));
  137.     HX_RESULT res = HXR_UNEXPECTED;
  138.     IHXBuffer* pMimeType = 0;
  139.     IHXBuffer* pPayloadParams = 0;
  140.     if (SUCCEEDED(pHeader->GetPropertyCString("MimeType", pMimeType)) &&
  141. SUCCEEDED(pHeader->GetPropertyCString("PayloadParameters",
  142.       pPayloadParams)) &&
  143. (CAMRMimeInfo::IsNarrowBandAMR((const char*)pMimeType->GetBuffer()) ||
  144.  CAMRMimeInfo::IsWideBandAMR((const char*)pMimeType->GetBuffer())))
  145.     {
  146. AMRFlavor flavor = NarrowBand;
  147. ULONG32 ulOctetAlign = 0;
  148. ULONG32 ulModeSet = 0;
  149. ULONG32 ulChangePeriod = 0;
  150. ULONG32 ulChangeNeighbor = 0;
  151. ULONG32 ulMaxPtime = 0;
  152. ULONG32 ulHasCRC = 0;
  153. ULONG32 ulRobustSort = 0;
  154. ULONG32 ulMaxInterleave = 0;
  155. ULONG32 ulPtime = 0;
  156. ULONG32 ulChannels = 0;
  157. if (CAMRMimeInfo::IsNarrowBandAMR((const char*)pMimeType->GetBuffer()))
  158. {
  159.     flavor = NarrowBand;
  160. }
  161. else if (CAMRMimeInfo::IsWideBandAMR((const char*)pMimeType->GetBuffer()))
  162. {
  163.     flavor = WideBand;
  164. }
  165. pHeader->GetPropertyULONG32(z_octetAlign, ulOctetAlign);
  166. pHeader->GetPropertyULONG32(z_modeSet, ulModeSet);
  167. pHeader->GetPropertyULONG32(z_changePeriod, ulChangePeriod);
  168. pHeader->GetPropertyULONG32(z_changeNeighbor, ulChangeNeighbor);
  169. pHeader->GetPropertyULONG32(z_maxPTime, ulMaxPtime);
  170. pHeader->GetPropertyULONG32(z_crc, ulHasCRC);
  171. pHeader->GetPropertyULONG32(z_robustSort, ulRobustSort);
  172. pHeader->GetPropertyULONG32(z_interleaving, ulMaxInterleave);
  173. pHeader->GetPropertyULONG32(z_ptime, ulPtime);
  174. pHeader->GetPropertyULONG32(z_channels, ulChannels);
  175. if (m_depack.Init(flavor,
  176.   (ulOctetAlign == 1),
  177.   ulModeSet,
  178.   ulChangePeriod,
  179.   (ulChangeNeighbor = 1),
  180.   ulMaxPtime,
  181.   (ulHasCRC == 1),
  182.   (ulRobustSort == 1),
  183.   ulMaxInterleave,
  184.   ulPtime,
  185.   ulChannels,
  186.   &CAMRPayloadFormat::static_OnFrame,
  187.   this))
  188.     res = HXR_OK;
  189.     }
  190.     HX_RELEASE(pMimeType);
  191.     HX_RELEASE(pPayloadParams);
  192.     return res;
  193. }
  194. STDMETHODIMP CAMRPayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
  195. {
  196.     DPRINTF(D_AMR,("CAMRPayloadFormat::GetStreamHeader()n"));
  197.     return HXR_NOTIMPL;
  198. }
  199. STDMETHODIMP CAMRPayloadFormat::SetPacket(IHXPacket* pPacket)
  200. {
  201.     DPRINTF(D_AMR,("CAMRPayloadFormat::SetPacket()n"));
  202.     HX_RESULT res = HXR_UNEXPECTED;
  203.     if (pPacket->IsLost())
  204.     {
  205. if (m_depack.OnLoss(1))
  206.     res = HXR_OK;
  207.     }
  208.     else
  209.     {
  210. IHXBuffer* pBuf = pPacket->GetBuffer();
  211. DPRINTF(D_AMR,("CAMRPayloadFormat::SetPacket(%lu, %lu, %u)n",
  212.        pPacket->GetTime(),
  213.        pBuf->GetSize(),
  214.        pPacket->GetASMRuleNumber()));
  215. ULONG32 ulTime =  m_TSConverter.Convert(pPacket->GetTime());
  216. if (m_depack.OnPacket(ulTime,
  217.       pBuf->GetBuffer(),
  218.       pBuf->GetSize(),
  219.       (pPacket->GetASMRuleNumber() == 1)))
  220.     res = HXR_OK;
  221. HX_RELEASE(pBuf);
  222.     }
  223.     return res;
  224. }
  225. STDMETHODIMP CAMRPayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
  226. {
  227.     DPRINTF(D_AMR,("CAMRPayloadFormat::GetPacket()n"));
  228.     return HXR_NOTIMPL;
  229. }
  230. STDMETHODIMP CAMRPayloadFormat::Flush()
  231. {
  232.     DPRINTF(D_AMR,("CAMRPayloadFormat::Flush()n"));
  233.     m_depack.Flush();
  234.     return HXR_OK;
  235. }
  236. /*
  237.  * IMP4APayloadFormat methods
  238.  */
  239. ULONG32 CAMRPayloadFormat::GetBitstreamHeaderSize(void)
  240. {
  241.     DPRINTF(D_AMR,("CAMRPayloadFormat::GetBitstreamHeaderSize()n"));
  242.     return 1;
  243. }
  244. const UINT8* CAMRPayloadFormat::GetBitstreamHeader(void)
  245. {
  246.     DPRINTF(D_AMR,("CAMRPayloadFormat::GetBitstreamHeader()n"));
  247.     return m_bitstreamHdr;
  248. }
  249. HX_RESULT CAMRPayloadFormat::CreateMediaPacket(CMediaPacket* &pOutMediaPacket)
  250. {
  251.     DPRINTF(D_AMR,("CAMRPayloadFormat::CreateMediaPacket()n"));
  252.     HX_RESULT res = HXR_NO_DATA;
  253.     if (!m_outputQueue.IsEmpty())
  254.     {
  255. pOutMediaPacket = (CMediaPacket*)m_outputQueue.RemoveHead();
  256. res = HXR_OK;
  257.     }
  258.     return res;
  259. }
  260. HX_RESULT CAMRPayloadFormat::SetSamplingRate(ULONG32 ulSamplesPerSecond)
  261. {
  262.     DPRINTF(D_AMR,("CAMRPayloadFormat::SetSamplingRate(%lu)n",
  263.     ulSamplesPerSecond));
  264.     m_ulSampleRate = ulSamplesPerSecond;
  265.     m_TSConverter.SetBase(1000, m_ulSampleRate);
  266.     m_depack.SetTSSampleRate(m_ulSampleRate);
  267.     return HXR_OK;
  268. }
  269. ULONG32 CAMRPayloadFormat::GetTimeBase(void)
  270. {
  271.     DPRINTF(D_AMR,("CAMRPayloadFormat::GetTimeBase() = %uln",
  272.     m_ulSampleRate));
  273.     return m_ulSampleRate;
  274. }
  275. HX_RESULT CAMRPayloadFormat::SetAUDuration(ULONG32 ulAUDuration)
  276. {
  277.     DPRINTF(D_AMR,("CAMRPayloadFormat::SetAUDuration(%lu)n",
  278.     ulAUDuration));
  279.     m_ulAUDuration = ulAUDuration;
  280.     return HXR_OK;
  281. }
  282. HX_RESULT CAMRPayloadFormat::SetTimeAnchor(ULONG32 ulTimeMs)
  283. {
  284.     DPRINTF(D_AMR,("CAMRPayloadFormat::SetTimeAnchor(%lu)n",
  285.     ulTimeMs));
  286.     m_TSConverter.SetOffset(ulTimeMs, TSCONVRT_INPUT);
  287.     return HXR_OK;
  288. }
  289. void CAMRPayloadFormat::OnFrame(ULONG32 ulTime,
  290. const UINT8* pData, ULONG32 ulSize,
  291. BOOL bPreviousLoss)
  292. {
  293.     DPRINTF(D_AMR,("CAMRPayloadFormat::OnFrame(%lu, %lu, %d)n",
  294.    ulTime,
  295.    ulSize,
  296.    bPreviousLoss));
  297.     IHXBuffer* pBuf = 0;
  298.     if (SUCCEEDED(m_pCCF->CreateInstance(IID_IHXBuffer, (void**)&pBuf)) &&
  299. SUCCEEDED(pBuf->SetSize(ulSize)))
  300.     {
  301. ::memcpy(pBuf->GetBuffer(), pData, ulSize); /* Flawfinder: ignore */
  302. ULONG32 ulFlags = MDPCKT_USES_IHXBUFFER_FLAG;
  303. if (bPreviousLoss)
  304.     ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
  305. CMediaPacket* pMediaPacket = new CMediaPacket(pBuf,
  306.       pBuf->GetBuffer(),
  307.       pBuf->GetSize(),
  308.       pBuf->GetSize(),
  309.       ulTime,
  310.       ulFlags,
  311.       0);
  312. if (pMediaPacket)
  313.     m_outputQueue.AddTail(pMediaPacket);
  314.     }
  315.     HX_RELEASE(pBuf);
  316. }
  317. void CAMRPayloadFormat::static_OnFrame(void* pUserData,
  318.        ULONG32 ulTime,
  319.        const UINT8* pData, ULONG32 ulSize,
  320.        BOOL bPreviousLoss)
  321. {
  322.     CAMRPayloadFormat* pObj = (CAMRPayloadFormat*)pUserData;
  323.     pObj->OnFrame(ulTime, pData, ulSize, bPreviousLoss);
  324. }
  325. void CAMRPayloadFormat::FlushOutput()
  326. {
  327.     while(!m_outputQueue.IsEmpty())
  328.     {
  329. CMediaPacket* pPkt = (CMediaPacket*)m_outputQueue.RemoveHead();
  330. delete pPkt;
  331.     }
  332. }