cra2ihxadec.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 ***** */
- /* a first feeble attempt to endow the RA codecs with a new interface.
- This might not work yet. */
- #include <assert.h>
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxresult.h"
- #include "cra2ihxadec.h"
- #include "racodec.h"
- #include "sipr_str.h"
- /* heap, memory debugging */
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #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 */
- class HXAudioDecoder : IHXAudioDecoder
- {
- protected:
- ~HXAudioDecoder() ;
- public:
- /*
- * IUnknown methods
- */
- STDMETHOD(QueryInterface) (THIS_
- REFIID riid,
- void** ppvObj) ;
- STDMETHOD_(ULONG32,AddRef) (THIS) ;
- STDMETHOD_(ULONG32,Release) (THIS) ;
- /*
- * IHXAudioDecoder methods
- */
- STDMETHOD(OpenDecoder) (THIS_
- const void* params, int sizeOf) ;
- STDMETHOD(SetStreamBegin) (THIS_
- int& delay) ;
- // HX_RESULT DecodeData(CDecoderUnit units[], int nDecoderUnits) = 0 ;
- STDMETHOD(Conceal) (THIS_
- int nSamples) ;
- STDMETHOD(DecodeDataRaw) (THIS_
- const char *data,
- int nBytes,
- int& nBytesConsumed,
- short *samplesOut,
- int& nSamplesOut,
- int eof) ;
- STDMETHOD(MaxSamplesOut) (THIS_
- int& nSamples) CONSTMETHOD ;
- STDMETHOD_(void,CloseDecoder)(THIS) ;
- HXAudioDecoder() ;
- HX_RESULT Init() ;
- private:
- long m_lRefCount ;
- RACODEC mpCodecRef ;
- int mMaxSamplesOut ;
- int mBytesPerFrame ;
- int mnConceal ;
- bool mIsSiproCodec ;
- } ;
- HXAudioDecoder::HXAudioDecoder()
- : m_lRefCount(0)
- , mpCodecRef(0)
- , mMaxSamplesOut(0)
- , mBytesPerFrame(0)
- , mnConceal(0)
- , mIsSiproCodec(false)
- {
- }
- HXAudioDecoder::~HXAudioDecoder()
- {
- if (mpCodecRef)
- {
- ENTRYPOINT(RACloseCodec)(mpCodecRef) ;
- }
- }
- HX_RESULT HXEXPORT ENTRYPOINT(RACreateDecoderInstance) (const CLSID &clsid, IUnknown** ppUnknown)
- {
- HX_RESULT res = HXR_OUTOFMEMORY ;
- HXAudioDecoder* pObj = new HXAudioDecoder() ;
- if (pObj)
- res = pObj->Init() ;
- if (SUCCEEDED(res))
- res = pObj->QueryInterface(clsid, (void**)ppUnknown) ;
- return res ;
- }
- /****************************************************************************
- * IUnknown methods
- */
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::QueryInterface
- //
- STDMETHODIMP HXAudioDecoder::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IHXAudioDecoder))
- {
- AddRef();
- *ppvObj = (IHXAudioDecoder*) 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) HXAudioDecoder::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::Release
- //
- STDMETHODIMP_(ULONG32) HXAudioDecoder::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- HX_RESULT HXAudioDecoder::Init()
- {
- HX_RESULT res ;
- res = ENTRYPOINT(RAOpenCodec2)(&mpCodecRef, 0) ;
- // if (SUCCEEDED(res)) ENTRYPOINT(RASetPwd)(mpCodecRef, CURRENT_PWD) ;
- // if (SUCCEEDED(res)) res = retrieveProperties() ;
- return res ;
- }
- // HX_RESULT HXEXPORT ENTRYPOINT(RAInitDecoder) (RACODEC codecRef, void* pParam);
- // HX_RESULT HXEXPORT ENTRYPOINT(RADecode) (RACODEC codecRef, Byte* in, UINT32 inLength, Byte* out, UINT32* pOutLength, UINT32 userData);
- // HX_RESULT HXEXPORT ENTRYPOINT(RAFlush) (RACODEC codecRef, Byte* outBuf, UINT32* pOutLength);
- // void HXEXPORT ENTRYPOINT(RAFreeDecoder) (RACODEC codecRef);
- STDMETHODIMP HXAudioDecoder::OpenDecoder(const void* pInitParams, int sizeOf)
- {
- HX_RESULT res = HXR_OK ;
- RADECODER_INIT_PARAMS2 *pParams = (RADECODER_INIT_PARAMS2 *)pInitParams ;
- unsigned short pSize ;
- UINT32 *x ;
- int i, n = ENTRYPOINT(RAGetNumberOfFlavors2)(mpCodecRef) ;
- /* find out which decoder we are driving. Some decoders are not created equal... argh. */
- char *s = (char*)ENTRYPOINT(RAGetFlavorProperty)(mpCodecRef, 0, ::FLV_PROP_NAME, &pSize) ;
- mIsSiproCodec = (pSize && (0 == strncmp(SIPR_NAME_FLAVOR0, s, pSize))) ;
- if (SUCCEEDED(res)) res = ENTRYPOINT(RAInitDecoder)(mpCodecRef, (void*)&(pParams->p)) ;
- if (SUCCEEDED(res) && mIsSiproCodec) res = ENTRYPOINT(RASetFlavor)(mpCodecRef, pParams->flvNumber) ;
- #if 1
- x = (UINT32*)ENTRYPOINT(RAGetFlavorProperty)(mpCodecRef, pParams->flvNumber, ::FLV_PROP_SAMPLES_IN, &pSize) ;
- if (x && pSize == sizeof(*x) && *x > mMaxSamplesOut)
- {
- mMaxSamplesOut = *x ;
- }
- else
- {
- return HXR_INVALID_PARAMETER ;
- }
- #else
- mMaxSamplesOut = 0 ;
- for (i = 0 ; i < n ; i++)
- {
-
- x = (UINT32*)RAGetFlavorProperty(mpCodecRef, i, ::FLV_PROP_SAMPLES_IN, &pSize) ;
- if (x && pSize == sizeof(*x) && *x > mMaxSamplesOut)
- {
- mMaxSamplesOut = *x ;
- }
- }
- if (!mMaxSamplesOut)
- {
- res = HXR_NOTIMPL ;
- }
- #endif
- mBytesPerFrame = pParams->p.bitsPerFrame ;
- return res ;
- }
- STDMETHODIMP HXAudioDecoder::SetStreamBegin(int& delay)
- {
- delay = 0 ; // the old decoders ate the startup delay
- return HXR_OK ;
- }
- STDMETHODIMP HXAudioDecoder::Conceal(int nSamples)
- {
- mnConceal = nSamples ;
- return HXR_OK ;
- }
- STDMETHODIMP HXAudioDecoder::DecodeDataRaw(
- const char *data,
- int nBytes,
- int& nBytesConsumed,
- short *samplesOut,
- int& nSamplesOut,
- int eof)
- /* for the old CBR codecs, the length of the input data must be some
- multiple of the "frame size" */
- {
- HX_RESULT res = HXR_OK ;
- UINT32 mask ;
- unsigned long nSamples ;
- int maxSamplesOut ;
- int nFrames = nBytes / mBytesPerFrame ;
- if (nBytes - mBytesPerFrame * nFrames != 0)
- return HXR_INVALID_PARAMETER ;
- maxSamplesOut = nSamplesOut ;
- nSamplesOut = 0 ;
- nBytesConsumed = 0 ;
- /* now do concealment. We rely on the fact that nSamples is equal to maxSamplesOut in every call.
- This fails for the first couple of frames because decoders currently eat their delay. Oh well. */
- if (mnConceal)
- {
- #if 0
- int i ;
- for (i = 0 ; i < (mnConceal + mMaxSamplesOut/2) / mMaxSamplesOut ; i++)
- {
- res = RADecode(mpCodecRef, (unsigned char *)data, mBytesPerFrame, (Byte*)(samplesOut + nSamplesOut), &nSamples, 0) ;
- if (FAILED(res))
- break ;
- nSamples /= sizeof(short) ;
- nSamplesOut += nSamples ;
- }
- mnConceal = 0 ;
- #else
- nSamples = 0 ;
- while (mnConceal > (signed)nSamples / 2 && nSamplesOut + nSamples <= maxSamplesOut)
- {
- res = ENTRYPOINT(RADecode)(mpCodecRef, (unsigned char *)data, mBytesPerFrame, (Byte*)(samplesOut + nSamplesOut), &nSamples, 0) ;
- if (FAILED(res))
- break ;
- nSamples /= sizeof(short) ;
- mnConceal -= nSamples ;
- nSamplesOut += nSamples ;
- }
- if (mnConceal < (signed)nSamples / 2)
- {
- mnConceal = 0 ; // we assume we have concealed enough
- }
- #endif
- }
- while (!FAILED(res) &&
- nSamplesOut + mMaxSamplesOut <= maxSamplesOut &&
- nBytesConsumed < nBytes)
- {
- res = ENTRYPOINT(RADecode)(mpCodecRef, (unsigned char *)data + nBytesConsumed, mBytesPerFrame,
- (Byte*)(samplesOut + nSamplesOut), &nSamples, ~0UL) ;
- nSamples /= sizeof(short) ;
- nBytesConsumed += mBytesPerFrame ;
- nSamplesOut += nSamples ;
- }
- return res ;
- }
- STDMETHODIMP HXAudioDecoder::MaxSamplesOut(int& nSamples) const
- {
- nSamples = mIsSiproCodec ? 2 * mMaxSamplesOut : mMaxSamplesOut ;
- return HXR_OK ;
- }
- STDMETHODIMP_(void) HXAudioDecoder::CloseDecoder()
- {
- ENTRYPOINT(RAFreeDecoder)(mpCodecRef) ;
- }