OggDemuxSourcePin.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 #include "stdafx.h"
00032 #include "oggdemuxsourcepin.h"
00033 
00034 OggDemuxSourcePin::OggDemuxSourcePin(   TCHAR* inObjectName, 
00035                                                                                 OggDemuxSourceFilter* inParentFilter,
00036                                                                                 CCritSec* inFilterLock,
00037                                                                                 StreamHeaders* inHeaderSource, 
00038                                                                                 CMediaType* inMediaType,
00039                                                                                 wstring inPinName,
00040                                                                                 bool inAllowSeek,
00041                                                                                 unsigned long inNumBuffers,
00042                                                                                 unsigned long inBufferSize)
00043         :       CBaseOutputPin(                 NAME("Ogg Demux Output Pin")
00044                                                         ,       inParentFilter
00045                                                         ,       inFilterLock
00046                                                         ,       &mFilterHR
00047                                                         ,       inPinName.c_str() )
00048         ,       mHeaders(inHeaderSource)
00049         ,       mParentFilter(inParentFilter)
00050         ,       mMediaType(inMediaType)
00051         ,       mDataQueue(NULL)
00052         ,       mFirstRun(true)
00053         ,       mPartialPacket(NULL)
00054         ,       mBufferSize(inBufferSize)
00055         ,       mNumBuffers(inNumBuffers)
00056                 
00057 {
00058         //TODO::: Something about this is causing a COM reference leak.
00059 #ifdef OGGCODECS_LOGGING
00060         debugLog.open("d:\\zen\\logs\\sourcefilterpin.log", ios_base::out);
00061 #endif
00062 
00063         IMediaSeeking* locSeeker = NULL;
00064         //if (inAllowSeek) {
00065                 //debugLog<<"Allowing seek"<<endl;
00066                 //Subvert COM and do this directly... this way, the source filter won't expose the interface to the
00067                 // graph but we can still delegate to it.
00068                 
00069                 //inParentFilter->NonDelegatingQueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00070                 locSeeker = (IMediaSeeking*)mParentFilter;
00071 
00072                 //UNdecided whether this should be adreff or not... if you do you have  a cyclic reference, if you don't see below.
00073                 //locSeeker->AddRef();                          //If you addref theres a weird destructor infinite loop. See the OggStreamMapper Destructor.
00074 
00075         
00076         //}
00077         SetDelegate(locSeeker);
00078 }
00079 
00080 OggDemuxSourcePin::~OggDemuxSourcePin(void)
00081 {
00082         debugLog.close();
00083         
00084         delete mDataQueue;
00085         mDataQueue = NULL;
00086 }
00087 
00088 STDMETHODIMP OggDemuxSourcePin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00089 {
00090         if (riid == IID_IMediaSeeking) {
00091                 //debugLog<<"Pin queried for IMediaSeeking"<<endl;
00092                 *ppv = (IMediaSeeking*)this;
00093                 ((IUnknown*)*ppv)->AddRef();
00094                 return NOERROR;
00095         }
00096 
00097         return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); 
00098 }
00099 
00100 
00101 bool OggDemuxSourcePin::deliverOggPacket(StampedOggPacket* inPacket) 
00102 {
00103         //We don't own the packet, so don't delete it.
00104         CAutoLock locStreamLock(mParentFilter->mStreamLock);
00105 
00106 
00107         IMediaSample* locSample = NULL;
00108         REFERENCE_TIME locStart = inPacket->startTime();
00109         REFERENCE_TIME locStop = inPacket->endTime();
00110         debugLog<<"Delivering packet : "<<locStart<< " - "<<locStop<<endl;
00111 
00112 
00113         HRESULT locHR = GetDeliveryBuffer(&locSample, &locStart, &locStop, NULL);
00114         DbgLog((LOG_TRACE, 2, "* After get Buffer in Source Pin..."));
00115         //Error checks
00116         if (locHR != S_OK) {
00117                 //Stopping, fluching or error
00118 
00119                 debugLog<<"Failure... No buffer"<<endl;
00120                 return false;
00121         }
00122 
00123         //More hacks so we can send a timebase after a seek, since granule pos in theora
00124         // is not convertible in both directions to time.
00125         
00126         //TIMESTAMP FIXING !
00127         locSample->SetTime(&locStart, &locStop);
00128         
00129         //TODO::: This style of timestamping should not be necessary anymore.
00130         //Yes this is way dodgy !
00131         locSample->SetMediaTime(&mParentFilter->mSeekTimeBase, &mParentFilter->mSeekTimeBase);
00132         locSample->SetSyncPoint(TRUE);
00133         
00134 
00135         // Create a pointer for the samples buffer
00136         BYTE* locBuffer = NULL;
00137         locSample->GetPointer(&locBuffer);
00138 
00139         if (locSample->GetSize() >= inPacket->packetSize()) {
00140 
00141                 memcpy((void*)locBuffer, (const void*)inPacket->packetData(), inPacket->packetSize());
00142                 locSample->SetActualDataLength(inPacket->packetSize());
00143 
00144                 locHR = mDataQueue->Receive(locSample);
00145 
00146                 if (locHR != S_OK) {
00147                         debugLog << "Failure... Queue rejected sample..."<<endl;
00148                         //Stopping ??
00149 
00150                         return false;
00151                 } else {
00152 
00153                         return true;
00154                 }
00155         } else {
00156                 DbgLog((LOG_TRACE, 2, "* BUFFER TOO SMALL... FATALITY !!"));
00157                 throw 0;
00158         }
00159 }
00160 HRESULT OggDemuxSourcePin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00161 {
00162         debugLog<<"Delivering new segment"<<endl;
00163         NewSegment(tStart, tStop, dRate);
00164 
00165         mPartialPacket = NULL;
00166         mDataQueue->NewSegment(tStart, tStop, dRate);
00167 
00168         return S_OK;
00169 }
00170 HRESULT OggDemuxSourcePin::DeliverEndOfStream(void)
00171 {
00172         mPartialPacket = NULL;
00173         mDataQueue->EOS();
00174     return S_OK;
00175 }
00176 
00177 HRESULT OggDemuxSourcePin::DeliverEndFlush(void)
00178 {
00179         debugLog<<"Delivering End flush"<<endl;
00180         mDataQueue->EndFlush();
00181     return S_OK;
00182 }
00183 
00184 HRESULT OggDemuxSourcePin::DeliverBeginFlush(void)
00185 {
00186         debugLog<<"Delivering begin flush"<<endl;
00187         mPartialPacket = NULL;
00188         mDataQueue->BeginFlush();
00189     return S_OK;
00190 }
00191 
00192 HRESULT OggDemuxSourcePin::CompleteConnect (IPin *inReceivePin)
00193 {
00194         mFilterHR = S_OK;
00195         //Set the delegate for seeking
00196         //((BasicSeekable*)(inReceivePin))->SetDelegate(this);
00197         //This may cause issue if pins are disconnected and reconnected
00198         //DELETE in DEStructor
00199         mDataQueue = new COutputQueue (inReceivePin, &mFilterHR, FALSE, TRUE,1,TRUE, NUM_BUFFERS);
00200         
00201         return CBaseOutputPin::CompleteConnect(inReceivePin);
00202 }
00203 
00204 HRESULT OggDemuxSourcePin::BreakConnect(void) 
00205 {
00206         delete mDataQueue;
00207         mDataQueue = NULL;
00208         return CBaseOutputPin::BreakConnect();
00209 }
00210 
00211         //CSourceStream virtuals
00212 HRESULT OggDemuxSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType) 
00213 {
00214         //Put it in from the info we got in the constructor.
00215         if (inPosition == 0) {
00216                 *outMediaType = *mMediaType;
00217                 return S_OK;
00218         } else {
00219                 return VFW_S_NO_MORE_ITEMS;
00220         }
00221 }
00222 HRESULT OggDemuxSourcePin::CheckMediaType(const CMediaType* inMediaType) {
00223         if (inMediaType->majortype == mMediaType->majortype && inMediaType->subtype == mMediaType->subtype && inMediaType->formattype == mMediaType->formattype) {
00224                 return S_OK;
00225         } else {
00226                 return E_FAIL;
00227         }
00228 }
00229 HRESULT OggDemuxSourcePin::DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest) 
00230 {
00231         HRESULT locHR = S_OK;
00232 
00233         ALLOCATOR_PROPERTIES locReqAlloc;
00234         ALLOCATOR_PROPERTIES locActualAlloc;
00235 
00236         locReqAlloc.cbAlign = 1;
00237         locReqAlloc.cbBuffer = mBufferSize; //BUFFER_SIZE;
00238         locReqAlloc.cbPrefix = 0;
00239         locReqAlloc.cBuffers = mNumBuffers; //NUM_BUFFERS;
00240 
00241         locHR = inoutAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00242 
00243         if (locHR != S_OK) {
00244                 return locHR;
00245         }
00246         
00247         locHR = inoutAllocator->Commit();
00248 
00249         return locHR;
00250 
00251 }
00252 
00253 

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