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

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 "hxcom.h"
  36. #include "hxtypes.h"
  37. #include "hxresult.h"
  38. #include "hlxclib/string.h"
  39. /* heap, memory debugging */
  40. #include "hxheap.h"
  41. #ifdef _DEBUG
  42. #undef HX_THIS_FILE
  43. static const char HX_THIS_FILE[] = __FILE__;
  44. #endif
  45. #include "dunitprvt.h"
  46. #include "gcd.h"
  47. #include "racodec.h"
  48. #include "hxacodec.h"
  49. #include "cra2ihxaenc.h"
  50. #ifdef _M_IX86 /* Asm versions */
  51. __inline short
  52. RoundFtoS(float f) {
  53. long l;
  54. __asm fld f
  55. __asm fistp l
  56. if (l < -32768)
  57. l = -32768;
  58. else if (l > 32767)
  59. l = 32767;
  60. return (short)l;
  61. }
  62. #else /* C versions */
  63. __inline short
  64. RoundFtoS(float f) {
  65. long l = (long)(f < 0.0f ? f - 0.5f : f + 0.5f);
  66. if (l < -32768)
  67. l = -32768;
  68. else if (l > 32767)
  69. l = 32767;
  70. return (short)l;
  71. }
  72. #endif /* _M_IX86 */
  73. /****************************************************************************
  74.  *  IUnknown methods
  75.  */
  76. /////////////////////////////////////////////////////////////////////////
  77. //  Method:
  78. // IUnknown::QueryInterface
  79. //
  80. STDMETHODIMP HXAudioEncoder::QueryInterface(REFIID riid, void** ppvObj)
  81. {
  82.     if (IsEqualIID(riid, IID_IHXAudioEncoder))
  83.     {
  84.         AddRef();
  85.         *ppvObj = (IHXAudioEncoder*) this;
  86.         return HXR_OK;
  87.     }
  88.     else if (IsEqualIID(riid, IID_IHXAudioEncoderConfigurator))
  89.     {
  90.         AddRef();
  91.         *ppvObj = (IHXAudioEncoderConfigurator*)this;
  92.         return HXR_OK;
  93.     }
  94.     else if (IsEqualIID(riid, IID_IHXCodecOldStyleAuthenticate))
  95.     {
  96. // runtime check if password function is present
  97. if (RAHaveSetPassword())
  98. {
  99.     AddRef();
  100.     *ppvObj = (IHXCodecOldStyleAuthenticate*)this;
  101.     return HXR_OK;
  102. }
  103.     }
  104.     else if (IsEqualIID(riid, IID_IUnknown))
  105.     {
  106.         AddRef();
  107.         *ppvObj = this;
  108.         return HXR_OK;
  109.     }
  110.     
  111.     *ppvObj = NULL;
  112.     
  113.     return HXR_NOINTERFACE;
  114. }
  115. /////////////////////////////////////////////////////////////////////////
  116. //  Method:
  117. // IUnknown::AddRef
  118. //
  119. STDMETHODIMP_(ULONG32) HXAudioEncoder::AddRef()
  120. {
  121.     return InterlockedIncrement(&m_lRefCount);
  122. }
  123. /////////////////////////////////////////////////////////////////////////
  124. //  Method:
  125. // IUnknown::Release
  126. //
  127. STDMETHODIMP_(ULONG32) HXAudioEncoder::Release()
  128. {
  129.     if (InterlockedDecrement(&m_lRefCount) > 0)
  130.     {
  131.         return m_lRefCount;
  132.     }
  133.     delete this;
  134.     return 0;
  135. }
  136. HXAudioEncoder::HXAudioEncoder()
  137. : m_lRefCount(0)
  138. , mpCodecRef(0)
  139. , mnSamplesIn(0)
  140. , mnBytesOut(0)
  141. , mCurrentFlavorIndex(-1)
  142. , mpDataIn(0)
  143. , mpDataOut(0)
  144. , mDataOffset(0)
  145. , mpPropTable(0)
  146. {
  147. }
  148. HXAudioEncoder::~HXAudioEncoder()
  149. {
  150.     if (mpCodecRef)
  151.     {
  152. ENTRYPOINT(RACloseCodec)(mpCodecRef) ;
  153.     }
  154.     if (mpPropTable)
  155. delete[] mpPropTable ;
  156. }
  157. HX_RESULT HXAudioEncoder::Init()
  158. {
  159.     HX_RESULT res ;
  160.     res = ENTRYPOINT(RAOpenCodec2)(&mpCodecRef, 0) ;
  161.     if (SUCCEEDED(res)) res = retrieveProperties() ;
  162.     return res ;
  163. }
  164. HX_RESULT HXEXPORT ENTRYPOINT(RACreateEncoderInstance) (const CLSID &clsid, IUnknown** ppUnknown)
  165. {
  166.     HX_RESULT res = HXR_OUTOFMEMORY ;
  167.     HXAudioEncoder* pObj = new HXAudioEncoder() ;
  168.     if (pObj)
  169. res = pObj->Init() ;
  170.     if (SUCCEEDED(res))
  171.         res = pObj->QueryInterface(clsid, (void**)ppUnknown) ;
  172.     return res ;
  173. }
  174. STDMETHODIMP HXAudioEncoder::SetOption(OPTION_LONG option, INT32 arg)
  175. {
  176.     return HXR_NOTIMPL ;
  177. }
  178. STDMETHODIMP HXAudioEncoder::OpenEncoder()
  179. {
  180.     HX_RESULT res ;
  181.     RAENCODER_INIT_PARAMS initParams ;
  182.     HX_AUDIO_FORMAT *p ;
  183.     unsigned short pSize ;
  184.     /* stupid. Some encoders (notably tokyo) check for consistency among initParams and its
  185.        internal parameters, failing if inconsistent. This is why we have to fill this structure
  186.        out */
  187.     p = (HX_AUDIO_FORMAT*)ENTRYPOINT(RAGetFlavorProperty)(mpCodecRef, mCurrentFlavorIndex, ::FLV_PROP_INPUT_AUDIO_FORMAT, &pSize) ;
  188.     if (p && pSize == sizeof(*p))
  189.     {
  190.         initParams.sampleRate = p->SamplesPerSec ;
  191. initParams.bitsPerSample = p->BitsPerSample ;
  192. initParams.channels = p->Channels ;
  193. if (p->BitsPerSample != 16)
  194.     return HXR_NOTIMPL ;
  195.     }
  196.     res = ENTRYPOINT(RAInitEncoder)(mpCodecRef, &initParams) ;
  197.     if (SUCCEEDED(res))
  198.     {
  199. mnSamplesIn = initParams.numSamplesIn ;
  200. mnBytesOut  = initParams.numBytesOut ;
  201. mDataOffset = mpPropTable[mCurrentFlavorIndex].bytesPerEncode ;
  202. mpDataIn  = new short[mnSamplesIn] ;
  203. mpDataOut = new unsigned char[mnBytesOut] ;
  204.     }
  205.     return res ;
  206. }
  207. STDMETHODIMP_(void) HXAudioEncoder::CloseEncoder()
  208. {
  209.     if (mpCodecRef) ENTRYPOINT(RAFreeEncoder)(mpCodecRef) ;
  210.     if (mpDataIn)  delete[] mpDataIn ;
  211.     if (mpDataOut) delete[] mpDataOut ;
  212. }
  213. STDMETHODIMP
  214. HXAudioEncoder::EncodeData(void *pvDataIn, UINT32 nSamplesIn,
  215. UINT32& nSamplesConsumed,
  216. IQueryDecoderUnit* dataOut[], UINT32& nDecoderUnits,
  217. INT32 eof)
  218. {
  219.     float *pfDataIn = (float*)pvDataIn ;
  220.     UINT32 maxDecoderUnits = nDecoderUnits ;
  221.     UINT32 samplesLeft = nSamplesIn ;
  222.     nDecoderUnits = 0 ;
  223.     nSamplesConsumed = 0 ;
  224.     while (1)
  225.     {
  226. if (samplesLeft > (eof ? 0 : mnSamplesIn-1) &&
  227.     mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode) // can produce output
  228. {
  229.     unsigned short *input ;
  230.     if (samplesLeft >= mnSamplesIn)
  231. input = (unsigned short *)pvDataIn + nSamplesConsumed ;
  232.     else
  233.     {
  234. // apparently, eof is on. Copy remaining samples into temp buffer and fill with zeros.
  235. input = new unsigned short[mnSamplesIn] ;
  236. memcpy(input, (unsigned short*)pvDataIn + nSamplesConsumed, samplesLeft * sizeof(signed short)) ; /* Flawfinder: ignore */
  237. memset(input + samplesLeft, 0, (mnSamplesIn - samplesLeft) * sizeof(short)) ;
  238.     }
  239.     ENTRYPOINT(RAEncode)(mpCodecRef, input, mpDataOut) ;
  240.     mDataOffset = 0 ;
  241.     // delete the temp buffer if this was the last time around.
  242.     if (samplesLeft < mnSamplesIn)
  243. delete[] input ;
  244.     nSamplesConsumed += mnSamplesIn ;
  245.     if (nSamplesConsumed > nSamplesIn)
  246. nSamplesConsumed = nSamplesIn ;
  247. }
  248. samplesLeft = nSamplesIn - nSamplesConsumed ;
  249. if (mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode)
  250. {
  251.     // did not produce any samples, and none are pending
  252.     break ;
  253. }
  254. // pack output into data units
  255. while (nDecoderUnits < maxDecoderUnits && mDataOffset < mpPropTable[mCurrentFlavorIndex].bytesPerEncode)
  256. {
  257.     /* we have data pending from a previous Encode() call
  258.        that are not yet shipped in decoder units. */
  259.             /* since we always allocate these, we know they are really PrepareDecoderUnits,
  260.        and the cast is harmless */
  261.             IPrepareDecoderUnit* du = (IPrepareDecoderUnit*)dataOut[nDecoderUnits] ;
  262.             if (du == 0) /* need to instantiate a new unit */
  263.             {
  264.                 HX_RESULT hr = CreateIPrepareDecoderUnit(du) ;
  265.                 if (FAILED(hr))
  266.                     return hr ;
  267.                 dataOut[nDecoderUnits] = du ;
  268.             }
  269.             du->putData((const char*)mpDataOut + mDataOffset, mpPropTable[mCurrentFlavorIndex].bytesPerFrame, mpPropTable[mCurrentFlavorIndex].samplesPerFrame) ;
  270.             du->setBufferFullness(0) ; // we are CBR
  271.     if (eof && samplesLeft <= 0 &&
  272. mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode - mpPropTable[mCurrentFlavorIndex].bytesPerFrame )
  273.     {
  274. // this is the very last decoder unit.
  275. du->setFlags(IQueryDecoderUnit::ENDOFSTREAM) ;
  276.     }
  277.     mDataOffset += mpPropTable[mCurrentFlavorIndex].bytesPerFrame ;
  278.             nDecoderUnits++;
  279.     if (nDecoderUnits == maxDecoderUnits)
  280.     {
  281. return HXR_OK ;
  282.     }
  283. }
  284.     }
  285.     return HXR_OK ;
  286. }
  287. HX_RESULT HXAudioEncoder::CreateIPrepareDecoderUnit(IPrepareDecoderUnit*& ppi)
  288. {
  289.     CDecoderUnit *du = new CDecoderUnit() ;
  290.     return du->QueryInterface(IID_IPrepareDecoderUnit, (void**)&ppi) ;
  291. }
  292. HX_RESULT HXAudioEncoder::SetPassword(const char* password)
  293. {
  294.     if (mpCodecRef && password) ENTRYPOINT(RASetPwd)(mpCodecRef, password) ;
  295.     return HXR_OK ; // we always smile, no matter what
  296. }