VorbisEncodeInputPin.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 
00033 
00034 #include "stdafx.h"
00035 #include "VorbisEncodeInputPin.h"
00036 
00037 VorbisEncodeInputPin::VorbisEncodeInputPin(AbstractTransformFilter* inParentFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes)
00038         :       AbstractTransformInputPin(inParentFilter, inFilterLock, inOutputPin, NAME("VorbisEncodeInputPin"), L"PCM In", inAcceptableMediaTypes)
00039         ,       mFishSound(NULL)
00040         ,       mWaveFormat(NULL)
00041         ,       mUptoFrame(0)
00042         ,       mVorbisQuality(0.6f)
00043 {
00044 #ifdef OGGCODECS_LOGGING
00045         debugLog.open("G:\\logs\\vorbisenc.logs", ios_base::out);
00046 #endif
00047 }
00048 
00049 VorbisEncodeInputPin::~VorbisEncodeInputPin(void)
00050 {
00051         debugLog.close();
00052         DestroyCodec();
00053 }
00054 
00055 
00056 //PURE VIRTUALS
00057 HRESULT VorbisEncodeInputPin::TransformData(unsigned char* inBuf, long inNumBytes) 
00058 {
00059         
00060         float* locFloatBuf = new float[inNumBytes/2];
00061         short locTempShort = 0;
00062         float locTempFloat = 0;
00063 
00064         for (int i = 0; i < inNumBytes; i += 2) {
00065                 locTempShort = *((short*)(inBuf + i));
00066                 locTempFloat = (float)locTempShort;
00067                 locTempFloat /= 32767.0;
00068                 locFloatBuf[i/2] = locTempFloat;;
00069         }
00070         //FIX::: The 2 is the size of a sample ie 16 bits
00071         long locErr = fish_sound_encode(mFishSound, (float**)locFloatBuf, inNumBytes/(mFishInfo.channels*2));
00072         delete[] locFloatBuf;
00073         //FIX::: Do something here ?
00074         if (locErr < 0) {
00075         
00076         } else {
00077         
00078         }
00079         return locErr;
00080 }
00081 bool VorbisEncodeInputPin::ConstructCodec() {
00082         mFishInfo.channels = mWaveFormat->nChannels;
00083         mFishInfo.format = FISH_SOUND_VORBIS;
00084         mFishInfo.samplerate = mWaveFormat->nSamplesPerSec;
00085     
00086         mFishInfo.format = FISH_SOUND_VORBIS;
00087         
00088         //This has to be done before fishsound new... otherwise, wy the time we get to setting it later... it's too late.
00089         debugLog<<"Setting quality with fs command to "<<mVorbisQuality<<endl;
00090         
00091         //Evil bit of hackery to trick the check for null.
00092         int I_AM_NOT_NULL = 1;
00093 
00094         fish_sound_command((FishSound*)I_AM_NOT_NULL, FISH_SOUND_VORBIS_SET_QUALITY, &mVorbisQuality, sizeof(float));
00095 
00096         mFishSound = fish_sound_new (FISH_SOUND_ENCODE, &mFishInfo);
00097 
00098         //Change to fill in vorbis format block so muxer can work
00099         ((VorbisEncodeFilter*)mParentFilter)->mVorbisFormatBlock.numChannels = (unsigned char)mWaveFormat->nChannels;
00100         ((VorbisEncodeFilter*)mParentFilter)->mVorbisFormatBlock.samplesPerSec = mWaveFormat->nSamplesPerSec;
00101         //
00102 
00103         int i = 1;
00104         //FIX::: Use new API for interleave setting
00105         fish_sound_command(mFishSound, FISH_SOUND_SET_INTERLEAVE, &i, sizeof(int));
00106 
00107 
00108 
00109         fish_sound_set_encoded_callback (mFishSound, VorbisEncodeInputPin::VorbisEncoded, this);
00110         //FIX::: Proper return value
00111         return true;
00112 
00113 }
00114 void VorbisEncodeInputPin::DestroyCodec() 
00115 {
00116         fish_sound_delete(mFishSound);
00117         mFishSound = NULL;
00118 }
00119 
00120 
00121 //Encoded callback
00122 int VorbisEncodeInputPin::VorbisEncoded (FishSound* inFishSound, unsigned char* inPacketData, long inNumBytes, void* inThisPointer) 
00123 {
00124 
00125         VorbisEncodeInputPin* locThis = reinterpret_cast<VorbisEncodeInputPin*> (inThisPointer);
00126         VorbisEncodeFilter* locFilter = reinterpret_cast<VorbisEncodeFilter*>(locThis->m_pFilter);
00127         
00128 
00129         //Time stamps are granule pos not directshow times - granule pos in vorbis is equivalent to frame number
00130 
00131         LONGLONG locFrameStart = locThis->mUptoFrame;
00132         LONGLONG locFrameEnd    = locThis->mUptoFrame
00133                                                         = fish_sound_get_frameno(locThis->mFishSound);
00134         //Get a pointer to a new sample stamped with our time
00135         IMediaSample* locSample;
00136         HRESULT locHR = locThis->mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, NULL);
00137 
00138         if (FAILED(locHR)) {
00139                 //We get here when the application goes into stop mode usually.
00140                 return locHR;
00141         }       
00142         
00143         BYTE* locBuffer = NULL;
00144 
00145         
00146         //Make our pointers set to point to the samples buffer
00147         locSample->GetPointer(&locBuffer);
00148 
00149         
00150 
00151         if (locSample->GetSize() >= inNumBytes) {
00152 
00153                 memcpy((void*)locBuffer, (const void*)inPacketData, inNumBytes);
00154                 
00155                 //Set the sample parameters.
00156                 locThis->SetSampleParams(locSample, inNumBytes, &locFrameStart, &locFrameEnd);
00157 
00158                 {
00159                         CAutoLock locLock(locThis->m_pLock);
00160 
00161                         //Add a reference so it isn't deleted en route.
00162                         //locSample->AddRef();
00163                         HRESULT locHR = ((VorbisEncodeOutputPin*)(locThis->mOutputPin))->mDataQueue->Receive(locSample);                                                //->DownstreamFilter()->Receive(locSample);
00164                         if (locHR != S_OK) {
00165                                 
00166                         } else {
00167                         }
00168                 }
00169 
00170                 return 0;
00171         } else {
00172                 throw 0;
00173         }
00174 }
00175 
00176 
00177 HRESULT VorbisEncodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00178         if (    (inMediaType->subtype == MEDIASUBTYPE_PCM) &&
00179                         (inMediaType->formattype == FORMAT_WaveFormatEx)) {
00180 
00181                 mWaveFormat = (WAVEFORMATEX*)inMediaType->pbFormat;
00182                 //mParentFilter->mAudioFormat = AbstractAudioDecodeFilter::VORBIS;
00183         } else {
00184                 //Failed... should never be here !
00185                 throw 0;
00186         }
00187         //This is here and not the constructor because we need audio params from the
00188         // input pin to construct properly.
00189         ConstructCodec();
00190 
00191         return CBaseInputPin::SetMediaType(inMediaType);
00192 
00193         
00194 }

Generated on Tue Feb 15 14:54:17 2005 for oggdsf by  doxygen 1.3.9