VorbisDecodeInputPin.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 #include "stdafx.h"
00033 
00034 #include "VorbisDecodeInputPin.h"
00035 
00036 
00037 VorbisDecodeInputPin::VorbisDecodeInputPin      (               AbstractTransformFilter* inFilter
00038                                                                                                 ,       CCritSec* inFilterLock
00039                                                                                                 ,       AbstractTransformOutputPin* inOutputPin
00040                                                                                                 ,       vector<CMediaType*> inAcceptableMediaTypes
00041                                                                                         )
00042 
00043         :       AbstractTransformInputPin                       (               inFilter
00044                                                                                                 ,       inFilterLock
00045                                                                                                 ,       inOutputPin
00046                                                                                                 ,       NAME("VorbisDecodeInputPin")
00047                                                                                                 ,       L"Vorbis In", inAcceptableMediaTypes
00048                                                                                         )
00049         ,       mBegun(false)
00050         ,       mFishSound(NULL)
00051 
00052         ,       mNumChannels(0)
00053         ,       mFrameSize(0)
00054         ,       mSampleRate(0)
00055         ,       mUptoFrame(0)
00056                 
00057 {
00058         //debugLog.open("g:\\logs\\vorbislog.log", ios_base::out);
00059         ConstructCodec();
00060 }
00061 
00062 VorbisDecodeInputPin::~VorbisDecodeInputPin(void)
00063 {
00064         //debugLog.close();
00065         DestroyCodec();
00066 }
00067 //Is this needed ??
00068 STDMETHODIMP VorbisDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00069 {
00070         if (riid == IID_IMediaSeeking) {
00071                 *ppv = (IMediaSeeking*)this;
00072                 ((IUnknown*)*ppv)->AddRef();
00073                 return NOERROR;
00074         }
00075 
00076         return AbstractTransformInputPin::NonDelegatingQueryInterface(riid, ppv); 
00077 }
00078 bool VorbisDecodeInputPin::ConstructCodec() 
00079 {
00080         mFishSound = fish_sound_new (FISH_SOUND_DECODE, &mFishInfo);                    //Deleted by destroycodec from destructor.
00081 
00082         int i = 1;
00083         //FIX::: Use new API for interleave setting
00084         fish_sound_command(mFishSound, FISH_SOUND_SET_INTERLEAVE, &i, sizeof(int));
00085 
00086         fish_sound_set_decoded_callback (mFishSound, VorbisDecodeInputPin::VorbisDecoded, this);
00087         //FIX::: Proper return value
00088         return true;
00089 }
00090 void VorbisDecodeInputPin::DestroyCodec() 
00091 {
00092         fish_sound_delete(mFishSound);
00093         mFishSound = NULL;
00094 }
00095 
00096 
00097 STDMETHODIMP VorbisDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate) 
00098 {
00099         CAutoLock locLock(mStreamLock);
00100         //debugLog<<"New segment "<<inStartTime<<" - "<<inStopTime<<endl;
00101         mUptoFrame = 0;
00102         return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
00103         
00104 }
00105 
00106 int __cdecl VorbisDecodeInputPin::VorbisDecoded (FishSound* inFishSound, float** inPCM, long inFrames, void* inThisPointer) 
00107 {
00108         
00109         VorbisDecodeInputPin* locThis = reinterpret_cast<VorbisDecodeInputPin*> (inThisPointer);
00110         VorbisDecodeFilter* locFilter = reinterpret_cast<VorbisDecodeFilter*>(locThis->m_pFilter);
00111 
00112         if (locThis->CheckStreaming() == S_OK) {
00113                 if (! locThis->mBegun) {
00114                         //locThis->debugLog<<"First Time"<<endl;
00115                         //Set up fishsound              
00116                         fish_sound_command (locThis->mFishSound, FISH_SOUND_GET_INFO, &(locThis->mFishInfo), sizeof (FishSoundInfo)); 
00117                         locThis->mBegun = true;
00118                         
00119                         locThis->mNumChannels = locThis->mFishInfo.channels;
00120                         locThis->mFrameSize = locThis->mNumChannels * SIZE_16_BITS;
00121                         locThis->mSampleRate = locThis->mFishInfo.samplerate;
00122 
00123                 }
00124 
00125 
00126                 unsigned long locActualSize = inFrames * locThis->mFrameSize;
00127                 unsigned long locTotalFrameCount = inFrames * locThis->mNumChannels;
00128                 
00129                 //locThis->debugLog<<"m_tStart = "<<locThis->m_tStart<<endl;
00130                 //locThis->debugLog<<"mUptoFrame = "<<locThis->mUptoFrame<<endl;
00131                 //Make the start presentation time
00132                 REFERENCE_TIME locFrameStart = (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00133 
00134                 //Increment the frame counter
00135                 locThis->mUptoFrame += inFrames;
00136 
00137                 //Make the end presentation time
00138                 REFERENCE_TIME locFrameEnd = (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00139 
00140                 //locThis->debugLog<<"Sample time = "<<locFrameStart<<" - "<<locFrameEnd<<endl;
00141                 IMediaSample* locSample;
00142                 HRESULT locHR = locThis->mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, NULL);
00143 
00144                 if (locHR != S_OK) {
00145                         return -1;
00146                 }       
00147                 
00148 
00149                 //Create pointers for the samples buffer to be assigned to
00150                 BYTE* locBuffer = NULL;
00151                 signed short* locShortBuffer = NULL;
00152                 
00153                 locSample->GetPointer(&locBuffer);
00154                 locShortBuffer = (short *) locBuffer;
00155                 
00156                 signed short tempInt = 0;
00157                 float tempFloat = 0;
00158                 
00159                 //FIX:::Move the clipping to the abstract function
00160 
00161                 if (locSample->GetSize() >= locActualSize) {
00162                         //Do float to int conversion with clipping
00163                         const float SINT_MAX_AS_FLOAT = 32767.0f;
00164                         for (unsigned long i = 0; i < locTotalFrameCount; i++) {
00165                                 //Clipping because vorbis puts out floats out of range -1 to 1
00166                                 if (((float*)inPCM)[i] <= -1.0f) {
00167                                         tempInt = SINT_MIN;     
00168                                 } else if (((float*)inPCM)[i] >= 1.0f) {
00169                                         tempInt = SINT_MAX;
00170                                 } else {
00171                                         //FIX:::Take out the unnescessary variable.
00172                                         tempFloat = ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00173                                         //ASSERT((tempFloat <= 32767.0f) && (tempFloat >= -32786.0f));
00174                                         tempInt = (signed short)(tempFloat);
00175                                         //tempInt = (signed short) ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00176                                 }
00177                                 
00178                                 *locShortBuffer = tempInt;
00179                                 locShortBuffer++;
00180                         }
00181                         
00182                         //Set the sample parameters.
00183                         locThis->SetSampleParams(locSample, locActualSize, &locFrameStart, &locFrameEnd);
00184 
00185                         {
00186                 
00187                                 CAutoLock locLock(locThis->m_pLock);
00188 
00189                                 //TODO::: Explain why we don't addref or release.
00190                                 HRESULT locHR = ((VorbisDecodeOutputPin*)(locThis->mOutputPin))->mDataQueue->Receive(locSample);
00191                                 if (locHR != S_OK) {
00192                                         DbgLog((LOG_TRACE,1,TEXT("Queue rejected us...")));
00193                                         return -1;
00194                                 }
00195                         }
00196 
00197                         
00198                         return 0;
00199                 } else {
00200                         throw 0;
00201                 }
00202         } else {
00203                 DbgLog((LOG_TRACE,1,TEXT("Fishsound sending stuff we aren't ready for...")));
00204                 return -1;
00205         }
00206 
00207 }
00208 
00209 
00210 
00211 HRESULT VorbisDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes) 
00212 {
00213         //TODO::: Return types !!!
00214 
00215         //debugLog << "Decode called... Last Gran Pos : "<<mLastSeenStartGranPos<<endl;
00216         DbgLog((LOG_TRACE,1,TEXT("decodeData")));
00217         long locErr = fish_sound_decode(mFishSound, inBuf, inNumBytes);
00218         //FIX::: Do something here ?
00219         if (locErr < 0) {
00220                 DbgLog((LOG_TRACE,1,TEXT("decodeData : fishsound returns < 0")));
00221                 return S_FALSE;
00222                 //debugLog <<"** Fish Sound error **"<<endl;
00223         } else {
00224                 return S_OK;
00225                 //debugLog << "Fish Sound OK >=0 "<<endl;
00226         }
00227         //return locErr;
00228 }
00229 
00230 
00231 HRESULT VorbisDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00232         //FIX:::Error checking
00233         //RESOLVED::: Bit better.
00234 
00235         if (inMediaType->subtype == MEDIASUBTYPE_Vorbis) {
00236                 ((VorbisDecodeFilter*)mParentFilter)->setVorbisFormat((sVorbisFormatBlock*)inMediaType->pbFormat);
00237                 
00238         } else {
00239                 throw 0;
00240         }
00241         return CBaseInputPin::SetMediaType(inMediaType);
00242 }
00243 
00244 
00245 
00246 
00247 //Old imp
00248 //*************************************************
00249 //#include "stdafx.h"
00250 //
00251 //#include "VorbisDecodeInputPin.h"
00252 //
00253 //
00254 //VorbisDecodeInputPin::VorbisDecodeInputPin(AbstractAudioDecodeFilter* inFilter, CCritSec* inFilterLock, AbstractAudioDecodeOutputPin* inOutputPin, CMediaType* inAcceptMediaType)
00255 //      :       AbstractAudioDecodeInputPin(inFilter, inFilterLock, inOutputPin, NAME("VorbisDecodeInputPin"), L"Vorbis In", inAcceptMediaType),
00256 //              mBegun(false)
00257 //      ,       mFishSound(NULL)
00258 //              
00259 //{
00260 //      //debugLog.open("g:\\logs\\vorbislog.log", ios_base::out);
00261 //      ConstructCodec();
00262 //}
00263 //
00264 //STDMETHODIMP VorbisDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00265 //{
00266 //      if (riid == IID_IMediaSeeking) {
00267 //              *ppv = (IMediaSeeking*)this;
00268 //              ((IUnknown*)*ppv)->AddRef();
00269 //              return NOERROR;
00270 //      }
00271 //
00272 //      return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00273 //}
00274 //bool VorbisDecodeInputPin::ConstructCodec() {
00275 //      mFishSound = fish_sound_new (FISH_SOUND_DECODE, &mFishInfo);                    //Deleted by destroycodec from destructor.
00276 //
00277 //      int i = 1;
00278 //      //FIX::: Use new API for interleave setting
00279 //      fish_sound_command(mFishSound, FISH_SOUND_SET_INTERLEAVE, &i, sizeof(int));
00280 //
00281 //      fish_sound_set_decoded_callback (mFishSound, VorbisDecodeInputPin::VorbisDecoded, this);
00282 //      //FIX::: Proper return value
00283 //      return true;
00284 //}
00285 //void VorbisDecodeInputPin::DestroyCodec() {
00286 //      fish_sound_delete(mFishSound);
00287 //      mFishSound = NULL;
00288 //}
00289 //VorbisDecodeInputPin::~VorbisDecodeInputPin(void)
00290 //{
00291 //      //debugLog.close();
00292 //      DestroyCodec();
00293 //}
00294 //
00295 //
00296 //
00297 //int __cdecl VorbisDecodeInputPin::VorbisDecoded (FishSound* inFishSound, float** inPCM, long inFrames, void* inThisPointer) 
00298 //{
00299 //
00300 //      DbgLog((LOG_TRACE,1,TEXT("Decoded... Sending...")));
00301 //      //Do we need to delete the pcm structure ???? 
00302 //      //More of this can go to the abstract class.
00303 //
00304 //      //For convenience we do all these cast once and for all here.
00305 //      VorbisDecodeInputPin* locThis = reinterpret_cast<VorbisDecodeInputPin*> (inThisPointer);
00306 //      VorbisDecodeFilter* locFilter = reinterpret_cast<VorbisDecodeFilter*>(locThis->m_pFilter);
00307 //      
00308 //
00309 //      if (locThis->CheckStreaming() == S_OK) {
00310 //              if (! locThis->mBegun) {
00311 //
00312 //              
00313 //                      fish_sound_command (locThis->mFishSound, FISH_SOUND_GET_INFO, &(locThis->mFishInfo), sizeof (FishSoundInfo)); 
00314 //                      locThis->mBegun = true;
00315 //                      
00316 //                      locThis->mNumChannels = locThis->mFishInfo.channels;
00317 //                      locThis->mFrameSize = locThis->mNumChannels * SIZE_16_BITS;
00318 //                      locThis->mSampleRate = locThis->mFishInfo.samplerate;
00319 //
00320 //              }
00321 //
00322 //              //FIX::: Most of this will be obselete... the demux does it all.
00323 //              
00324 //
00325 //              unsigned long locActualSize = inFrames * locThis->mFrameSize;
00326 //              unsigned long locTotalFrameCount = inFrames * locThis->mNumChannels;
00327 //              
00328 //              //REFERENCE_TIME locFrameStart = locThis->CurrentStartTime() + (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00329 //
00330 //
00331 //              //New hacks for chaining.
00332 //              if (locThis->mSeekTimeBase == -1) {
00333 //                      //locThis->debugLog<<"Chaining was detected... setting chain time base to : "<<locThis->mPreviousEndTime<<endl;
00334 //                      //This is our signal this is the start of a chain...
00335 //                      // This can only happen on non-seekable streams.
00336 //                      locThis->mChainTimeBase = locThis->mPreviousEndTime;
00337 //                      
00338 //                      locThis->mSeekTimeBase = 0;
00339 //              }
00340 //
00341 //              //Start time hacks
00342 //              REFERENCE_TIME locTimeBase = ((locThis->mLastSeenStartGranPos * UNITS) / locThis->mSampleRate) - locThis->mSeekTimeBase + locThis->mChainTimeBase;
00343 //      
00344 //              
00345 //              
00346 //              //locThis->aadDebug<<"Last Seen  : " <<locThis->mLastSeenStartGranPos<<endl;
00347 //              //locThis->debugLog<<"Last Seen  : " << locThis->mLastSeenStartGranPos<<endl;
00348 //              //locThis->debugLog<<"Time Base  : " << locTimeBase << endl;
00349 //              //locThis->debugLog<<"FrameCount : " <<locThis->mUptoFrame<<endl;
00350 //              //locThis->debugLog<<"Seek TB    : " <<locThis->mSeekTimeBase<<endl;
00351 //
00352 //              //Temp - this will break seeking
00353 //              REFERENCE_TIME locFrameStart = locTimeBase + (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00354 //              //Increment the frame counter
00355 //              locThis->mUptoFrame += inFrames;
00356 //              //Make the end frame counter
00357 //
00358 //              //REFERENCE_TIME locFrameEnd = locThis->CurrentStartTime() + (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00359 //              REFERENCE_TIME locFrameEnd = locTimeBase + (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00360 //              locThis->mPreviousEndTime = locFrameEnd;
00361 //
00362 //
00363 //
00364 //              //locThis->debugLog<<"Start      : "<<locFrameStart<<endl;
00365 //              //locThis->debugLog<<"End        : "<<locFrameEnd<<endl;
00366 //              //locThis->debugLog<<"=================================================="<<endl;
00367 //              IMediaSample* locSample;
00368 //              HRESULT locHR = locThis->mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, NULL);
00369 //
00370 //              if (locHR != S_OK) {
00371 //                      return -1;
00372 //              }       
00373 //              
00374 //
00375 //              //Create pointers for the samples buffer to be assigned to
00376 //              BYTE* locBuffer = NULL;
00377 //              signed short* locShortBuffer = NULL;
00378 //              
00379 //              locSample->GetPointer(&locBuffer);
00380 //              locShortBuffer = (short *) locBuffer;
00381 //              
00382 //              signed short tempInt = 0;
00383 //              float tempFloat = 0;
00384 //              
00385 //              //FIX:::Move the clipping to the abstract function
00386 //
00387 //              if (locSample->GetSize() >= locActualSize) {
00388 //                      //Do float to int conversion with clipping
00389 //                      const float SINT_MAX_AS_FLOAT = 32767.0f;
00390 //                      for (unsigned long i = 0; i < locTotalFrameCount; i++) {
00391 //                              //Clipping because vorbis puts out floats out of range -1 to 1
00392 //                              if (((float*)inPCM)[i] <= -1.0f) {
00393 //                                      tempInt = SINT_MIN;     
00394 //                              } else if (((float*)inPCM)[i] >= 1.0f) {
00395 //                                      tempInt = SINT_MAX;
00396 //                              } else {
00397 //                                      //FIX:::Take out the unnescessary variable.
00398 //                                      tempFloat = ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00399 //                                      //ASSERT((tempFloat <= 32767.0f) && (tempFloat >= -32786.0f));
00400 //                                      tempInt = (signed short)(tempFloat);
00401 //                                      //tempInt = (signed short) ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00402 //                              }
00403 //                              
00404 //                              *locShortBuffer = tempInt;
00405 //                              locShortBuffer++;
00406 //                      }
00407 //                      
00408 //                      //Set the sample parameters.
00409 //                      locThis->SetSampleParams(locSample, locActualSize, &locFrameStart, &locFrameEnd);
00410 //
00411 //                      {
00412 //              
00413 //                              CAutoLock locLock(locThis->m_pLock);
00414 //
00415 //                              //Add a reference so it isn't deleted en route.... or not
00416 //                              //locSample->AddRef();
00417 //                              HRESULT lHR = locThis->mOutputPin->mDataQueue->Receive(locSample);
00418 //                              if (lHR != S_OK) {
00419 //                                      DbgLog((LOG_TRACE,1,TEXT("Queue rejected us...")));
00420 //                                      return -1;
00421 //                              }
00422 //                      }
00423 //
00424 //                      //Don't Release the sample it gets done for us !
00425 //                      //locSample->Release();
00426 //
00427 //                      return 0;
00428 //              } else {
00429 //                      throw 0;
00430 //              }
00431 //      } else {
00432 //              DbgLog((LOG_TRACE,1,TEXT("Fishsound sending stuff we aren't ready for...")));
00433 //              return -1;
00434 //      }
00435 //
00436 //}
00437 //
00438 //
00439 //
00440 //long VorbisDecodeInputPin::decodeData(BYTE* inBuf, long inNumBytes) 
00441 //{
00442 //      //debugLog << "Decode called... Last Gran Pos : "<<mLastSeenStartGranPos<<endl;
00443 //      DbgLog((LOG_TRACE,1,TEXT("decodeData")));
00444 //      long locErr = fish_sound_decode(mFishSound, inBuf, inNumBytes);
00445 //      //FIX::: Do something here ?
00446 //      if (locErr < 0) {
00447 //              //debugLog <<"** Fish Sound error **"<<endl;
00448 //      } else {
00449 //              //debugLog << "Fish Sound OK >=0 "<<endl;
00450 //      }
00451 //      return locErr;
00452 //}
00453 //
00454 //
00455 //HRESULT VorbisDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00456 //      //FIX:::Error checking
00457 //      //RESOLVED::: Bit better.
00458 //
00459 //      if (inMediaType->subtype == MEDIASUBTYPE_Vorbis) {
00460 //              ((VorbisDecodeFilter*)mParentFilter)->setVorbisFormat((sVorbisFormatBlock*)inMediaType->pbFormat);
00461 //              mParentFilter->mAudioFormat = AbstractAudioDecodeFilter::VORBIS;
00462 //      } else {
00463 //              throw 0;
00464 //      }
00465 //      return CBaseInputPin::SetMediaType(inMediaType);
00466 //}
00467 //

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