[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