[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