From 930455959fd6b94785cb730cbdd4df52a568f94a Mon Sep 17 00:00:00 2001 From: Matthew Gregan Date: Mon, 11 Aug 2014 14:05:09 +1200 Subject: [PATCH] Bug 1050083 - Changes to WebM buffered range handling. r=cajbir Include the frame duration in the range end. Also handle (ignore) invalid negative timestamps when parsing. Include cluster offset in time/data offset record. Cluster offset will be used when calculating discard/resync points in MSE. --- content/media/webm/WebMBufferedParser.cpp | 25 +++++++++++++++-------- content/media/webm/WebMBufferedParser.h | 10 +++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/content/media/webm/WebMBufferedParser.cpp b/content/media/webm/WebMBufferedParser.cpp index 8348bb026e05..6f4f1ec551b0 100644 --- a/content/media/webm/WebMBufferedParser.cpp +++ b/content/media/webm/WebMBufferedParser.cpp @@ -32,8 +32,8 @@ VIntLength(unsigned char aFirstByte, uint32_t* aMask) } void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength, - nsTArray& aMapping, - ReentrantMonitor& aReentrantMonitor) + nsTArray& aMapping, + ReentrantMonitor& aReentrantMonitor) { static const unsigned char CLUSTER_ID[] = { 0x1f, 0x43, 0xb6, 0x75 }; static const unsigned char TIMECODE_ID = 0xe7; @@ -60,6 +60,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength, // and return to CLUSTER_SYNC. if (mClusterIDPos == sizeof(CLUSTER_ID)) { mClusterIDPos = 0; + mClusterOffset = mCurrentOffset + (p - aBuffer) - 1; mState = READ_VINT; mNextState = TIMECODE_SYNC; } @@ -140,9 +141,14 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength, { ReentrantMonitorAutoEnter mon(aReentrantMonitor); uint32_t idx = aMapping.IndexOfFirstElementGt(mBlockOffset); - if (idx == 0 || !(aMapping[idx-1] == mBlockOffset)) { - WebMTimeDataOffset entry(mBlockOffset, mClusterTimecode + mBlockTimecode); - aMapping.InsertElementAt(idx, entry); + if (idx == 0 || !(aMapping[idx - 1] == mBlockOffset)) { + // Don't insert invalid negative timecodes. + if (mBlockOffset > 0 || mClusterTimecode > uint16_t(abs(mBlockOffset))) { + WebMTimeDataOffset entry(mBlockOffset, + mClusterTimecode + mBlockTimecode, + mClusterOffset); + aMapping.InsertElementAt(idx, entry); + } } } @@ -177,18 +183,18 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength, } bool WebMBufferedState::CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset, - uint64_t* aStartTime, uint64_t* aEndTime) + uint64_t* aStartTime, uint64_t* aEndTime) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); // Find the first WebMTimeDataOffset at or after aStartOffset. - uint32_t start = mTimeMapping.IndexOfFirstElementGt(aStartOffset-1); + uint32_t start = mTimeMapping.IndexOfFirstElementGt(aStartOffset - 1); if (start == mTimeMapping.Length()) { return false; } // Find the first WebMTimeDataOffset at or before aEndOffset. - uint32_t end = mTimeMapping.IndexOfFirstElementGt(aEndOffset-1); + uint32_t end = mTimeMapping.IndexOfFirstElementGt(aEndOffset - 1); if (end > 0) { end -= 1; } @@ -216,13 +222,14 @@ bool WebMBufferedState::CalculateBufferedForRange(int64_t aStartOffset, int64_t *aStartTime = mTimeMapping[start].mTimecode; *aEndTime = mTimeMapping[end].mTimecode; + *aEndTime += mTimeMapping[end].mTimecode - mTimeMapping[end - 1].mTimecode; return true; } bool WebMBufferedState::GetOffsetForTime(uint64_t aTime, int64_t* aOffset) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); - WebMTimeDataOffset result(0,0); + WebMTimeDataOffset result(0, 0, 0); for (uint32_t i = 0; i < mTimeMapping.Length(); ++i) { WebMTimeDataOffset o = mTimeMapping[i]; diff --git a/content/media/webm/WebMBufferedParser.h b/content/media/webm/WebMBufferedParser.h index 2c1edc0b72ca..1942e1626720 100644 --- a/content/media/webm/WebMBufferedParser.h +++ b/content/media/webm/WebMBufferedParser.h @@ -21,8 +21,8 @@ class TimeRanges; // scale before use. struct WebMTimeDataOffset { - WebMTimeDataOffset(int64_t aOffset, uint64_t aTimecode) - : mOffset(aOffset), mTimecode(aTimecode) + WebMTimeDataOffset(int64_t aOffset, uint64_t aTimecode, int64_t aSyncOffset) + : mOffset(aOffset), mTimecode(aTimecode), mSyncOffset(aSyncOffset) {} bool operator==(int64_t aOffset) const { @@ -35,6 +35,7 @@ struct WebMTimeDataOffset int64_t mOffset; uint64_t mTimecode; + int64_t mSyncOffset; }; // A simple WebM parser that produces data offset to timecode pairs as it @@ -165,6 +166,11 @@ private: // Cluster-level timecode. uint64_t mClusterTimecode; + // Start offset of the cluster currently being parsed. Used as the sync + // point offset for the offset-to-time mapping as each block timecode is + // been parsed. + int64_t mClusterOffset; + // Start offset of the block currently being parsed. Used as the byte // offset for the offset-to-time mapping once the block timecode has been // parsed.