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

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