diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index b3ea7ffcad1..f3acf523c85 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -2645,7 +2645,11 @@ void nsHTMLMediaElement::ResourceLoaded() mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE; AddRemoveSelfReference(); if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA) { - ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA); + // MediaStream sources are put into HAVE_CURRENT_DATA state here on setup. If the + // stream is not blocked, we will receive a notification that will put it + // into HAVE_ENOUGH_DATA state. + ChangeReadyState(mStream ? nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA + : nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA); } // Ensure a progress event is dispatched at the end of download. DispatchAsyncEvent(NS_LITERAL_STRING("progress")); diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index c9d5e6a31e0..59fd0f37c5c 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -1761,6 +1761,17 @@ MediaStream::ChangeExplicitBlockerCount(PRInt32 aDelta) GraphImpl()->AppendMessage(new Message(this, aDelta)); } +void +MediaStream::AddListenerImpl(already_AddRefed aListener) +{ + MediaStreamListener* listener = *mListeners.AppendElement() = aListener; + listener->NotifyBlockingChanged(GraphImpl(), + mBlocked.GetAt(GraphImpl()->mCurrentTime) ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED); + if (mNotifiedFinished) { + listener->NotifyFinished(GraphImpl()); + } +} + void MediaStream::AddListener(MediaStreamListener* aListener) { diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index 8be96fa6b9d..22ed0f3afce 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -83,6 +83,10 @@ class MediaStreamGraph; * reentry into media graph methods is possible, although very much discouraged! * You should do something non-blocking and non-reentrant (e.g. dispatch an * event to some thread) and return. + * + * When a listener is first attached, we guarantee to send a NotifyBlockingChanged + * callback to notify of the initial blocking state. Also, if a listener is + * attached to a stream that has already finished, we'll call NotifyFinished. */ class MediaStreamListener { public: @@ -263,10 +267,7 @@ public: { mExplicitBlockerCount.SetAtAndAfter(aTime, mExplicitBlockerCount.GetAt(aTime) + aDelta); } - void AddListenerImpl(already_AddRefed aListener) - { - *mListeners.AppendElement() = aListener; - } + void AddListenerImpl(already_AddRefed aListener); void RemoveListenerImpl(MediaStreamListener* aListener) { mListeners.RemoveElement(aListener);