diff --git a/content/media/webm/nsWebMBufferedParser.cpp b/content/media/webm/nsWebMBufferedParser.cpp index cbc8e2be4f4..834e46c765a 100644 --- a/content/media/webm/nsWebMBufferedParser.cpp +++ b/content/media/webm/nsWebMBufferedParser.cpp @@ -209,10 +209,8 @@ void nsWebMBufferedParser::Append(const unsigned char* aBuffer, PRUint32 aLength mCurrentOffset += aLength; } -void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered, - PRInt64 aStartOffset, PRInt64 aEndOffset, - PRUint64 aTimecodeScale, - PRInt64 aStartTimeOffsetNS) +bool nsWebMBufferedState::CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset, + PRUint64* aStartTime, PRUint64* aEndTime) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); @@ -220,7 +218,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered, PRUint32 start; mTimeMapping.GreatestIndexLtEq(aStartOffset, start); if (start == mTimeMapping.Length()) { - return; + return false; } // Find the first nsWebMTimeDataOffset at or before aEndOffset. @@ -233,7 +231,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered, // Range is empty. if (end <= start) { - return; + return false; } NS_ASSERTION(mTimeMapping[start].mOffset >= aStartOffset && @@ -252,9 +250,9 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered, // from the ranges' start and end timestamps, so that those timestamps are // normalized in the range [0,duration]. - double startTime = (mTimeMapping[start].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S; - double endTime = (mTimeMapping[end].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S; - aBuffered->Add(startTime, endTime); + *aStartTime = mTimeMapping[start].mTimecode; + *aEndTime = mTimeMapping[end].mTimecode; + return true; } void nsWebMBufferedState::NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset) diff --git a/content/media/webm/nsWebMBufferedParser.h b/content/media/webm/nsWebMBufferedParser.h index f25feb5dd48..51b27d4a7ee 100644 --- a/content/media/webm/nsWebMBufferedParser.h +++ b/content/media/webm/nsWebMBufferedParser.h @@ -225,10 +225,8 @@ public: } void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset); - void CalculateBufferedForRange(nsTimeRanges* aBuffered, - PRInt64 aStartOffset, PRInt64 aEndOffset, - PRUint64 aTimecodeScale, - PRInt64 aStartTimeOffsetNS); + bool CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset, + PRUint64* aStartTime, PRUint64* aEndTime); private: // Synchronizes access to the mTimeMapping array. diff --git a/content/media/webm/nsWebMReader.cpp b/content/media/webm/nsWebMReader.cpp index e3b3b03cf49..7f56d2337cc 100644 --- a/content/media/webm/nsWebMReader.cpp +++ b/content/media/webm/nsWebMReader.cpp @@ -791,24 +791,45 @@ nsresult nsWebMReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime) } // Special case completely cached files. This also handles local files. - if (resource->IsDataCachedToEndOfResource(0)) { + bool isFullyCached = resource->IsDataCachedToEndOfResource(0); + if (isFullyCached) { uint64_t duration = 0; if (nestegg_duration(mContext, &duration) == 0) { aBuffered->Add(0, duration / NS_PER_S); } - } else { + } + + PRUint32 bufferedLength = 0; + aBuffered->GetLength(&bufferedLength); + + // Either we the file is not fully cached, or we couldn't find a duration in + // the WebM bitstream. + if (!isFullyCached || !bufferedLength) { MediaResource* resource = mDecoder->GetResource(); nsTArray ranges; nsresult res = resource->GetCachedRanges(ranges); NS_ENSURE_SUCCESS(res, res); - PRInt64 startTimeOffsetNS = aStartTime * NS_PER_USEC; for (PRUint32 index = 0; index < ranges.Length(); index++) { - mBufferedState->CalculateBufferedForRange(aBuffered, - ranges[index].mStart, - ranges[index].mEnd, - timecodeScale, - startTimeOffsetNS); + PRUint64 start, end; + bool rv = mBufferedState->CalculateBufferedForRange(ranges[index].mStart, + ranges[index].mEnd, + &start, &end); + if (rv) { + double startTime = start * timecodeScale / NS_PER_S - aStartTime; + double endTime = end * timecodeScale / NS_PER_S - aStartTime; + + // If this range extends to the end of the file, the true end time + // is the file's duration. + if (resource->IsDataCachedToEndOfResource(ranges[index].mStart)) { + uint64_t duration = 0; + if (nestegg_duration(mContext, &duration) == 0) { + endTime = duration / NS_PER_S; + } + } + + aBuffered->Add(startTime, endTime); + } } }