diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h index 5dd129979ea..5438d47857e 100644 --- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -272,8 +272,4 @@ protected: // to ensure that the playstate doesn't change when the user goes Forward/Back // from the bfcache. PRPackedBool mPausedBeforeFreeze; - - // True if playback was requested before a decoder was available to begin - // playback with. - PRPackedBool mPlayRequested; }; diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index bb5b8c38da9..2c2ac4a1bed 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -506,8 +506,7 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse mPaused(PR_TRUE), mMuted(PR_FALSE), mIsDoneAddingChildren(!aFromParser), - mPlayingBeforeSeek(PR_FALSE), - mPlayRequested(PR_FALSE) + mPlayingBeforeSeek(PR_FALSE) { } @@ -525,33 +524,37 @@ nsHTMLMediaElement::~nsHTMLMediaElement() NS_IMETHODIMP nsHTMLMediaElement::Play() { - if (!mDecoder) { - mPlayRequested = PR_TRUE; - return NS_OK; - } - if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) { - mPlayRequested = PR_TRUE; - return Load(); - } - - if (mDecoder->IsEnded()) { - SetCurrentTime(0); + nsresult rv = Load(); + NS_ENSURE_SUCCESS(rv, rv); + } else if (mDecoder) { + if (mDecoder->IsEnded()) { + SetCurrentTime(0); + } + nsresult rv = mDecoder->Play(); + NS_ENSURE_SUCCESS(rv, rv); } // TODO: If the playback has ended, then the user agent must set // currentLoop to zero and seek to the effective start. // TODO: The playback rate must be set to the default playback rate. - nsresult rv = mDecoder->Play(); - NS_ENSURE_SUCCESS(rv, rv); + if (mPaused) { + DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play")); + switch (mReadyState) { + case nsIDOMHTMLMediaElement::HAVE_METADATA: + case nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA: + DispatchAsyncSimpleEvent(NS_LITERAL_STRING("waiting")); + break; + case nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA: + case nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA: + DispatchAsyncSimpleEvent(NS_LITERAL_STRING("playing")); + break; + } + } - PRBool oldPaused = mPaused; mPaused = PR_FALSE; mAutoplaying = PR_FALSE; - if (oldPaused) - DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play")); - return NS_OK; } @@ -870,7 +873,15 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel, mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING; - return mDecoder->Load(nsnull, aChannel, aListener); + nsresult rv = mDecoder->Load(nsnull, aChannel, aListener); + if (NS_FAILED(rv)) + return rv; + + if (!mPaused) { + rv = mDecoder->Play(); + } + + return rv; } nsresult nsHTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI) @@ -953,14 +964,6 @@ void nsHTMLMediaElement::MetadataLoaded() ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); DispatchAsyncSimpleEvent(NS_LITERAL_STRING("durationchange")); DispatchAsyncSimpleEvent(NS_LITERAL_STRING("loadedmetadata")); - if (mPlayRequested) { - mPlayRequested = PR_FALSE; - mPaused = PR_FALSE; - if (mDecoder) { - mDecoder->Play(); - } - DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play")); - } } void nsHTMLMediaElement::FirstFrameLoaded() @@ -1103,16 +1106,12 @@ void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState) break; case nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA: - DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplaythrough")); if (oldState != mReadyState) { LOG(PR_LOG_DEBUG, ("Ready state changed to HAVE_ENOUGH_DATA")); } if (oldState <= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA) { DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplay")); } - if (oldState <= nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) { - DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplaythrough")); - } if (mAutoplaying && mPaused && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) { @@ -1127,6 +1126,9 @@ void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState) IsPotentiallyPlaying()) { DispatchAsyncSimpleEvent(NS_LITERAL_STRING("playing")); } + if (oldState <= nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) { + DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplaythrough")); + } break; } } diff --git a/content/media/video/test/Makefile.in b/content/media/video/test/Makefile.in index 256137aad02..ec8888ac7dc 100644 --- a/content/media/video/test/Makefile.in +++ b/content/media/video/test/Makefile.in @@ -75,6 +75,7 @@ _TEST_FILES += \ test_ended1.html \ test_ended2.html \ test_onloadedmetadata.html \ + test_play.html \ test_progress1.html \ test_progress3.html \ test_standalone.html \ diff --git a/content/media/video/test/test_autoplay.html b/content/media/video/test/test_autoplay.html index 60de46abc2c..010aba03595 100644 --- a/content/media/video/test/test_autoplay.html +++ b/content/media/video/test/test_autoplay.html @@ -1,7 +1,7 @@
-+ + ++ +