cra2ihxaenc.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxresult.h"
- #include "hlxclib/string.h"
- /* heap, memory debugging */
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #include "dunitprvt.h"
- #include "gcd.h"
- #include "racodec.h"
- #include "hxacodec.h"
- #include "cra2ihxaenc.h"
- #ifdef _M_IX86 /* Asm versions */
- __inline short
- RoundFtoS(float f) {
- long l;
- __asm fld f
- __asm fistp l
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
- return (short)l;
- }
- #else /* C versions */
- __inline short
- RoundFtoS(float f) {
- long l = (long)(f < 0.0f ? f - 0.5f : f + 0.5f);
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
- return (short)l;
- }
- #endif /* _M_IX86 */
- /****************************************************************************
- * IUnknown methods
- */
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::QueryInterface
- //
- STDMETHODIMP HXAudioEncoder::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IHXAudioEncoder))
- {
- AddRef();
- *ppvObj = (IHXAudioEncoder*) this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXAudioEncoderConfigurator))
- {
- AddRef();
- *ppvObj = (IHXAudioEncoderConfigurator*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXCodecOldStyleAuthenticate))
- {
- // runtime check if password function is present
- if (RAHaveSetPassword())
- {
- AddRef();
- *ppvObj = (IHXCodecOldStyleAuthenticate*)this;
- return HXR_OK;
- }
- }
- else if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = this;
- return HXR_OK;
- }
-
- *ppvObj = NULL;
-
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::AddRef
- //
- STDMETHODIMP_(ULONG32) HXAudioEncoder::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::Release
- //
- STDMETHODIMP_(ULONG32) HXAudioEncoder::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- HXAudioEncoder::HXAudioEncoder()
- : m_lRefCount(0)
- , mpCodecRef(0)
- , mnSamplesIn(0)
- , mnBytesOut(0)
- , mCurrentFlavorIndex(-1)
- , mpDataIn(0)
- , mpDataOut(0)
- , mDataOffset(0)
- , mpPropTable(0)
- {
- }
- HXAudioEncoder::~HXAudioEncoder()
- {
- if (mpCodecRef)
- {
- ENTRYPOINT(RACloseCodec)(mpCodecRef) ;
- }
- if (mpPropTable)
- delete[] mpPropTable ;
- }
- HX_RESULT HXAudioEncoder::Init()
- {
- HX_RESULT res ;
- res = ENTRYPOINT(RAOpenCodec2)(&mpCodecRef, 0) ;
- if (SUCCEEDED(res)) res = retrieveProperties() ;
- return res ;
- }
- HX_RESULT HXEXPORT ENTRYPOINT(RACreateEncoderInstance) (const CLSID &clsid, IUnknown** ppUnknown)
- {
- HX_RESULT res = HXR_OUTOFMEMORY ;
- HXAudioEncoder* pObj = new HXAudioEncoder() ;
- if (pObj)
- res = pObj->Init() ;
- if (SUCCEEDED(res))
- res = pObj->QueryInterface(clsid, (void**)ppUnknown) ;
- return res ;
- }
- STDMETHODIMP HXAudioEncoder::SetOption(OPTION_LONG option, INT32 arg)
- {
- return HXR_NOTIMPL ;
- }
- STDMETHODIMP HXAudioEncoder::OpenEncoder()
- {
- HX_RESULT res ;
- RAENCODER_INIT_PARAMS initParams ;
- HX_AUDIO_FORMAT *p ;
- unsigned short pSize ;
- /* stupid. Some encoders (notably tokyo) check for consistency among initParams and its
- internal parameters, failing if inconsistent. This is why we have to fill this structure
- out */
- p = (HX_AUDIO_FORMAT*)ENTRYPOINT(RAGetFlavorProperty)(mpCodecRef, mCurrentFlavorIndex, ::FLV_PROP_INPUT_AUDIO_FORMAT, &pSize) ;
- if (p && pSize == sizeof(*p))
- {
- initParams.sampleRate = p->SamplesPerSec ;
- initParams.bitsPerSample = p->BitsPerSample ;
- initParams.channels = p->Channels ;
- if (p->BitsPerSample != 16)
- return HXR_NOTIMPL ;
- }
- res = ENTRYPOINT(RAInitEncoder)(mpCodecRef, &initParams) ;
- if (SUCCEEDED(res))
- {
- mnSamplesIn = initParams.numSamplesIn ;
- mnBytesOut = initParams.numBytesOut ;
- mDataOffset = mpPropTable[mCurrentFlavorIndex].bytesPerEncode ;
- mpDataIn = new short[mnSamplesIn] ;
- mpDataOut = new unsigned char[mnBytesOut] ;
- }
- return res ;
- }
- STDMETHODIMP_(void) HXAudioEncoder::CloseEncoder()
- {
- if (mpCodecRef) ENTRYPOINT(RAFreeEncoder)(mpCodecRef) ;
- if (mpDataIn) delete[] mpDataIn ;
- if (mpDataOut) delete[] mpDataOut ;
- }
- STDMETHODIMP
- HXAudioEncoder::EncodeData(void *pvDataIn, UINT32 nSamplesIn,
- UINT32& nSamplesConsumed,
- IQueryDecoderUnit* dataOut[], UINT32& nDecoderUnits,
- INT32 eof)
- {
- float *pfDataIn = (float*)pvDataIn ;
- UINT32 maxDecoderUnits = nDecoderUnits ;
- UINT32 samplesLeft = nSamplesIn ;
- nDecoderUnits = 0 ;
- nSamplesConsumed = 0 ;
- while (1)
- {
- if (samplesLeft > (eof ? 0 : mnSamplesIn-1) &&
- mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode) // can produce output
- {
- unsigned short *input ;
- if (samplesLeft >= mnSamplesIn)
- input = (unsigned short *)pvDataIn + nSamplesConsumed ;
- else
- {
- // apparently, eof is on. Copy remaining samples into temp buffer and fill with zeros.
- input = new unsigned short[mnSamplesIn] ;
- memcpy(input, (unsigned short*)pvDataIn + nSamplesConsumed, samplesLeft * sizeof(signed short)) ; /* Flawfinder: ignore */
- memset(input + samplesLeft, 0, (mnSamplesIn - samplesLeft) * sizeof(short)) ;
- }
- ENTRYPOINT(RAEncode)(mpCodecRef, input, mpDataOut) ;
- mDataOffset = 0 ;
- // delete the temp buffer if this was the last time around.
- if (samplesLeft < mnSamplesIn)
- delete[] input ;
- nSamplesConsumed += mnSamplesIn ;
- if (nSamplesConsumed > nSamplesIn)
- nSamplesConsumed = nSamplesIn ;
- }
- samplesLeft = nSamplesIn - nSamplesConsumed ;
- if (mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode)
- {
- // did not produce any samples, and none are pending
- break ;
- }
- // pack output into data units
- while (nDecoderUnits < maxDecoderUnits && mDataOffset < mpPropTable[mCurrentFlavorIndex].bytesPerEncode)
- {
- /* we have data pending from a previous Encode() call
- that are not yet shipped in decoder units. */
- /* since we always allocate these, we know they are really PrepareDecoderUnits,
- and the cast is harmless */
- IPrepareDecoderUnit* du = (IPrepareDecoderUnit*)dataOut[nDecoderUnits] ;
- if (du == 0) /* need to instantiate a new unit */
- {
- HX_RESULT hr = CreateIPrepareDecoderUnit(du) ;
- if (FAILED(hr))
- return hr ;
- dataOut[nDecoderUnits] = du ;
- }
- du->putData((const char*)mpDataOut + mDataOffset, mpPropTable[mCurrentFlavorIndex].bytesPerFrame, mpPropTable[mCurrentFlavorIndex].samplesPerFrame) ;
- du->setBufferFullness(0) ; // we are CBR
- if (eof && samplesLeft <= 0 &&
- mDataOffset == mpPropTable[mCurrentFlavorIndex].bytesPerEncode - mpPropTable[mCurrentFlavorIndex].bytesPerFrame )
- {
- // this is the very last decoder unit.
- du->setFlags(IQueryDecoderUnit::ENDOFSTREAM) ;
- }
- mDataOffset += mpPropTable[mCurrentFlavorIndex].bytesPerFrame ;
- nDecoderUnits++;
- if (nDecoderUnits == maxDecoderUnits)
- {
- return HXR_OK ;
- }
- }
- }
- return HXR_OK ;
- }
- HX_RESULT HXAudioEncoder::CreateIPrepareDecoderUnit(IPrepareDecoderUnit*& ppi)
- {
- CDecoderUnit *du = new CDecoderUnit() ;
- return du->QueryInterface(IID_IPrepareDecoderUnit, (void**)&ppi) ;
- }
- HX_RESULT HXAudioEncoder::SetPassword(const char* password)
- {
- if (mpCodecRef && password) ENTRYPOINT(RASetPwd)(mpCodecRef, password) ;
- return HXR_OK ; // we always smile, no matter what
- }