[xiph-commits] r10316 - in branches/oggdsf_new_demux/src/lib: codecs/theora/filters/dsfTheoraDecoder core/directshow/dsfOggDemux2 core/ogg/libOOOggSeek

illiminable at svn.xiph.org illiminable at svn.xiph.org
Tue Nov 1 04:22:43 PST 2005


Author: illiminable
Date: 2005-11-01 04:22:31 -0800 (Tue, 01 Nov 2005)
New Revision: 10316

Modified:
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeInputPin.cpp
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/OggDemuxPacketSourceFilter.cpp
   branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp
   branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h
Log:
* Almost page accurate seeking in theora... just need to stop the pre-keyframe packets that are on the same page as the keyframe getting forced through the renderer

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2005-11-01 12:22:31 UTC (rev 10316)
@@ -65,6 +65,10 @@
 	,	mBegun(false)
 	,	mSeekTimeBase(0)
 	,	mLastSeenStartGranPos(0)
+
+	,	mSegStart(0)
+	,	mSegEnd(0)
+	,	mPlaybackRate(0.0)
 	,	mTheoraFormatInfo(NULL)
 {
 #ifdef OGGCODECS_LOGGING
@@ -335,6 +339,9 @@
 {
 	debugLog<<"Resetting frame count"<<endl;
 	ResetFrameCount();
+	mSegStart = inStart;
+	mSegEnd = inEnd;
+	mPlaybackRate = inRate;
 	return CTransformFilter::NewSegment(inStart, inEnd, inRate);
 
 }
@@ -410,8 +417,8 @@
 
 					//REFERENCE_TIME locAdjustedStart = (locStart * RATE_DENOMINATOR) / mRateNumerator;
 					//REFERENCE_TIME locAdjustedEnd = (locEnd * RATE_DENOMINATOR) / mRateNumerator;
-					REFERENCE_TIME locAdjustedStart = locStart - m_tStart;
-					REFERENCE_TIME locAdjustedEnd = locStart - m_tStart;
+					REFERENCE_TIME locAdjustedStart = locStart - mSegStart;
+					REFERENCE_TIME locAdjustedEnd = locEnd - mSegStart;
 
 					//Fill the sample info
 					if (TheoraDecoded(locYUV, locOutSample, locIsKeyFrame, locAdjustedStart, locAdjustedEnd) != S_OK) {
@@ -422,7 +429,7 @@
 						return S_FALSE;
 					} else {
 						//Deliver the sample
-						debugLog<<"Theora::Receive - Calling Deliver on outputPin"<<endl;
+						debugLog<<"Theora::Receive - Delivering: "<<locAdjustedStart<<" to "<<locAdjustedEnd<<(locIsKeyFrame ? "KEYFRAME": " ")<<endl;
 						
 						locHR = m_pOutput->Deliver(locOutSample);
 						locOutSample->Release();

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2005-11-01 12:22:31 UTC (rev 10316)
@@ -96,6 +96,9 @@
 
 	HRESULT TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame, REFERENCE_TIME inStart, REFERENCE_TIME inEnd);
 
+	REFERENCE_TIME mSegStart;
+	REFERENCE_TIME mSegEnd;
+	double mPlaybackRate;
 
 	__int64 mSeekTimeBase;
 	__int64 mLastSeenStartGranPos;

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeInputPin.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeInputPin.cpp	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeInputPin.cpp	2005-11-01 12:22:31 UTC (rev 10316)
@@ -113,7 +113,7 @@
 	//LOOG_INT64 retTime ((((inGranule >> locParent->getTheoraFormatBlock()->maxKeyframeInterval) + locInterFrameNo) * UNITS) * locParent->getTheoraFormatBlock()->frameRateDenominator) / locParent->getTheoraFormatBlock()->frameRateNumerator;
 
 	LOOG_INT64 retTime = inGranule >> locParent->getTheoraFormatBlock()->maxKeyframeInterval;
-	retTime += locInterFrameNo;
+	retTime += locInterFrameNo + 1;
 	retTime *= UNITS;
 	retTime *= locParent->getTheoraFormatBlock()->frameRateDenominator;
 	retTime /= locParent->getTheoraFormatBlock()->frameRateNumerator;

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/OggDemuxPacketSourceFilter.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/OggDemuxPacketSourceFilter.cpp	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/OggDemuxPacketSourceFilter.cpp	2005-11-01 12:22:31 UTC (rev 10316)
@@ -629,7 +629,9 @@
 		
 		
 		//For now, seek to the position directly, later we will discard the preroll
-		*pCurrent = locStartPos.first;
+		//Probably don't ever want to do this. We want to record the desired time,
+		//	and it will be up to the decoders to drop anything that falss before it.
+		//*pCurrent = locStartPos.first;
 
 		{
 			//debugLog<<"       : Delivering End Flush..."<<endl;

Modified: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.cpp	2005-11-01 12:22:31 UTC (rev 10316)
@@ -6,6 +6,7 @@
 	,	mFilePos(0)
 	,	mOggDemux(NULL)
 	,	mDuration(0)
+	,	mPreviousFilePos(0)
 	,	mIsEnabled(false)
 {
 	mOggDemux = new OggDataBuffer;
@@ -93,20 +94,50 @@
 	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())))) {
+	//There can be upto 2 incomplete packets on any page, one at the end and one at the start
+	unsigned long locNumBrokenPacks = (inOggPage->header()->isContinuation() ? 1 : 0);
+	if (inOggPage->numPackets() > 0) {
+		locNumBrokenPacks += (inOggPage->getPacket(inOggPage->numPackets() - 1)->isTruncated() ? 1 : 0);
+	}
+	//Exclude pages, with -1 granule pos, or that have no complete packets
+	if (locGranule != -1) { 
 		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);
-				if (locRealTime > mDuration) {
-					mDuration = locRealTime;
+		if ((inOggPage->numPackets() > locNumBrokenPacks)) {
+			
+			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);
+					if (locRealTime > mDuration) {
+						mDuration = locRealTime;
+					}
 				}
 			}
