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

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. #include "hxtypes.h"
  36. #include "hlxclib/stdio.h"
  37. #include "hxcom.h"              // IUnknown
  38. #include "hxcomm.h"            // IHXCommonClassFactory
  39. #include "ihxpckts.h"           // IHXBuffer, IHXPacket, IHXValues
  40. #include "hxplugn.h"           // IHXPlugin
  41. #include "hxrendr.h"           // IHXRenderer
  42. #include "hxengin.h"           // IHXInterruptSafe
  43. #include "hxcore.h"            // IHXStream
  44. #include "hxausvc.h"           // Audio Services
  45. #include "hxmon.h"             // IHXStatistics
  46. #include "hxupgrd.h"           // IHXUpgradeCollection
  47. #include "hxslist.h"            // CHXSimpleList
  48. #include "carray.h"             // CHXPtrArray
  49. #include "mpadecobj.h"          // MPEG Audio Decoder (selects fixed-pt or floating-pt based on HELIX_CONFIG_FIXEDPOINT)
  50. #include "mp3format.h"          // MP3 formatter
  51. #include "mp3rend.h"            // CRnMp3Ren
  52. #include "pktparse.h"           // CPacketParser
  53. const UINT32 CPacketParser::DEC_BUFFER_SIZE = 4096;
  54. CPacketParser::CPacketParser() :    
  55.     m_pBufHead(NULL),
  56.     m_pDecBuffer(NULL),
  57.     m_ulDecBufBytes(0),
  58.     m_pFmt(NULL),
  59.     m_pRenderer(NULL),
  60.     m_pDecoder(NULL),
  61.     m_pClassFactory(NULL),
  62.     m_pLastPCMBuffer(NULL),
  63.     m_dLastPCMTime(0.0),
  64.     m_nLayer(0),
  65.     m_ulBitRate(0),
  66.     m_ulChannels(0),
  67.     m_nWaveBufSize(0),
  68.     m_dFrameTime(0.0),
  69.     m_dNextPts(0.0),
  70.     m_bTrustPackets(FALSE),
  71.     m_bEndOfPackets(FALSE)
  72. {
  73. }
  74. CPacketParser::~CPacketParser()
  75. {
  76.     HX_VECTOR_DELETE(m_pBufHead);
  77.     HX_DELETE(m_pDecoder);
  78.     HX_RELEASE(m_pRenderer);
  79.     
  80.     HX_RELEASE(m_pLastPCMBuffer);
  81.     HX_RELEASE(m_pClassFactory);
  82. }
  83. HX_RESULT
  84. CPacketParser::Init(CRnMp3Ren* pRenderer, 
  85.                     IHXCommonClassFactory* pClassFactory)
  86. {
  87.     if(!pRenderer || !pClassFactory)
  88.     {
  89.         return HXR_INVALID_PARAMETER;
  90.     }
  91.     pRenderer->AddRef();
  92.     pClassFactory->AddRef();
  93.     
  94.     HX_RELEASE(m_pRenderer);
  95.     HX_RELEASE(m_pClassFactory);
  96.     m_pRenderer = pRenderer;
  97.     m_pClassFactory = pClassFactory;
  98.     if(m_pDecBuffer == NULL)
  99.     {
  100.         m_pBufHead = new BYTE[DEC_BUFFER_SIZE + 31];
  101.         m_pDecBuffer = (UCHAR*)((PTR_INT)m_pBufHead+31 & ~31);
  102.     
  103.         if(m_pDecBuffer == NULL || m_pBufHead == NULL)
  104.             return HXR_OUTOFMEMORY;
  105.     }
  106.     HX_DELETE(m_pFmt);
  107.     m_pFmt = new CMp3Format(NULL);
  108.     m_pFmt->SetTrustPackets(m_bTrustPackets);
  109.     return m_pFmt ? HXR_OK : HXR_OUTOFMEMORY;
  110. }
  111. UINT32
  112. CPacketParser::DecodeAndRender(UCHAR* pDec, UINT32 ulSize, double dTime, 
  113.                                BOOL bPacketLoss)
  114. {
  115.     // Dynamic format change - must reinit
  116.     if (DidSourceChange(pDec, ulSize) && !InitDecoder(pDec, ulSize, TRUE))
  117.     {
  118.         return 0;
  119.     }
  120.     // Create our PCM buffer
  121.     IHXBuffer *pPCMBuffer = NULL;
  122.     m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pPCMBuffer);
  123.     if (!pPCMBuffer)
  124.     {
  125.         return 0;
  126.     }
  127.     HX_RESULT 
  128.     retVal = pPCMBuffer->SetSize(m_nWaveBufSize);
  129.     if (FAILED(retVal) || pPCMBuffer->GetSize() != m_nWaveBufSize)
  130.     {
  131.         pPCMBuffer->Release();
  132.         return 0;
  133.     }
  134.     UINT32 dwPCM = pPCMBuffer->GetSize();
  135.     // Decode the frame
  136.     UINT32 ulDec = bPacketLoss ? (UINT32)-1 : ulSize;
  137.     m_pDecoder->DecodeFrame_v(pDec,(unsigned long*)&ulDec,
  138.                                pPCMBuffer->GetBuffer(), 
  139.                                (unsigned long*)&dwPCM);
  140.     if(bPacketLoss)
  141.     {
  142.         ulDec = ulSize;
  143.     }
  144.     if(ulDec)
  145.     {
  146.         m_pRenderer->Render(pPCMBuffer, dTime);
  147.     }
  148.     // Store the pcm buffer of the last decoded frame
  149.     HX_RELEASE(m_pLastPCMBuffer);
  150.     m_pLastPCMBuffer = pPCMBuffer;
  151.     m_pLastPCMBuffer->AddRef();
  152.     m_dLastPCMTime = dTime;
  153.     pPCMBuffer->Release();
  154.     return ulDec;
  155. }
  156. BOOL 
  157. CPacketParser::DidSourceChange(UCHAR *pHeader, UINT32 ulSize)
  158. {
  159.     unsigned long lPCMSampleRate = 0;
  160.     int nChannels = 0;
  161.     int nBitsPerSample = 0;
  162.     // Get existing header info
  163.     m_pDecoder->GetPCMInfo_v(lPCMSampleRate,
  164.                               nChannels,
  165.                               nBitsPerSample);
  166.     UINT32  ulBitRate = 0;
  167.     UINT32  ulSampRate = 0;
  168.     int     nSrcChannels = 0;
  169.     int     nLayer = 0;
  170.     int     nSamplesPerFrame = 0;
  171.     // Get new header values
  172.     m_pFmt->GetEncodeInfo(pHeader, ulSize,
  173.                           ulBitRate, ulSampRate,
  174.                           nSrcChannels, nLayer, nSamplesPerFrame);
  175.     // Allow layer3 bitrates to change
  176.     if (nChannels != nSrcChannels ||
  177.         lPCMSampleRate != ulSampRate ||
  178.         m_pDecoder->GetSamplesPerFrame_n() != nSamplesPerFrame ||
  179.         (m_ulBitRate != ulBitRate && (nLayer != 3 || m_nLayer != 3)))
  180.         return TRUE;
  181.     else
  182.         return FALSE;
  183. }
  184. BOOL
  185. CPacketParser::InitDecoder(UCHAR *pBuffer, UINT32 ulSize, BOOL bReInit)
  186. {
  187.     if (!m_pDecoder)
  188.     {
  189.         // Create and init the decoder
  190.         m_pDecoder = new CMpaDecObj();
  191.         if (m_pDecoder) m_pDecoder->SetTrustPackets(m_bTrustPackets);
  192.     }
  193.     if (!m_pDecoder->Init_n(pBuffer, ulSize, m_bReformatted))
  194.     {
  195.         delete m_pDecoder;
  196.         m_pDecoder = NULL;
  197.         return FALSE;
  198.     }
  199.     // Create and init the PCM device
  200.     unsigned long lPCMSampRate = 0;
  201.     int     nPCMChannels = 0,
  202.             nBitsPerSample = 0;
  203.     m_pDecoder->GetPCMInfo_v(lPCMSampRate,
  204.                               nPCMChannels,
  205.                               nBitsPerSample);
  206.     m_nWaveBufSize = m_pDecoder->GetSamplesPerFrame_n() *
  207.                      (nBitsPerSample>>3) * nPCMChannels;
  208.     // Get the time per frame
  209.     m_dFrameTime = m_pDecoder->GetSamplesPerFrame_n() * 1000.0 / lPCMSampRate;
  210.     m_ulChannels = nPCMChannels;
  211.     // Init the audio stream
  212.     HXAudioFormat audioFmt;
  213.     audioFmt.uChannels = nPCMChannels;
  214.     audioFmt.uBitsPerSample = nBitsPerSample;
  215.     audioFmt.ulSamplesPerSec = lPCMSampRate;
  216.     audioFmt.uMaxBlockSize = m_nWaveBufSize;
  217.     
  218.     HX_ASSERT(m_pRenderer);
  219.     if(bReInit ? !m_pRenderer->ReInitAudioStream(audioFmt) :
  220.        !m_pRenderer->InitAudioStream(audioFmt))
  221.     {
  222.         return FALSE;      
  223.     }
  224.     
  225.     HX_ASSERT(m_pFmt);
  226.     m_pFmt->Init(pBuffer, ulSize);    
  227.     UINT32 ulSampRate = 0;
  228.     int nChannels = 0;
  229.     int nSamplesPerFrame = 0;
  230.     m_pFmt->GetEncodeInfo(pBuffer, ulSize,
  231.                           m_ulBitRate, ulSampRate,
  232.                           nChannels, m_nLayer, nSamplesPerFrame);
  233.     return TRUE;
  234. }
  235. void
  236. CPacketParser::OverrideFactory(IHXCommonClassFactory* pCommonClassFactory)
  237. {
  238.     HX_RELEASE(m_pClassFactory);
  239.     m_pClassFactory = pCommonClassFactory;
  240.     m_pClassFactory->AddRef();
  241. }