Bug 1229256: P2. Use buffered range to determine next frame availability. r=jwwang

To avoid potential regression with some of our tests expecting our old particular behaviour, we only use the buffered range to determine the next frame status if the old method determined that the next frame was unavailable due to the MediaDecodeStateMachine not having decoded the next frame yet.
This commit is contained in:
Jean-Yves Avenard 2015-12-02 11:50:21 +11:00
Родитель b968a258a5
Коммит dc75044746
3 изменённых файлов: 29 добавлений и 3 удалений

Просмотреть файл

@ -3764,7 +3764,12 @@ HTMLMediaElement::UpdateReadyStateInternal()
MetadataLoaded(&mediaInfo, nsAutoPtr<const MetadataTags>(nullptr));
}
if (NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) {
enum NextFrameStatus nextFrameStatus = NextFrameStatus();
if (mDecoder && nextFrameStatus == NEXT_FRAME_UNAVAILABLE) {
nextFrameStatus = mDecoder->NextFrameBufferedStatus();
}
if (nextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"NEXT_FRAME_UNAVAILABLE_SEEKING; Forcing HAVE_METADATA", this));
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
@ -3800,13 +3805,13 @@ HTMLMediaElement::UpdateReadyStateInternal()
return;
}
if (NextFrameStatus() != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
if (nextFrameStatus != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Next frame not available", this));
if (mFirstFrameLoaded) {
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
}
if (!mWaitingFired && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
if (!mWaitingFired && nextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
FireTimeUpdate(false);
DispatchAsyncEvent(NS_LITERAL_STRING("waiting"));
mWaitingFired = true;

Просмотреть файл

@ -1816,6 +1816,21 @@ MediaDecoder::RemoveMediaTracks()
mMediaTracksConstructed = false;
}
MediaDecoderOwner::NextFrameStatus
MediaDecoder::NextFrameBufferedStatus()
{
MOZ_ASSERT(NS_IsMainThread());
// Next frame hasn't been decoded yet.
// Use the buffered range to consider if we have the next frame available.
media::TimeUnit currentPosition =
media::TimeUnit::FromMicroseconds(CurrentPosition());
media::TimeInterval interval(currentPosition,
currentPosition + media::TimeUnit::FromMicroseconds(DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED));
return GetBuffered().Contains(interval)
? MediaDecoderOwner::NEXT_FRAME_AVAILABLE
: MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
}
MediaMemoryTracker::MediaMemoryTracker()
{
}

Просмотреть файл

@ -719,6 +719,7 @@ private:
}
virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() { return mNextFrameStatus; }
virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus();
protected:
virtual ~MediaDecoder();
@ -792,6 +793,11 @@ protected:
// Media data resource.
RefPtr<MediaResource> mResource;
// Amount of buffered data ahead of current time required to consider that
// the next frame is available.
// An arbitrary value of 250ms is used.
static const int DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED = 250000;
private:
// Called when the metadata from the media file has been loaded by the
// state machine. Call on the main thread only.