AbstractAudioDecodeInputPin.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 "abstractaudiodecodeinputpin.h"
00034 
00035 //#include <mtype.h>
00036 AbstractAudioDecodeInputPin::AbstractAudioDecodeInputPin (AbstractAudioDecodeFilter* inParentFilter, CCritSec* inFilterLock, AbstractAudioDecodeOutputPin* inOutputPin, CHAR* inObjectName, LPCWSTR inPinDisplayName, CMediaType* inAcceptMediaType)
00037         :       CBaseInputPin (inObjectName, inParentFilter, inFilterLock, &mHR, inPinDisplayName)
00038         ,       mOutputPin (inOutputPin)
00039         ,       mParentFilter (inParentFilter)
00040         
00041         ,       mBegun (false)
00042         ,       mUptoFrame (0)
00043         ,       mFrameSize (0)
00044         ,       mNumChannels (0)
00045         ,       mSampleRate (0)
00046         //,     mFilterLock(inFilterLock)
00047         ,       mLastSeenStartGranPos (0)
00048         ,       mSeekTimeBase (0)
00049         ,       mChainTimeBase (0)
00050 {
00051         
00052         //ConstructCodec();
00053         //debugLog.open("g:\\logs\\aad.log", ios_base::out);
00054         mAcceptableMediaType = inAcceptMediaType;
00055         mStreamLock = new CCritSec;                     //Deleted in destructor.
00056 
00057         //This is causing a problem... since every addref on a pin automatically
00058         // adds a ref to the filter... we get the situation, where on shutdown
00059         // the output pin still hold a ref on the input pin due to this bit of code
00060         // So at shutdown, 
00061         // the input pin has a ref count of 1
00062         // the output pin has a ref count of 0 (it's released by the downstream filter)
00063         // the filter has a ref count of 1 by way of the automatic addref from the input pin
00064         // This means that even when everything else releases all it's refs on the filter
00065         // it still has a ref count of 1... and since currently the ref that the
00066         // output pin holds on the input pin isn't release until the output pin is
00067         // destroyed, and the output pin isn't destroyed until the filter is
00068         // we get a circular reference.
00069         //
00070         //New solution is to attach this reference (from output to input) on the
00071         // complete connect method of the output pin via mParentfilter
00072         // and to release it when on the break conncet of the output pin.
00073         // This means that now as soon as the downstream filter releases the output
00074         // pin, it will release it's ref on the input pin, leaving the pins and the filer with
00075         // zero ref counts... well thats the plan anyway.
00076         //
00077         //IMediaSeeking* locSeeker = NULL;
00078         //this->NonDelegatingQueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00079         //mOutputPin->SetDelegate(locSeeker);
00080         //
00081 }
00082 
00083 STDMETHODIMP AbstractAudioDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00084 {
00085         if (riid == IID_IMediaSeeking) {
00086                 *ppv = (IMediaSeeking*)this;
00087                 ((IUnknown*)*ppv)->AddRef();
00088                 return NOERROR;
00089         }
00090 
00091         return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00092 }
00093 
00094 HRESULT AbstractAudioDecodeInputPin::BreakConnect() 
00095 {
00096         CAutoLock locLock(m_pLock);
00097         //Release the seeking 
00098         ReleaseDelegate();
00099         return CBaseInputPin::BreakConnect();
00100 }
00101 HRESULT AbstractAudioDecodeInputPin::CompleteConnect (IPin *inReceivePin) 
00102 {
00103         CAutoLock locLock(m_pLock);
00104         
00105         IMediaSeeking* locSeeker = NULL;
00106         inReceivePin->QueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00107         SetDelegate(locSeeker);
00108         return CBaseInputPin::CompleteConnect(inReceivePin);
00109 }
00110 AbstractAudioDecodeInputPin::~AbstractAudioDecodeInputPin(void)
00111 {
00112         //DestroyCodec();
00113         //debugLog.close();
00114         delete mStreamLock;
00115         delete mAcceptableMediaType;
00116         mAcceptableMediaType = NULL;
00117 }
00118 
00119 
00120 void AbstractAudioDecodeInputPin::ResetFrameCount() 
00121 {
00122         mUptoFrame = 0;
00123         
00124 }
00125 void AbstractAudioDecodeInputPin::ResetTimeBases() 
00126 {
00127         mLastSeenStartGranPos = 0;
00128 }
00129 bool AbstractAudioDecodeInputPin::SetSampleParams(IMediaSample* outMediaSample, unsigned long inDataSize, REFERENCE_TIME* inStartTime, REFERENCE_TIME* inEndTime) 
00130 {
00131         outMediaSample->SetTime(inStartTime, inEndTime);
00132         outMediaSample->SetMediaTime(NULL, NULL);
00133         outMediaSample->SetActualDataLength(inDataSize);
00134         outMediaSample->SetPreroll(FALSE);
00135         outMediaSample->SetDiscontinuity(FALSE);
00136         outMediaSample->SetSyncPoint(TRUE);
00137         return true;
00138 }
00139 
00140 
00141 STDMETHODIMP AbstractAudioDecodeInputPin::Receive(IMediaSample* inSample) 
00142 {
00143         CAutoLock locLock(mStreamLock);
00144 
00145         HRESULT locHR = CheckStreaming();
00146 
00147         if (locHR == S_OK) {
00148                 BYTE* locBuff = NULL;
00149                 locHR = inSample->GetPointer(&locBuff);
00150 
00151                 if (FAILED(locHR)) {
00152                         return locHR;
00153                 } else {
00154                         //New start time hacks
00155                         REFERENCE_TIME locStart = 0;
00156                         REFERENCE_TIME locEnd = 0;
00157 
00158                         //More work arounds for that stupid granule pos scheme in theora!
00159                         REFERENCE_TIME locTimeBase = 0;
00160                         REFERENCE_TIME locDummy = 0;
00161                         inSample->GetMediaTime(&locTimeBase, &locDummy);
00162                         mSeekTimeBase = locTimeBase;
00163                         //
00164 
00165                         inSample->GetTime(&locStart, &locEnd);
00166                         //Error chacks needed here
00167                         //debugLog<<"Receive : Start    = "<<locStart<<endl;
00168                         //debugLog<<"Receive : End      = "<<locEnd<<endl;
00169                         //debugLog<<"Receive : Timebase = "<<locTimeBase<<endl;
00170                         
00171                         if ((mLastSeenStartGranPos != locStart) && (locStart != -1)) {
00172                                 //debugLog<<"Receive : RESETTING FRAME COUNT !!"<<endl;
00173                                 ResetFrameCount();
00174                         }
00175                         //debugLog<<endl;
00176                         mLastSeenStartGranPos = locStart;
00177                         //End of additions
00178                         
00179                         long locResult = decodeData(locBuff, inSample->GetActualDataLength());
00180                         if (locResult == 0) {
00181 
00182                                 //aadDebug<<"Receive Decode : OK"<<endl;
00183                                 return S_OK;
00184                         } else {
00185                                 //aadDebug<<"Receive Decode : *** FAILED *** "<<locResult<<endl;
00186                                 return S_FALSE;
00187                         }
00188                 }
00189         } else {
00190                 //debugLog<<"NOT STREAMING.... "<<endl;
00191                 return locHR;
00192         }
00193         
00194         return S_OK;
00195 }
00196 
00197 HRESULT AbstractAudioDecodeInputPin::CheckMediaType(const CMediaType *inMediaType) {
00198         //TO DO::: Neaten this up.      
00199         if      ( (inMediaType->majortype == MEDIATYPE_Audio) &&
00200                         (inMediaType->subtype == mAcceptableMediaType->subtype) && (inMediaType->formattype == mAcceptableMediaType->formattype)
00201                 )
00202         {
00203                 return S_OK;
00204         } else {
00205                 return S_FALSE;
00206         }
00207 }
00208 
00209 STDMETHODIMP AbstractAudioDecodeInputPin::EndOfStream(void) {
00210         CAutoLock locLock(mStreamLock);
00211         
00212         return mParentFilter->mOutputPin->DeliverEndOfStream();
00213 }
00214 
00215 STDMETHODIMP AbstractAudioDecodeInputPin::BeginFlush() {
00216         CAutoLock locLock(m_pLock);
00217 
00218         CBaseInputPin::BeginFlush();
00219         return mParentFilter->mOutputPin->DeliverBeginFlush();
00220 }
00221 STDMETHODIMP AbstractAudioDecodeInputPin::EndFlush() {
00222         CAutoLock locLock(m_pLock);
00223 
00224         mParentFilter->mOutputPin->DeliverEndFlush();
00225         return CBaseInputPin::EndFlush();
00226 }
00227 
00228 STDMETHODIMP AbstractAudioDecodeInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) {
00229         CAutoLock locLock(mStreamLock);
00230         ResetFrameCount();
00231 
00232         //BUG::: Why is this on the base pin and not the baseinputpin ?
00233         CBasePin::NewSegment(tStart, tStop, dRate);
00234         return mParentFilter->mOutputPin->DeliverNewSegment(tStart, tStop, dRate);
00235 }
00236 
00237 HRESULT AbstractAudioDecodeInputPin::GetMediaType(int inPosition, CMediaType *outMediaType) {
00238 
00239         if (inPosition < 0) {
00240                 return E_INVALIDARG;
00241         }
00242 
00243         switch (inPosition) {
00244                 case 0:
00245 
00246                         outMediaType->SetType(&MEDIATYPE_Audio);
00247                         outMediaType->SetSubtype(&(mAcceptableMediaType->subtype));
00248                         //Don't set the format data here. That's up to our output pin/
00249                         return S_OK;                    
00250                 default:
00251                         return VFW_S_NO_MORE_ITEMS;
00252         }
00253 }

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