Bug 599217 - WebM buffered: should use duration for end time of last buffered range. r=kinetik

This commit is contained in:
Paul Adenot 2010-09-24 13:57:30 +12:00
parent f814bb5630
commit d76fe09441
3 changed files with 38 additions and 21 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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<MediaByteRange> 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);
}
}
}