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