FLACDecodeInputPin.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 #include "flacdecodeinputpin.h"
00034 
00035 FLACDecodeInputPin::FLACDecodeInputPin(AbstractTransformFilter* inParentFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes)
00036         :       AbstractTransformInputPin(inParentFilter, inFilterLock, inOutputPin, NAME("FLACDecodeInputPin"), L"FLAC In", inAcceptableMediaTypes)
00037         ,       mGotMetaData(false)
00038         ,       mCodecLock(NULL)
00039 
00040         ,       mUptoFrame(0)
00041 
00042 {
00043         //debugLog.open("G:\\logs\\flacfilter.log", ios_base::out);
00044         mCodecLock = new CCritSec;                      //Deleted in destructor.
00045         ConstructCodec();
00046 }
00047 
00048 FLACDecodeInputPin::~FLACDecodeInputPin(void)
00049 {
00050         //debugLog.close();
00051         delete mCodecLock;
00052         
00053 }
00054 
00055 STDMETHODIMP FLACDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00056 {
00057         if (riid == IID_IMediaSeeking) {
00058                 *ppv = (IMediaSeeking*)this;
00059                 ((IUnknown*)*ppv)->AddRef();
00060                 return NOERROR;
00061         }
00062 
00063         return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00064 }
00065 bool FLACDecodeInputPin::ConstructCodec() 
00066 {
00067         mFLACDecoder.initCodec();
00068 
00069         return true;
00070 }
00071 void FLACDecodeInputPin::DestroyCodec() 
00072 {
00073 
00074 }
00075 STDMETHODIMP FLACDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate) 
00076 {
00077         CAutoLock locLock(mStreamLock);
00078         //debugLog<<"New segment "<<inStartTime<<" - "<<inStopTime<<endl;
00079         mUptoFrame = 0;
00080         return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
00081         
00082 }
00083 HRESULT FLACDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes) 
00084 {
00085 
00086         //TODO::: Locks ???
00087 
00088         //What happens when another packet arrives and the other one is still there ?
00089         //delete mPendingPacket;
00090         //debugLog<<"decodeData : "<<endl;
00091         if(!m_bFlushing) {
00092                 unsigned char* locBuff = new unsigned char[inNumBytes];                 //Given to packet.
00093                 memcpy((void*)locBuff, (const void*)inBuf, inNumBytes);
00094 
00095                 OggPacket* locPacket = new OggPacket(locBuff, inNumBytes, false, false);        //We give this away.
00096 
00097                 if (mGotMetaData) {
00098                         StampedOggPacket* locStamped = NULL;
00099                         {
00100                                 CAutoLock locCodecLock(mCodecLock);
00101                                 //for(unsigned long i = 0; i < mPendingPackets.size(); i++) {
00102                                  locStamped = (StampedOggPacket*)mFLACDecoder.decodeFLAC(locPacket)->clone();                   //clone deleted below, locpacket accepted by decoder.
00103                         }
00104 
00105                         if (locStamped != NULL) {
00106                                 //Do the directshow crap here....
00107 
00108                                 IMediaSample* locSample;
00109 
00110                                 HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, NULL, NULL, NULL);
00111                                 
00112                                 if (FAILED(locHR)) {
00113                                         //debugLog<<"Write_Callback : Get deliverybuffer failed. returning abort code."<<endl;
00114                                         //              //We get here when the application goes into stop mode usually.
00115                                         delete locStamped;
00116                                         return S_FALSE;
00117                                 }       
00118 
00119 
00120                                 BYTE* locBuffer = NULL;
00121 
00122 
00123                                 //      //Make our pointers set to point to the samples buffer
00124                                 locSample->GetPointer(&locBuffer);
00125 
00126 
00127                                 //*** WARNING 4018: Leave this.
00128                                 if (locSample->GetSize() >= locStamped->packetSize()) {
00129                                         REFERENCE_TIME locFrameStart = (((__int64)(mUptoFrame * UNITS)) / mFLACDecoder.mSampleRate);
00130                                         
00131                                         //Increment the frame counter
00132                                         //NOTE::: The returned packet is stamped 0-numSamples so endTime will be in long range.
00133                                         mUptoFrame += (unsigned long)locStamped->endTime();
00134                                         
00135                                         //      //Make the end frame counter
00136 
00137                                         REFERENCE_TIME locFrameEnd = (((__int64)(mUptoFrame * UNITS)) / mFLACDecoder.mSampleRate);
00138 
00139                                         memcpy((void*)locBuffer, (const void*)locStamped->packetData(), locStamped->packetSize());
00140                                         SetSampleParams(locSample, locStamped->packetSize(), &locFrameStart, &locFrameEnd);
00141                                         HRESULT locHR = ((FLACDecodeOutputPin*)(mOutputPin))->mDataQueue->Receive(locSample);
00142                                         if (locHR != S_OK) {
00143         
00144                                         } else {
00145                                                 //debugLog<<"Write_Callback : Delivery of sample succeeded"<<endl;
00146                                         }
00147                                 } else {
00148                                         delete locStamped;
00149                                         throw 0;                //SAMPLE SIZE IS TOO SMALL TO FIT DATA
00150                                 }
00151 
00152 
00153                                 delete locStamped;
00154                                 return S_OK;
00155                         } else {
00156                                 return S_FALSE;
00157                         }
00158                 } else {
00159                         {
00160                                 CAutoLock locCodecLock(mCodecLock);
00161                                 mGotMetaData = mFLACDecoder.acceptMetadata(locPacket);          //Accepts the packet.
00162                         }
00163                         if (mGotMetaData) {
00164                                 return S_OK;
00165                         } else {
00166                                 return S_FALSE;
00167                         }
00168                 }
00169 
00170         } else {
00171                 //debugLog<<"decodeData : Filter flushing... bad things !!!"<<endl;
00172                 return S_FALSE;
00173         }
00174 
00175         
00176 }
00177 
00178 
00179 STDMETHODIMP FLACDecodeInputPin::BeginFlush() {
00180         CAutoLock locLock(m_pLock);
00181         
00182         //debugLog<<"BeginFlush : Calling flush on the codec."<<endl;
00183 
00184         HRESULT locHR = AbstractTransformInputPin::BeginFlush();
00185         {       //PROTECT CODEC FROM IMPLODING
00186                 CAutoLock locCodecLock(mCodecLock);
00187                 mFLACDecoder.flushCodec();
00188         }       //END CRITICAL SECTION
00189         return locHR;
00190         
00191 }
00192 
00193 STDMETHODIMP FLACDecodeInputPin::EndOfStream(void) {
00194         CAutoLock locStreamLock(mStreamLock);
00195         {       //PROTECT CODEC FROM IMPLODING
00196                 CAutoLock locCodecLock(mCodecLock);
00197                 mFLACDecoder.flushCodec();
00198         }       //END CRITICAL SECTION
00199 
00200         return AbstractTransformInputPin::EndOfStream();
00201 }
00202 
00203 HRESULT FLACDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00204         //FIX:::Error checking
00205         //RESOLVED::: Bit better.
00206 
00207         if (inMediaType->subtype == MEDIASUBTYPE_FLAC) {
00208                 
00209                 //Keep the format block
00210                 
00211                 ((FLACDecodeFilter*)mParentFilter)->setFLACFormatBlock((sFLACFormatBlock*)inMediaType->pbFormat);               //Copies the format in the mutator
00212 
00213         } else {
00214                 throw 0;
00215         }
00216         return CBaseInputPin::SetMediaType(inMediaType);
00217 }
00218 

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