OggDemuxSourceFilter.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 "oggdemuxsourcefilter.h"
00034 
00035 //#define OGGCODECS_LOGGING
00036 
00037 //-------------------
00038 // This template lets the Object factory create us properly and work with COM infrastructure.
00039 CFactoryTemplate g_Templates[] = 
00040 {
00041     { 
00042                 L"OggDemuxFilter",                                              // Name
00043             &CLSID_OggDemuxSourceFilter,            // CLSID
00044             OggDemuxSourceFilter::CreateInstance,       // Method to create an instance of MyComponent
00045         NULL,                                                                   // Initialization function
00046         NULL                                                                    // Set-up information (for filters)
00047     },
00048 
00049         { 
00050                 L"illiminable About Page",                              // Name
00051             &CLSID_PropsAbout,                                          // CLSID
00052             PropsAbout::CreateInstance,                         // Method to create an instance of MyComponent
00053         NULL,                                                                   // Initialization function
00054         NULL                                                                    // Set-up information (for filters)
00055     }
00056 
00057 };
00058 
00059 // Generic way of determining the number of items in the template
00060 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
00061 
00062 
00063 //COM Creator Function
00064 CUnknown* WINAPI OggDemuxSourceFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00065 {
00066         OggDemuxSourceFilter *pNewObject = new OggDemuxSourceFilter();
00067     if (pNewObject == NULL) {
00068         *pHr = E_OUTOFMEMORY;
00069     }
00070     return pNewObject;
00071 } 
00072 
00073 //COM Interface query function
00074 STDMETHODIMP OggDemuxSourceFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00075 {
00076         if (riid == IID_IFileSourceFilter) {
00077                 *ppv = (IFileSourceFilter*)this;
00078                 ((IUnknown*)*ppv)->AddRef();
00079                 return NOERROR;
00080         /*} else if (riid == IID_IMediaSeeking) {
00081                 *ppv = (IMediaSeeking*)this;
00082                 ((IUnknown*)*ppv)->AddRef();
00083                 return NOERROR;*/
00084         } else if (riid == IID_ISpecifyPropertyPages) {
00085                 *ppv = (ISpecifyPropertyPages*)this;
00086                 ((IUnknown*)*ppv)->AddRef();
00087                 return NOERROR;
00088         }  else if (riid == IID_IAMFilterMiscFlags) {
00089                 *ppv = (IAMFilterMiscFlags*)this;
00090                 ((IUnknown*)*ppv)->AddRef();
00091                 return NOERROR;
00092         } else if (riid == IID_IAMMediaContent) {
00093                 //debugLog<<"Queries for IAMMediaContent///"<<endl;
00094                 *ppv = (IAMMediaContent*)this;
00095                 ((IUnknown*)*ppv)->AddRef();
00096                 return NOERROR;
00097         }
00098 
00099         return CBaseFilter::NonDelegatingQueryInterface(riid, ppv); 
00100 }
00101 
00102 
00103 //------------------
00104 
00105 //ANX::: This needs to be changed so these details are passed into the constructor. Or add another parametised constructo
00106 OggDemuxSourceFilter::OggDemuxSourceFilter()
00107         :       CBaseFilter(NAME("OggDemuxSourceFilter"), NULL, m_pLock, CLSID_OggDemuxSourceFilter)
00108         
00109         ,       mSeekTable(NULL)
00110         ,       mDataSource(NULL)
00111         ,       mSeekTimeBase(0)
00112         ,       mJustReset(true)
00113 {
00114         //LEAK CHECK:::Both get deleted in constructor.
00115         m_pLock = new CCritSec;
00116         mSourceFileLock = new CCritSec;
00117         mDemuxLock = new CCritSec;
00118         mStreamLock = new CCritSec;
00119         mStreamMapper = new OggStreamMapper(this);
00120 
00121 #ifdef OGGCODECS_LOGGING
00122         debugLog.open("d:\\zen\\logs\\sourcelog.log", ios_base::out);
00123 #endif
00124 
00125 }
00126 
00127 //Perhaps also pass in the name field.
00128 OggDemuxSourceFilter::OggDemuxSourceFilter(REFCLSID inFilterGUID)
00129         :       CBaseFilter(NAME("OggDemuxSourceFilter"), NULL, m_pLock, inFilterGUID)
00130         ,       mSeekTable(NULL)
00131         ,       mStreamMapper(NULL)
00132         ,       mSeekTimeBase(0)
00133         ,       mJustReset(true)
00134 {
00135         //LEAK CHECK:::Both get deleted in constructor.
00136         m_pLock = new CCritSec;
00137         mSourceFileLock = new CCritSec;
00138         mDemuxLock = new CCritSec;
00139         mStreamLock = new CCritSec;
00140 #ifdef OGGCODECS_LOGGING
00141         debugLog.open("d:\\zen\\logs\\anx_base_sourcelog.log", ios_base::out);
00142 #endif
00143 
00144         //When it is derived, it's up to the superclass to set this.
00145         //mStreamMapper = new OggStreamMapper(this);
00146 
00147 }
00148 
00149 OggDemuxSourceFilter::~OggDemuxSourceFilter(void)
00150 {
00151         //TODO::: For some reason, you can't delete these !!
00152 
00153         //Clean up all our stuff...
00154         //delete m_pLock;
00155         //delete mStreamLock;
00156         //delete mSourceFileLock;
00157         //delete mDemuxLock;
00158         //debugLog<<"Deleting Data Source : "<<(int)mDataSource<<endl;
00159 
00160         //Close down the data source and delete it
00161 
00162         if (mDataSource != NULL) {
00163                 mDataSource->close();
00164         }
00165         delete mDataSource;
00166 
00167         debugLog.close();
00168         
00169         //Selete the stream mapper
00170         delete mStreamMapper;
00171         mStreamMapper = NULL;
00172 
00173         //Shut down the thread
00174         if (ThreadExists() == TRUE) {
00175                 //DbgLog((LOG_ERROR, 1, TEXT("******** Thread exists - closing *****")));
00176                 Close();
00177         }
00178         //Delete the seektable
00179         delete mSeekTable;
00180         mSeekTable = NULL;
00181 }
00182 
00183 //IAMFilterMiscFlags Interface
00184 ULONG OggDemuxSourceFilter::GetMiscFlags(void) 
00185 {
00186         return AM_FILTER_MISC_FLAGS_IS_SOURCE;
00187 }
00188 //ISpecifyPropertyPgaes Interface
00189 STDMETHODIMP OggDemuxSourceFilter::GetPages(CAUUID* outPropPages) 
00190 {
00191         //This function is to display a property page in graphedit.
00192         if (outPropPages == NULL) return E_POINTER;
00193 
00194         const int NUM_PROP_PAGES = 1;
00195     outPropPages->cElems = NUM_PROP_PAGES;
00196     outPropPages->pElems = (GUID*)(CoTaskMemAlloc(sizeof(GUID) * NUM_PROP_PAGES));
00197     if (outPropPages->pElems == NULL) 
00198     {
00199         return E_OUTOFMEMORY;
00200     }
00201 
00202         outPropPages->pElems[0] = CLSID_PropsAbout;
00203     
00204     return S_OK;
00205 
00206 }
00207 
00208         //IFileSource Interface
00209 STDMETHODIMP OggDemuxSourceFilter::GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType) 
00210 {
00211         //Return the filename and mediatype of the raw data
00212         LPOLESTR x = SysAllocString(mFileName.c_str());
00213         *outFileName = x;
00214         
00215         return S_OK;
00216 }
00217 
00218 
00219 STDMETHODIMP OggDemuxSourceFilter::Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType) 
00220 {
00221         //Initialise the file here and setup all the streams
00222         CAutoLock locLock(m_pLock);
00223         mFileName = inFileName;
00224 
00225         debugLog<<"Loading : "<<StringHelper::toNarrowStr(mFileName)<<endl;
00226 
00227         debugLog << "Opening source file : "<<StringHelper::toNarrowStr(mFileName)<<endl;
00228         mSeekTable = new AutoOggSeekTable(StringHelper::toNarrowStr(mFileName));
00229         mSeekTable->buildTable();
00230         
00231         return SetUpPins();
00232 }
00233 
00234 STDMETHODIMP OggDemuxSourceFilter::GetCapabilities(DWORD* inCapabilities) 
00235 {
00236         if (mSeekTable->enabled())  {
00237                 //debugLog<<"GetCaps "<<mSeekingCap<<endl;
00238                 *inCapabilities = mSeekingCap;
00239                 return S_OK;
00240         } else {
00241                 //debugLog<<"Get Caps failed !!!!!!!"<<endl;
00242                 *inCapabilities = 0;
00243                 return S_OK;;
00244         }
00245 }
00246 STDMETHODIMP OggDemuxSourceFilter::GetDuration(LONGLONG* outDuration) 
00247 {
00248         if (mSeekTable->enabled())  {
00249                 //debugLog<<"GetDuration = " << mSeekTable->fileDuration()<<" ds units"<<endl;
00250                 *outDuration = mSeekTable->fileDuration();
00251                 return S_OK;
00252         } else {
00253                 return E_NOTIMPL;
00254         }
00255 
00256 }
00257          
00258 STDMETHODIMP OggDemuxSourceFilter::CheckCapabilities(DWORD *pCapabilities)
00259 {
00260         //debugLog<<"CheckCaps  : Not impl"<<endl;
00261         return E_NOTIMPL;
00262 }
00263 STDMETHODIMP OggDemuxSourceFilter::IsFormatSupported(const GUID *pFormat)
00264 {
00265         ASSERT(pFormat != NULL);
00266         if (*pFormat == TIME_FORMAT_MEDIA_TIME) {
00267                 //debugLog<<"IsFormatSupported  : TRUE"<<endl;
00268                 return S_OK;
00269         } else {
00270                 //debugLog<<"IsFormatSupported  : FALSE !!!"<<endl;
00271                 return S_FALSE;
00272         }
00273         
00274         
00275 }
00276 STDMETHODIMP OggDemuxSourceFilter::QueryPreferredFormat(GUID *pFormat){
00277         //debugLog<<"QueryPrefferedTimeFormat   : MEDIA TIME"<<endl;
00278         *pFormat = TIME_FORMAT_MEDIA_TIME;
00279         return S_OK;
00280 }
00281 STDMETHODIMP OggDemuxSourceFilter::SetTimeFormat(const GUID *pFormat){
00282         //debugLog<<"SetTimeForamt : NOT IMPL"<<endl;
00283         return E_NOTIMPL;
00284 }
00285 STDMETHODIMP OggDemuxSourceFilter::GetTimeFormat( GUID *pFormat){
00286         *pFormat = TIME_FORMAT_MEDIA_TIME;
00287         return S_OK;
00288 }
00289 STDMETHODIMP OggDemuxSourceFilter::GetStopPosition(LONGLONG *pStop){
00290         if (mSeekTable->enabled())  {
00291 
00292                 //debugLog<<"GetStopPos = " << mSeekTable->fileDuration()<<" ds units"<<endl;
00293                 *pStop = mSeekTable->fileDuration();
00294                 return S_OK;
00295         } else {
00296                 //debugLog<<"GetStopPos NOT IMPL"<<endl;
00297                 return E_NOTIMPL;
00298         }
00299 }
00300 STDMETHODIMP OggDemuxSourceFilter::GetCurrentPosition(LONGLONG *pCurrent)
00301 {
00302         //TODO::: Implement this properly
00303 
00304         //debugLog<<"GetCurrentPos = NOT_IMPL"<<endl;
00305         return E_NOTIMPL;
00306 }
00307 STDMETHODIMP OggDemuxSourceFilter::ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat){
00308         //debugLog<<"ConvertTimeForamt : NOT IMPL"<<endl;
00309         return E_NOTIMPL;
00310 }
00311 STDMETHODIMP OggDemuxSourceFilter::SetPositions(LONGLONG *pCurrent,DWORD dwCurrentFlags,LONGLONG *pStop,DWORD dwStopFlags){
00312 
00313 
00314         CAutoLock locLock(m_pLock);
00315         //debugLog<<"Set Positions "<<*pCurrent<<" to "<<*pStop<<" with flags "<<dwCurrentFlags<<" and "<<dwStopFlags<<endl;
00316         if (mSeekTable->enabled())  {
00317                 //debugLog<<"SetPos : Current = "<<*pCurrent<<" Flags = "<<dwCurrentFlags<<" Stop = "<<*pStop<<" dwStopFlags = "<<dwStopFlags<<endl;
00318                 //debugLog<<"       : Delivering begin flush..."<<endl;
00319 
00320         
00321                 CAutoLock locSourceLock(mSourceFileLock);
00322                 mSetIgnorePackets = false;
00323                 DeliverBeginFlush();
00324                 //debugLog<<"       : Begin flush Delviered."<<endl;
00325 
00326                 //Find the byte position for this time.
00327                 OggSeekTable::tSeekPair locStartPos = mSeekTable->getStartPos(*pCurrent);
00328                 bool locSendExcess = false;
00329 
00330                 //FIX::: This code needs to be removed, and handle start seek case.
00331                 //.second is the file position.
00332                 //.first is the time in DS units
00333                 if (locStartPos.second == mStreamMapper->startOfData()) {
00334                         locSendExcess = true;
00335                         //GGFF:::
00336                         //mStreamMapper->toStartOfData();
00337                         mSetIgnorePackets = true;
00338                 }
00339                 
00340                 
00341                 //We have to save this here now... since time can't be reverted to granule pos in all cases
00342                 // we have to use granule pos timestamps in order for downstream codecs to work.
00343                 // Because of this we can't factor time bases after seeking into the sample times.
00344                 *pCurrent       = mSeekTimeBase 
00345                                         = locStartPos.first;            //Time from seek pair.
00346 
00347                 //debugLog<<"Corrected pCurrent : "<<mSeekTimeBase<<endl;
00348                 for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00349                         mStreamMapper->getOggStream(i)->setSendExcess(locSendExcess);           //Not needed
00350                         mStreamMapper->getOggStream(i)->setLastEndGranPos(*pCurrent);
00351                 }
00352                 {
00353                         //debugLog<<"       : Delivering End Flush..."<<endl;
00354                         DeliverEndFlush();
00355                         //debugLog<<"       : End flush Delviered."<<endl;
00356                         DeliverNewSegment(*pCurrent, mSeekTable->fileDuration(), 1.0);
00357                 }
00358 
00359                 //.second is the file position.
00360                 mDataSource->seek(locStartPos.second);
00361         
00362                 //debugLog<<"       : Seek complete."<<endl;
00363         } else {
00364                 //debugLog<<"Seek not IMPL"<<endl;
00365                 return E_NOTIMPL;
00366         }
00367 
00368         return S_OK;
00369 }
00370 STDMETHODIMP OggDemuxSourceFilter::GetPositions(LONGLONG *pCurrent, LONGLONG *pStop)
00371 {
00372         //debugLog<<"Getpos : Not IMPL"<<endl;
00373         //debugLog<<"GetPos : Current = HARDCODED 2 secs , Stop = "<<mSeekTable->fileDuration()/UNITS <<" secs."<<endl;
00374         return E_NOTIMPL;
00375 }
00376 STDMETHODIMP OggDemuxSourceFilter::GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest){
00377         //debugLog<<"****GetAvailable : NOT IMPL"<<endl;
00378         if (mSeekTable->enabled())  {
00379                 //debugLog<<"Get Avail ok"<<endl;
00380                 *pEarliest = 0;
00381                 //debugLog<<"+++++ Duration is "<<mSeekTable->fileDuration()<<endl;
00382                 *pLatest = mSeekTable->fileDuration();
00383                 return S_OK;
00384         } else {
00385                 return E_NOTIMPL;
00386         }
00387 }
00388 STDMETHODIMP OggDemuxSourceFilter::SetRate(double dRate)
00389 {
00390         //debugLog<<"Set RATE : NOT IMPL"<<endl;
00391         return E_NOTIMPL;
00392 }
00393 STDMETHODIMP OggDemuxSourceFilter::GetRate(double *dRate)
00394 {
00395 
00396         *dRate = 1.0;
00397         return S_OK;;
00398 }
00399 STDMETHODIMP OggDemuxSourceFilter::GetPreroll(LONGLONG *pllPreroll)
00400 {
00401 
00402         *pllPreroll = 0;
00403         //debugLog<<"GetPreroll : HARD CODED TO 0"<<endl;
00404         return S_OK;
00405 }
00406 STDMETHODIMP OggDemuxSourceFilter::IsUsingTimeFormat(const GUID *pFormat){
00407         if (*pFormat == TIME_FORMAT_MEDIA_TIME) {
00408                 //debugLog<<"IsUsingTimeFormat : MEDIA TIME TRUE"<<endl;
00409                 return S_OK;
00410         } else {
00411                 //debugLog<<"IsUsingTimeFormat : MEDIA TIME FALSE !!!!"<<endl;
00412                 return S_FALSE;
00413         }
00414 }
00415 
00416 
00417 //BaseFilter Interface
00418 int OggDemuxSourceFilter::GetPinCount() 
00419 {
00420         return mStreamMapper->numStreams();
00421 }
00422 CBasePin* OggDemuxSourceFilter::GetPin(int inPinNo) 
00423 {
00424         //The cast in thesecond condition removes a warning C4018 signed/unsigned mismatch.
00425         // Since the first condition would short circuit if inPinNo was < 0, the cast is safe.
00426         if ((inPinNo >= 0) && ((unsigned long)inPinNo < mStreamMapper->numStreams())) {
00427                 return mStreamMapper->getOggStream(inPinNo)->getPin();
00428         } else {
00429                 return NULL;
00430         }
00431 }
00432 
00433 //CAMThread Stuff
00434 DWORD OggDemuxSourceFilter::ThreadProc(void) {
00435         //debugLog << "Thread Proc Called..."<<endl;
00436         while(true) {
00437                 DWORD locThreadCommand = GetRequest();
00438                 //debugLog << "Command = "<<locThreadCommand<<endl;
00439                 switch(locThreadCommand) {
00440                         case THREAD_EXIT:
00441                                 //debugLog << "EXIT ** "<<endl;
00442                                 Reply(S_OK);
00443                                 return S_OK;
00444 
00445                         case THREAD_RUN:
00446                                 //debugLog << "RUN ** "<<endl;
00447                                 Reply(S_OK);
00448                                 DataProcessLoop();
00449                                 break;
00450                 }
00451         }
00452         return S_OK;
00453 }
00454 
00455 //Helper methods
00456 
00457 void OggDemuxSourceFilter::resetStream() {
00458         {
00459                 debugLog<<"Reset stream pre-lock"<<endl;
00460                 CAutoLock locDemuxLock(mDemuxLock);
00461                 CAutoLock locSourceLock(mSourceFileLock);
00462                 debugLog<<"RestStream post-lock"<<endl;
00463 
00464                 //Close up the data source
00465                 mDataSource->clear();
00466 
00467                 debugLog<<"Pre close"<<endl;
00468                 mDataSource->close();
00469                 debugLog<<"Post close"<<endl;
00470 
00471                 //After closing kill the interface
00472                 delete mDataSource;
00473                 mDataSource = NULL;
00474                 
00475 
00476                 //Clearing the data out of the demuxer
00477                 //mOggBuffer.debugWrite("%%%%%% Clear calling from ResetStream");
00478                 mOggBuffer.clearData();
00479 
00480                 //Before opening make the interface
00481                 mDataSource = DataSourceFactory::createDataSource(StringHelper::toNarrowStr(mFileName).c_str());
00482 
00483                 debugLog<<"Pre open"<<endl;
00484                 mDataSource->open(StringHelper::toNarrowStr(mFileName).c_str());
00485                 debugLog<<"Post open"<<endl;
00486                 mDataSource->seek(mStreamMapper->startOfData());   //Should always be zero for now.
00487 
00488                 //TODO::: Should be doing stuff with the demux state here ? or packetiser ?>?
00489                 
00490                 mJustReset = true;   //TODO::: Look into this !
00491         }
00492 
00493         for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00494                 mStreamMapper->getOggStream(i)->setSendExcess(true);    
00495         }
00496 }
00497 
00498 void OggDemuxSourceFilter::DeliverBeginFlush() 
00499 {
00500         CAutoLock locLock(m_pLock);
00501         
00502         debugLog << "Delivering Begin Flush"<<endl;
00503         for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00504                 mStreamMapper->getOggStream(i)->getPin()->DeliverBeginFlush();
00505                 //mStreamMapper->getOggStream(i)->flush();
00506         }
00507 
00508         //Should this be here or endflush or neither ?
00509         //mOggBuffer.debugWrite("%%%%%% Reset calling from DeliverBegingFlush");
00510         debugLog<<"Calling reset stream from begin flush"<<endl;
00511         resetStream();
00512 }
00513 
00514 void OggDemuxSourceFilter::DeliverEndFlush() 
00515 {
00516         CAutoLock locLock(m_pLock);
00517         debugLog << "Delivering End Flush"<<endl;
00518         if (mSetIgnorePackets == true) {
00519                 mStreamMapper->toStartOfData();
00520                 for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00521                         //mStreamMapper->getOggStream(i)->flush();
00522                         mStreamMapper->getOggStream(i)->getPin()->DeliverEndFlush();
00523                 }
00524 
00525         } else {
00526         
00527                 for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00528                         mStreamMapper->getOggStream(i)->flush();
00529                         mStreamMapper->getOggStream(i)->getPin()->DeliverEndFlush();
00530                 }
00531         }
00532         mSetIgnorePackets = false;
00533 }
00534 void OggDemuxSourceFilter::DeliverEOS() 
00535 {
00536         mStreamMapper->toStartOfData();
00537         for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00538                 //mStreamMapper->getOggStream(i)->flush();
00539                 mStreamMapper->getOggStream(i)->getPin()->DeliverEndOfStream();
00540                 
00541         }
00542         //mOggBuffer.debugWrite("%%%%%% Reset calling from DeliverEOS");
00543         debugLog<<"Calling reset stream from DeliverEOS"<<endl;
00544         resetStream();
00545 }
00546 
00547 void OggDemuxSourceFilter::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) 
00548 {
00549         debugLog<<"DeliverNewSegment : Delivering start = "<<tStart<<" end = "<< tStop<<"rate = "<<dRate<<endl;
00550         
00551         for (unsigned long i = 0; i < mStreamMapper->numStreams(); i++) {
00552                 mStreamMapper->getOggStream(i)->getPin()->DeliverNewSegment(tStart, tStop, dRate);
00553         }
00554 }
00555 HRESULT OggDemuxSourceFilter::DataProcessLoop() 
00556 {
00557         //Mess with the locking mechanisms at your own risk.
00558 
00559         //debugLog<<"Starting DataProcessLoop :"<<endl;
00560         DWORD locCommand = 0;
00561         char* locBuff = new  char[4096];                        //Deleted before function returns...
00562         //TODO::: Make this a member variable ^^^^^
00563         bool locKeepGoing = true;
00564         unsigned long locBytesRead = 0;
00565         bool locIsEOF = true;
00566         {
00567                 CAutoLock locSourceLock(mSourceFileLock);
00568                 locIsEOF = mDataSource->isEOF();
00569         }
00570 
00571         while(true) {
00572                 if(CheckRequest(&locCommand) == TRUE) {
00573                         //debugLog<<"DataProcessLoop : Thread Command issued... leaving loop."<<endl;
00574                         delete[] locBuff;
00575                         return S_OK;
00576                 }
00577                 //debugLog<<"Looping..."<<endl;
00578                 {
00579                         CAutoLock locSourceLock(mSourceFileLock);
00580 
00581                         locBytesRead = mDataSource->read(locBuff, 4096);
00582                         mJustReset = false;
00583                 }
00584                 //debugLog <<"DataProcessLoop : gcount = "<<locBytesRead<<endl;
00585                 {
00586                         CAutoLock locDemuxLock(mDemuxLock);
00587                         //CAutoLock locStreamLock(mStreamLock);
00588                         if (mJustReset) {               //To avoid blocking problems... restart the loop if it was just reset while waiting for lock.
00589                                 continue;
00590                         }
00591                         locKeepGoing = ((mOggBuffer.feed((const unsigned char*)locBuff, locBytesRead)) == (OggDataBuffer::FEED_OK));;
00592                 }
00593                 if (!locKeepGoing) {
00594                         //debugLog << "DataProcessLoop : Feed in data buffer said stop"<<endl;
00595                         //debugLog<<"DataProcessLoop : Exiting. Deliver EOS"<<endl;
00596                         DeliverEOS();
00597                 }
00598                 {
00599                         CAutoLock locSourceLock(mSourceFileLock);
00600                         locIsEOF = mDataSource->isEOF();
00601                 }
00602                 if (locIsEOF) {
00603                         //debugLog << "DataProcessLoop : EOF"<<endl;
00604                         //debugLog<<"DataProcessLoop : Exiting. Deliver EOS"<<endl;
00605                         DeliverEOS();
00606                 }
00607         }
00608 
00609         //debugLog<<"DataProcessLoop : Exiting. Deliver EOS"<<endl;
00610 
00611         //Shuold we flush ehre ?
00612         delete[] locBuff;
00613         
00614         //return value ??
00615         return S_OK;
00616 }
00617 
00618 
00619 HRESULT OggDemuxSourceFilter::SetUpPins() 
00620 {
00621         CAutoLock locDemuxLock(mDemuxLock);
00622         CAutoLock locSourceLock(mSourceFileLock);
00623         
00624         unsigned short locRetryCount = 0;
00625         const unsigned short RETRY_THRESHOLD = 3;
00626         debugLog<<"SETUP PINS"<<endl;
00627         //Create and open a data source
00628         mDataSource = DataSourceFactory::createDataSource(StringHelper::toNarrowStr(mFileName).c_str());
00629         mDataSource->open(StringHelper::toNarrowStr(mFileName).c_str());
00630         
00631         //Error check
00632         
00633         //Register a callback
00634         mOggBuffer.registerVirtualCallback(this);
00635 
00636         char* locBuff = new char[RAW_BUFFER_SIZE];
00637         unsigned long locNumRead = 0;
00638 
00639         //Feed the data in until we have seen all BOS pages.
00640         while(!mStreamMapper->isReady()) {
00641         
00642                 locNumRead = mDataSource->read(locBuff, RAW_BUFFER_SIZE);
00643         
00644                 if (locNumRead > 0) {
00645                         mOggBuffer.feed((const unsigned char*)locBuff, locNumRead);
00646                 }
00647 
00648                 if (mDataSource->isEOF() || mDataSource->isError()) {
00649                         if (mDataSource->isError() && (mDataSource->shouldRetryAt() != "") && (locRetryCount < RETRY_THRESHOLD)) {
00650                                 mOggBuffer.clearData();
00651                                 string locNewLocation = mDataSource->shouldRetryAt();
00652                                 debugLog<<"Retrying at : "<<locNewLocation<<endl;
00653                                 delete mDataSource;
00654                                 mDataSource = DataSourceFactory::createDataSource(locNewLocation.c_str());
00655                                 mDataSource->open(locNewLocation.c_str());
00656                                 locRetryCount++;
00657                         } else {
00658                                 debugLog<<"Bailing out"<<endl;
00659                                 return VFW_E_CANNOT_RENDER;
00660                         }
00661                 }
00662         }
00663         
00664         mStreamMapper->setAllowDispatch(true);
00665         mStreamMapper->toStartOfData();                 //Flushes all streams and sets them to ignore the right number of headers.
00666         mOggBuffer.clearData();
00667         mDataSource->seek(0);                   //TODO::: This is bad for streams.
00668 
00669         //debugLog<<"COMPLETED SETUP"<<endl;
00670         delete[] locBuff;
00671         return S_OK;
00672 }
00673 //IOggCallback Interface
00674 
00675 bool OggDemuxSourceFilter::acceptOggPage(OggPage* inOggPage)    //Gives away page.
00676 {               
00677         return mStreamMapper->acceptOggPage(inOggPage);
00678 }
00679 
00680 //IMEdiaStreaming
00681 STDMETHODIMP OggDemuxSourceFilter::Run(REFERENCE_TIME tStart) 
00682 {
00683         const REFERENCE_TIME A_LONG_TIME = UNITS * 1000;
00684         CAutoLock locLock(m_pLock);
00685         debugLog<<"Run  :  time = "<<tStart<<endl;
00686         //DeliverNewSegment(tStart, tStart + A_LONG_TIME, 1.0);
00687         return CBaseFilter::Run(tStart);
00688         
00689 
00690 }
00691 STDMETHODIMP OggDemuxSourceFilter::Pause(void) 
00692 {
00693         CAutoLock locLock(m_pLock);
00694         debugLog << "** Pause called **"<<endl;
00695         if (m_State == State_Stopped) {
00696                 //debugLog << "Was in stopped state... starting thread"<<endl;
00697                 if (ThreadExists() == FALSE) {
00698                         Create();
00699                 }
00700                 CallWorker(THREAD_RUN);
00701         }
00702         //debugLog<<"Was NOT is stopped state, not doing much at all..."<<endl;
00703         
00704         HRESULT locHR = CBaseFilter::Pause();
00705         
00706         return locHR;
00707         
00708 }
00709 STDMETHODIMP OggDemuxSourceFilter::Stop(void) 
00710 {
00711         CAutoLock locLock(m_pLock);
00712         debugLog<<"** Stop Called ** "<<endl;
00713         CallWorker(THREAD_EXIT);
00714         Close();
00715         DeliverBeginFlush();
00716         mSetIgnorePackets = true;
00717         DeliverEndFlush();
00718         
00719         return CBaseFilter::Stop();
00720 }
00721 
00722 CCritSec* OggDemuxSourceFilter::theLock() 
00723 {
00724         return m_pLock;
00725 }
00726 
00727 
00728 //IAMMediaContent Interface
00729 STDMETHODIMP  OggDemuxSourceFilter::get_AuthorName(BSTR* outAuthorName) { 
00730         return E_NOTIMPL;
00731 }
00732 STDMETHODIMP  OggDemuxSourceFilter::get_Title(BSTR* outTitle) { 
00733         //debugLog<<"Try to get_Title"<<endl;
00734         return E_NOTIMPL;
00735 }
00736 STDMETHODIMP  OggDemuxSourceFilter::get_Rating(BSTR* outRating) { 
00737         return E_NOTIMPL;
00738 }
00739 STDMETHODIMP  OggDemuxSourceFilter::get_Description(BSTR* outDescription) { 
00740         return E_NOTIMPL;
00741 }
00742 STDMETHODIMP  OggDemuxSourceFilter::get_Copyright(BSTR* outCopyright) { 
00743         return E_NOTIMPL;
00744 }
00745 STDMETHODIMP  OggDemuxSourceFilter::get_BaseURL(BSTR* outBaseURL) { 
00746         return E_NOTIMPL;
00747 }
00748 STDMETHODIMP  OggDemuxSourceFilter::get_LogoURL(BSTR* outLogoURL) { 
00749         return E_NOTIMPL;
00750 }
00751 STDMETHODIMP  OggDemuxSourceFilter::get_LogoIconURL(BSTR* outLogoIconURL) { 
00752         return E_NOTIMPL;
00753 }
00754 STDMETHODIMP  OggDemuxSourceFilter::get_WatermarkURL(BSTR* outWatermarkURL) { 
00755         return E_NOTIMPL;
00756 }
00757 STDMETHODIMP  OggDemuxSourceFilter::get_MoreInfoURL(BSTR* outMoreInfoURL) { 
00758         return E_NOTIMPL;
00759 }
00760 STDMETHODIMP  OggDemuxSourceFilter::get_MoreInfoBannerImage(BSTR* outMoreInfoBannerImage) { 
00761         return E_NOTIMPL;
00762 }
00763 STDMETHODIMP  OggDemuxSourceFilter::get_MoreInfoBannerURL(BSTR* outMoreInfoBannerURL) { 
00764         return E_NOTIMPL;
00765 }
00766 STDMETHODIMP  OggDemuxSourceFilter::get_MoreInfoText(BSTR* outMoreInfoText) { 
00767         return E_NOTIMPL;
00768 }
00769 
00770 //IDispatch Interface
00771 STDMETHODIMP OggDemuxSourceFilter::GetTypeInfoCount(    unsigned int FAR*  pctinfo ) {
00772         return E_NOTIMPL;
00773 
00774 }
00775 STDMETHODIMP OggDemuxSourceFilter::GetIDsOfNames(               REFIID  riid, 
00776                                                                 OLECHAR FAR* FAR* rgszNames, 
00777                                                                 unsigned int cNames, 
00778                                                                 LCID lcid, 
00779                                                                 DISPID FAR* rgDispId ) {
00780         return E_NOTIMPL;
00781                                                                 }
00782 STDMETHODIMP OggDemuxSourceFilter::GetTypeInfo(         unsigned int iTInfo, 
00783                                                                 LCID lcid, 
00784                                                                 ITypeInfo FAR* FAR*  ppTInfo ) {
00785         return E_NOTIMPL;
00786 }
00787 STDMETHODIMP OggDemuxSourceFilter::Invoke(                      DISPID  dispIdMember,
00788                                                                 REFIID  riid,
00789                                                                 LCID  lcid,
00790                                                                 WORD  wFlags,
00791                                                                 DISPPARAMS FAR*  pDispParams,  
00792                                                                 VARIANT FAR*  pVarResult,  
00793                                                                 EXCEPINFO FAR*  pExcepInfo,  
00794                                                                 unsigned int FAR*  puArgErr ) {
00795         return E_NOTIMPL;
00796 }

Generated on Thu Feb 16 23:48:13 2006 for oggdsf by  doxygen 1.3.9