[xiph-commits] r10282 -
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek
illiminable at svn.xiph.org
illiminable at svn.xiph.org
Mon Oct 24 04:20:08 PDT 2005
Author: illiminable
Date: 2005-10-24 04:19:57 -0700 (Mon, 24 Oct 2005)
New Revision: 10282
Added:
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/IOggDecoderSeek.h
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.cpp
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.h
Modified:
branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/libOOOggSeek.vcproj
Log:
* New seek table, allows seeking over all streams, rather than just the primary stream as was previously the case.
* Seek table will find the minimum starting point to make a seek valid for all streams
* Lets codecs specify preroll, or keyframe rollback required to correctly display requested data.
Added: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp 2005-10-24 11:19:57 UTC (rev 10282)
@@ -0,0 +1,130 @@
+#include "StdAfx.h"
+#include ".\autooggchaingranuleseektable.h"
+
+AutoOggChainGranuleSeekTable::AutoOggChainGranuleSeekTable(string inFilename)
+ : mFilename(inFilename)
+ , mFilePos(0)
+ , mOggDemux(NULL)
+{
+ mOggDemux = new OggDataBuffer;
+
+}
+
+AutoOggChainGranuleSeekTable::~AutoOggChainGranuleSeekTable(void)
+{
+ delete mOggDemux;
+
+ for (size_t i = 0; i < mStreamMaps.size(); i++) {
+ delete mStreamMaps[i].mSeekTable;
+ }
+}
+
+
+bool AutoOggChainGranuleSeekTable::buildTable()
+{
+ if (mFilename.find("http") != 0) {
+
+ //mSeekMap.clear();
+ //addSeekPoint(0, 0);
+
+ mFile.open(mFilename.c_str(), ios_base::in | ios_base::binary);
+ //TODO::: Error check
+ const unsigned long BUFF_SIZE = 4096;
+ unsigned char* locBuff = new unsigned char[BUFF_SIZE]; //Deleted this function.
+ while (!mFile.eof()) {
+ mFile.read((char*)locBuff, BUFF_SIZE);
+ mOggDemux->feed((const unsigned char*)locBuff, mFile.gcount());
+ }
+ delete[] locBuff;
+
+ mFile.close();
+
+ }
+ return true;
+}
+unsigned long AutoOggChainGranuleSeekTable::seekPos(LOOG_INT64 inTime)
+{
+ unsigned long retEarliestPos = 4294967295UL;
+
+ LOOG_INT64 locStreamTime = -1;
+ bool locGotAValidPos = false;
+
+
+ OggGranuleSeekTable::tSeekPair locSeekInfo;
+ for (size_t i = 0; i < mStreamMaps.size(); i++) {
+
+ if ((mStreamMaps[i].mSeekTable != NULL) && (mStreamMaps[i].mSeekInterface != NULL)) {
+ //Get the preliminary seek info
+ locSeekInfo = mStreamMaps[i].mSeekTable->getStartPos(inTime);
+ //1. Get the granule pos in the preliminary seek
+ //2. Ask the seek interface what granule we must seek before to make this a valid seek
+ // ie if preroll or keyframes, this value must be less than the original seek value
+ //3. Convert the new granule to time
+ //4. Repeat the seek
+ locStreamTime = mStreamMaps[i].mSeekInterface->convertGranuleToTime(mStreamMaps[i].mSeekInterface->mustSeekBefore(locSeekInfo.second.second));
+ locSeekInfo = mStreamMaps[i].mSeekTable->getStartPos(locStreamTime);
+
+ if (retEarliestPos >= locSeekInfo.second.first) {
+ //Update the earliest position
+ retEarliestPos = locSeekInfo.second.first;
+ locGotAValidPos = true;
+ }
+ }
+ }
+
+ return retEarliestPos;
+
+}
+
+bool AutoOggChainGranuleSeekTable::acceptOggPage(OggPage* inOggPage)
+{
+ LOOG_INT64 locGranule = inOggPage->header()->GranulePos();
+ unsigned long locSerialNo = inOggPage->header()->StreamSerialNo();
+ sStreamMapping locMapping = getMapping(locSerialNo);
+
+ //Exclude pages, with -1 granule pos, or that have only 1 packet and that packet is incomplete
+ if ((locGranule != -1) && (!((inOggPage->numPackets() <= 1) && (inOggPage->header()->isContinuation())))) {
+ LOOG_INT64 locRealTime = -1;
+ if ((locMapping.mSeekInterface != NULL) && (locMapping.mSeekTable != NULL)) {
+ //There is valid stream info
+ locRealTime = locMapping.mSeekInterface->convertGranuleToTime(locGranule);
+ if (locRealTime >= 0) {
+ locMapping.mSeekTable->addSeekPoint(locRealTime, mFilePos, locGranule);
+ }
+ }
+ }
+ mFilePos += inOggPage->pageSize();
+
+ delete inOggPage;
+ return true;
+}
+AutoOggChainGranuleSeekTable::sStreamMapping AutoOggChainGranuleSeekTable::getMapping(unsigned long inSerialNo)
+{
+ for (size_t i = 0; i < mStreamMaps.size(); i++) {
+ if (mStreamMaps[i].mSerialNo == inSerialNo) {
+ return mStreamMaps[i];
+ }
+ }
+
+ sStreamMapping retMapping;
+ retMapping.mSeekInterface = NULL;
+ retMapping.mSeekTable = NULL;
+ retMapping.mSerialNo = 0;
+
+ return retMapping;
+}
+bool AutoOggChainGranuleSeekTable::addStream(unsigned long inSerialNo, IOggDecoderSeek* inSeekInterface)
+{
+ sStreamMapping locMapping;
+ locMapping.mSerialNo = inSerialNo;
+ locMapping.mSeekInterface = inSeekInterface;
+ if (inSeekInterface == NULL) {
+ locMapping.mSeekTable = NULL;
+ } else {
+ locMapping.mSeekTable = new OggGranuleSeekTable;
+ }
+ mStreamMaps.push_back(locMapping);
+
+ return true;
+
+}
\ No newline at end of file
Added: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h 2005-10-24 11:19:57 UTC (rev 10282)
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <libOOOgg/libOOOgg.h>
+#include "OggGranuleSeekTable.h"
+#include "IOggDecoderSeek.h"
+
+
+class AutoOggChainGranuleSeekTable
+ : public IOggCallback
+{
+public:
+ AutoOggChainGranuleSeekTable(string inFilename);
+ virtual ~AutoOggChainGranuleSeekTable(void);
+
+ /// Builds the actual seek table: only works if we have random access to the file.
+ virtual bool buildTable();
+
+ //IOggCallback interface
+ virtual bool acceptOggPage(OggPage* inOggPage);
+
+ /// The duration of the file, in DirectShow time units.
+ LOOG_INT64 fileDuration();
+
+ bool addStream(unsigned long inSerialNo, IOggDecoderSeek* inSeekInterface);
+
+ unsigned long seekPos(LOOG_INT64 inTime);
+protected:
+
+ struct sStreamMapping {
+ unsigned long mSerialNo;
+ IOggDecoderSeek* mSeekInterface;
+ OggGranuleSeekTable* mSeekTable;
+ };
+
+ vector<sStreamMapping> mStreamMaps;
+
+ sStreamMapping getMapping(unsigned long inSerialNo);
+ fstream mFile;
+ string mFilename;
+ unsigned long mFilePos;
+ OggDataBuffer* mOggDemux;
+};
Added: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/IOggDecoderSeek.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/IOggDecoderSeek.h 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/IOggDecoderSeek.h 2005-10-24 11:19:57 UTC (rev 10282)
@@ -0,0 +1,14 @@
+
+#pragma once
+
+class IOggDecoderSeek {
+public:
+ IOggDecoderSeek(void) {}
+ virtual ~IOggDecoderSeek(void) {}
+
+
+ virtual LOOG_INT64 convertGranuleToTime(LOOG_INT64 inGranule) = 0;
+ virtual LOOG_INT64 mustSeekBefore(LOOG_INT64 inGranule) = 0;
+
+
+};
Added: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.cpp 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.cpp 2005-10-24 11:19:57 UTC (rev 10282)
@@ -0,0 +1,89 @@
+//===========================================================================
+//Copyright (C) 2003, 2004, 2005 Zentaro Kavanagh
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+#include "stdafx.h"
+#include <libOOOggSeek/OggGranuleSeekTable.h>
+
+OggGranuleSeekTable::OggGranuleSeekTable(void)
+ : mEnabled(true)
+ , mRealStartPos(0)
+{
+ mSeekMap.clear();
+ mSeekMap.empty();
+ //stDebug.open("G:\\logs\\sktable.log", ios_base::out);
+}
+
+OggGranuleSeekTable::~OggGranuleSeekTable(void)
+{
+ //stDebug.close();
+}
+
+bool OggGranuleSeekTable::enabled() {
+ return mEnabled;
+}
+bool OggGranuleSeekTable::addSeekPoint(LOOG_INT64 inTime, unsigned long mStartPos, LOOG_INT64 inGranulePos)
+{
+ //stDebug<< "Add Point : Time = "<<inTime<<" -- Byte Pos : "<<mStartPos<<endl;
+ tGranulePair locPair;
+ locPair.first = mStartPos;
+ locPair.second = inGranulePos;
+
+ mSeekMap.insert(tSeekMap::value_type(inTime, locPair));
+
+ return true;
+
+}
+
+
+/** Returns a tSeekPair whose first element is the
+ actual closest possible time that can be seeked to (which will always be either before or at
+ the requested seek position). The second element is the number of bytes into the stream where
+ the first page of the actual seek time occurs.
+ */
+OggGranuleSeekTable::tSeekPair OggGranuleSeekTable::getStartPos(LOOG_INT64 inTime)
+{
+ // Finds the upper bound of the requested time in mSeekMap, which will always be in the range
+ // (0, maxItems], and return the element _before_ the upper bound
+ return *(--(mSeekMap.upper_bound(inTime)));
+ //mRealStartPos = locValue.first;
+ //stDebug<<"Get Point : Time Req = "<<inTime<<" -- Time Given = "<<mRealStartPos<<" -- Byte Pos : "<<locValue.second<<endl;
+ //return locValue.second;
+}
+
+/** Note that this method returns a copy of the seek table, not the actual seek table used by
+ the class. So, feel free to corrupt your copy to your heart's leisure.
+ */
+OggGranuleSeekTable::tSeekMap OggGranuleSeekTable::getSeekMap()
+{
+ tSeekMap locSeekMap = mSeekMap;
+
+ return locSeekMap;
+}
Added: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.h 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/OggGranuleSeekTable.h 2005-10-24 11:19:57 UTC (rev 10282)
@@ -0,0 +1,81 @@
+
+
+
+//===========================================================================
+//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+#pragma once
+
+#include <libilliCore/libilliCore.h>
+#include <libOOOggSeek/libOOOggSeek.h>
+
+#include <fstream>
+#include <map>
+
+using namespace std;
+
+class LIBOOOGGSEEK_API OggGranuleSeekTable
+{
+public:
+ OggGranuleSeekTable(void);
+ virtual ~OggGranuleSeekTable(void);
+
+ /// A Pair consitsing of a byte position and a granule pos
+ typedef pair<unsigned long, LOOG_INT64> tGranulePair;
+
+ /// A pair consiting of a real time, and a granule pair, making a triplet.
+ typedef pair<LOOG_INT64, tGranulePair> tSeekPair;
+ typedef map<LOOG_INT64, tGranulePair> tSeekMap;
+
+ /// Returns a copy of the seek table.
+ tSeekMap getSeekMap();
+
+ /// Add a seek point (which consists of a time in DirectShow units, and a byte offset corresponding to that time, and a granule pos) to the seek table.
+ bool addSeekPoint(LOOG_INT64 inTime, unsigned long mStartPos, LOOG_INT64 inGranulePos);
+
+ /// Given a requested seek time in DirectShow units, returns the closest time and byte to the seek time.
+ tSeekPair getStartPos(LOOG_INT64 inTime);
+
+ /// Returns whether this table is enabled or disabled.
+ bool enabled();
+
+protected:
+ tSeekMap mSeekMap;
+ tSeekMap::value_type mSeekValue;
+ LOOG_INT64 mRealStartPos;
+
+ //fstream stDebug;
+ bool mEnabled;
+
+private:
+ OggGranuleSeekTable(const OggGranuleSeekTable&); // Don't copy me
+ OggGranuleSeekTable &operator=(const OggGranuleSeekTable&); // Don't assign me
+};
Modified: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/libOOOggSeek.vcproj
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/libOOOggSeek.vcproj 2005-10-23 19:14:48 UTC (rev 10281)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/libOOOggSeek.vcproj 2005-10-24 11:19:57 UTC (rev 10282)
@@ -371,12 +371,18 @@
RelativePath=".\AutoAnxSeekTable.cpp">
</File>
<File
+ RelativePath=".\AutoOggChainGranuleSeekTable.cpp">
+ </File>
+ <File
RelativePath="AutoOggSeekTable.cpp">
</File>
<File
RelativePath="libOOOggSeek.cpp">
</File>
<File
+ RelativePath=".\OggGranuleSeekTable.cpp">
+ </File>
+ <File
RelativePath="OggSeekPoint.cpp">
</File>
<File
@@ -432,15 +438,24 @@
RelativePath=".\AutoAnxSeekTable.h">
</File>
<File
+ RelativePath=".\AutoOggChainGranuleSeekTable.h">
+ </File>
+ <File
RelativePath="AutoOggSeekTable.h">
</File>
<File
+ RelativePath=".\IOggDecoderSeek.h">
+ </File>
+ <File
RelativePath=".\IOggSeeker.h">
</File>
<File
RelativePath="libOOOggSeek.h">
</File>
<File
+ RelativePath=".\OggGranuleSeekTable.h">
+ </File>
+ <File
RelativePath="OggSeekPoint.h">
</File>
<File
More information about the commits
mailing list