зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1119757: Allow seeking on media with infinite duration. r=cpearce
MSE defines content to have infinite duration when no duration is defined. And MSE is always seekable within the buffered range, regardless of the duration --HG-- extra : rebase_source : 369cce10504b125716af0a60e07d1d1144117f59
This commit is contained in:
Родитель
9e51efea6e
Коммит
b0638f45f3
|
@ -188,6 +188,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mPlayDuration(0),
|
||||
mStartTime(-1),
|
||||
mEndTime(-1),
|
||||
mDurationSet(false),
|
||||
mFragmentEndTime(-1),
|
||||
mReader(aReader),
|
||||
mCurrentFrameTime(0),
|
||||
|
@ -1408,6 +1409,14 @@ int64_t MediaDecoderStateMachine::GetDuration()
|
|||
return mEndTime - mStartTime;
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::GetEndTime()
|
||||
{
|
||||
if (mEndTime == -1 && mDurationSet) {
|
||||
return INT64_MAX;
|
||||
}
|
||||
return mEndTime;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SetDuration(int64_t aDuration)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(),
|
||||
|
@ -1415,13 +1424,21 @@ void MediaDecoderStateMachine::SetDuration(int64_t aDuration)
|
|||
AssertCurrentThreadInMonitor();
|
||||
|
||||
if (aDuration == -1) {
|
||||
mDurationSet = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mDurationSet = true;
|
||||
|
||||
if (mStartTime == -1) {
|
||||
SetStartTime(0);
|
||||
}
|
||||
|
||||
if (aDuration == INT64_MAX) {
|
||||
mEndTime = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
mEndTime = mStartTime + aDuration;
|
||||
}
|
||||
|
||||
|
@ -1735,12 +1752,13 @@ MediaDecoderStateMachine::StartSeek(const SeekTarget& aTarget)
|
|||
}
|
||||
|
||||
// Bound the seek time to be inside the media range.
|
||||
int64_t end = GetEndTime();
|
||||
NS_ASSERTION(mStartTime != -1, "Should know start time by now");
|
||||
NS_ASSERTION(mEndTime != -1, "Should know end time by now");
|
||||
NS_ASSERTION(end != -1, "Should know end time by now");
|
||||
int64_t seekTime = aTarget.mTime + mStartTime;
|
||||
seekTime = std::min(seekTime, mEndTime);
|
||||
seekTime = std::min(seekTime, end);
|
||||
seekTime = std::max(mStartTime, seekTime);
|
||||
NS_ASSERTION(seekTime >= mStartTime && seekTime <= mEndTime,
|
||||
NS_ASSERTION(seekTime >= mStartTime && seekTime <= end,
|
||||
"Can only seek in range [0,duration]");
|
||||
mSeekTarget = SeekTarget(seekTime, aTarget.mType);
|
||||
|
||||
|
@ -2188,7 +2206,7 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mDecoder->StartProgressUpdates();
|
||||
mGotDurationFromMetaData = (GetDuration() != -1);
|
||||
mGotDurationFromMetaData = (GetDuration() != -1) || mDurationSet;
|
||||
|
||||
if (mGotDurationFromMetaData) {
|
||||
// We have all the information required: duration and size
|
||||
|
@ -2300,12 +2318,8 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
|||
}
|
||||
|
||||
NS_ASSERTION(mStartTime != -1, "Must have start time");
|
||||
MOZ_ASSERT((!HasVideo() && !HasAudio()) ||
|
||||
!(mDecoder->IsMediaSeekable() && mDecoder->IsTransportSeekable()) ||
|
||||
mEndTime != -1,
|
||||
"Active seekable media should have end time");
|
||||
MOZ_ASSERT(!(mDecoder->IsMediaSeekable() && mDecoder->IsTransportSeekable()) ||
|
||||
GetDuration() != -1,
|
||||
(GetDuration() != -1) || mDurationSet,
|
||||
"Seekable media should have duration");
|
||||
DECODER_LOG("Media goes from %lld to %lld (duration %lld) "
|
||||
"transportSeekable=%d, mediaSeekable=%d",
|
||||
|
@ -2429,7 +2443,7 @@ void MediaDecoderStateMachine::DecodeSeek()
|
|||
// the reader, since it could do I/O or deadlock some other way.
|
||||
res = mReader->ResetDecode();
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
mReader->Seek(seekTime, mStartTime, mEndTime, mCurrentTimeBeforeSeek)
|
||||
mReader->Seek(seekTime, mStartTime, GetEndTime(), mCurrentTimeBeforeSeek)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnSeekCompleted,
|
||||
&MediaDecoderStateMachine::OnSeekFailed);
|
||||
|
@ -3244,7 +3258,7 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
|
|||
mStartTime = 0;
|
||||
if (aStartTimeUsecs != 0) {
|
||||
mStartTime = aStartTimeUsecs;
|
||||
if (mGotDurationFromMetaData) {
|
||||
if (mGotDurationFromMetaData && GetEndTime() != INT64_MAX) {
|
||||
NS_ASSERTION(mEndTime != -1,
|
||||
"We should have mEndTime as supplied duration here");
|
||||
// We were specified a duration from a Content-Duration HTTP header.
|
||||
|
|
|
@ -171,11 +171,18 @@ public:
|
|||
// must be obtained before calling this. It is in units of microseconds.
|
||||
int64_t GetDuration();
|
||||
|
||||
// Time of the last frame in the media, in microseconds or INT64_MAX if
|
||||
// media has an infinite duration.
|
||||
// Accessed on state machine, decode, and main threads.
|
||||
// Access controlled by decoder monitor.
|
||||
int64_t GetEndTime();
|
||||
|
||||
// Called from the main thread to set the duration of the media resource
|
||||
// if it is able to be obtained via HTTP headers. Called from the
|
||||
// state machine thread to set the duration if it is obtained from the
|
||||
// media metadata. The decoder monitor must be obtained before calling this.
|
||||
// aDuration is in microseconds.
|
||||
// A value of INT64_MAX will be treated as infinity.
|
||||
void SetDuration(int64_t aDuration);
|
||||
|
||||
// Called while decoding metadata to set the end time of the media
|
||||
|
@ -832,8 +839,14 @@ protected:
|
|||
// Time of the last frame in the media, in microseconds. This is the
|
||||
// end time of the last frame in the media. Accessed on state
|
||||
// machine, decode, and main threads. Access controlled by decoder monitor.
|
||||
// It will be set to -1 if the duration is infinite
|
||||
int64_t mEndTime;
|
||||
|
||||
// Will be set when SetDuration has been called with a value != -1
|
||||
// mDurationSet false doesn't indicate that we do not have a valid duration
|
||||
// as mStartTime and mEndTime could have been set separately.
|
||||
bool mDurationSet;
|
||||
|
||||
// Position to seek to in microseconds when the seek state transition occurs.
|
||||
// The decoder monitor lock must be obtained before reading or writing
|
||||
// this value. Accessed on main and decode thread.
|
||||
|
|
Загрузка…
Ссылка в новой задаче