+		} else {
+			//If there's a granule pos, but no complete packets, there must at least be the end of a packet
+			//	so mark  the seek point with the previous filepos from a page that had a packet start on it
+			if ((locMapping.mSeekInterface != NULL) && (locMapping.mSeekTable != NULL)) {
+				//There is valid stream info
+				locRealTime = locMapping.mSeekInterface->convertGranuleToTime(locGranule);
+				if (locRealTime >= 0) {
+					locMapping.mSeekTable->addSeekPoint(locRealTime, mPreviousFilePos, locGranule);
+					if (locRealTime > mDuration) {
+						mDuration = locRealTime;
+					}
+				}
+			}
 		}
 	}
+
+	//Only remember the previous file position, if a packet started on this page, otherwise, we might
+	//	use the start point of the previous page, and that previous page may have not had any packets
+	//	on it.
+	//
+	//Any page that is not a continuation and has more than 1 packet, must have a packet starting on it
+	if (!(inOggPage->header()->isContinuation() && (inOggPage->numPackets() <= 1))) {
+		mPreviousFilePos = mFilePos;
+	}
 	mFilePos += inOggPage->pageSize();
 
 	delete inOggPage;

Modified: branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h	2005-11-01 07:51:27 UTC (rev 10315)
+++ branches/oggdsf_new_demux/src/lib/core/ogg/libOOOggSeek/AutoOggChainGranuleSeekTable.h	2005-11-01 12:22:31 UTC (rev 10316)
@@ -43,5 +43,7 @@
 	fstream mFile;
 	string mFilename;
 	unsigned long mFilePos;
+
+	unsigned long mPreviousFilePos;
 	OggDataBuffer* mOggDemux;
 };



More information about the commits mailing list