OggStreamMapper.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 "oggstreammapper.h"
00033 
00034 OggStreamMapper::OggStreamMapper(OggDemuxSourceFilter* inOwningFilter)
00035         :       mOwningFilter(inOwningFilter)
00036         ,       mDataStartsAt(0)
00037         
00038 {
00039 
00040 }
00041 
00042 OggStreamMapper::~OggStreamMapper(void)
00043 {
00044         for (size_t i = 0; i < mStreamList.size(); i++) {
00045                 //This is to deal with a circular reference. The pin has a ref on the filter and a filter one on the pin.
00046                 //If they are both allowed to normal reference count, neither are deleted and both are left with 1 ref each.
00047 
00048                 //If the pin just doesn't hold a ref on the filter, an infinite destruction loop occurs.
00049                 //So to combat this... the pin does not have a ref on the filter... the filter controls the pins lifetime.
00050                 // And when this destructor is called (which is in the destructor of the filter), we are just going to NULL
00051                 // out the seekdelegates pointer (which is a apointer to the filter)... since we don't hold a ref on the filter
00052                 // this isn't a leak.
00053                 mStreamList[i]->getPin()->SetDelegate(NULL);
00054                 delete mStreamList[i];
00055         }
00056         mStreamList.empty();
00057         mStreamList.clear();
00058 }
00059 
00060 //Sends the page to *only one* stream if it matches the serial number.
00061 bool OggStreamMapper::dispatchPage(OggPage* inOggPage)                          //Gives away or deletes page.
00062 {
00063         //debugLog<<"Dispatch page..."<<endl;
00064         for (unsigned long i = 0; i < mStreamList.size(); i++) {
00065                 if (mStreamList[i]->serialNo() == inOggPage->header()->StreamSerialNo()) {
00066                         //This is the correct stream
00067                         //DbgLog((LOG_TRACE, 2, TEXT("Mapper : Dispatching page to serial %u",inOggPage->header()->StreamSerialNo())));
00068                         //debugLog<<"Dispatch to stream "<<i<<endl;
00069                         return mStreamList[i]->acceptOggPage(inOggPage);                //Give away page.
00070                         
00071                 }
00072         }
00073         //debugLog<<"Shouldn't be here $$$$$$"<<endl;
00074 
00075         //::: CHAINING SUPPORT HACKED IN HERE !!!
00076         //===================================
00077         //We only get here if the serial number wasn't in a header... this means either
00078         // a) It's a chain, and we are going to hack around it
00079         // b) The file is invalid.
00080 
00081         //Only attempt a chain for a single stream (probably vorbis only)
00082         if (mStreamList.size() == 1) {
00083                 mStreamList[0]->setSerialNo(inOggPage->header()->StreamSerialNo());
00084                 return mStreamList[0]->acceptOggPage(inOggPage);                //Give away page.
00085         }
00086         //return false;
00087         delete inOggPage;                       //Delete page.
00088         return true;
00089 }
00090 
00091 unsigned long OggStreamMapper::startOfData() {
00092         return mDataStartsAt;
00093 }
00094 bool OggStreamMapper::acceptOggPage(OggPage* inOggPage)                 //Gives away page.
00095 {
00096         
00097         //FIXED::: Data starts a 0.
00098         //if(!isReady()) {
00099         //      mDataStartsAt += inOggPage->pageSize();
00100         //}
00101 
00102         if (!isReady() && inOggPage->header()->isBOS()) {
00103                 bool locAllowSeekThrough = false;
00104 
00105                 //We only want one of the pins to delegate their seek to us.
00106                 //if (mStreamList.size() == 0) {
00107                 //      locAllowSeekThrough = true;
00108                 //}
00109 
00110                 locAllowSeekThrough = true;
00111                 //Above code is changed... due to WMP9 and 10 's non-adherence to directshows standard... it
00112                 // requires all streams to be seekable, in contradiction to directshow which specifies that
00113                 // only 1 or more is required.
00114 
00115 
00116                         
00117                 //If the page is a BOS we need to start a new stream
00118                 OggStream* locStream = OggStreamFactory::CreateStream(inOggPage, mOwningFilter, locAllowSeekThrough);
00119                 //FIX::: Need to check for NULL
00120                 if (locStream != NULL) {
00121                         mStreamList.push_back(locStream);
00122                 }
00123                 return true;
00124                 //TODO::: Shuold verify the mapper doesn';t already have a stream with this number !
00125         } else {
00126                 return dispatchPage(inOggPage);                 //Gives away page.
00127         }
00128 }
00129 bool OggStreamMapper::toStartOfData() {
00130         if (isReady()) {  //CHECK::: Should check for allow dsipatch ???
00131                 for (unsigned long i = 0; i < mStreamList.size(); i++) {
00132                         //Flush each stream, then ignore the codec headers.
00133                         mStreamList[i]->flush((unsigned short)mStreamList[i]->numCodecHeaders());
00134                 }       
00135                 return true;
00136         } else {
00137                 return false;
00138         }
00139 }
00140 
00141 void OggStreamMapper::setAllowDispatch(bool inAllowDispatch) {
00142         //debugLog<<"Setting allow dispatch..."<<endl;
00143         for (unsigned long i = 0; i < mStreamList.size(); i++) {
00144                 mStreamList[i]->setAllowDispatch(inAllowDispatch);;
00145         }
00146 }
00147 bool OggStreamMapper::isReady() {
00148         bool retVal = true;
00149         bool locWasAny = false;
00150         for (unsigned long i = 0; i < mStreamList.size(); i++) {
00151                 locWasAny = true;
00152                 retVal = retVal && mStreamList[i]->streamReady();
00153         }
00154         return locWasAny && retVal;
00155 }
00156 
00157 unsigned long OggStreamMapper::numStreams() {
00158         return (unsigned long)mStreamList.size();
00159 }
00160 
00161 OggStream* OggStreamMapper::getOggStream(unsigned long inPinNo) {
00162         if (inPinNo < mStreamList.size()) {
00163                 return mStreamList[inPinNo];
00164         } else {
00165                 return NULL;
00166         }
00167         
00168 }

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