Backed out 4 changesets (bug 879717) for OSX/Android/B2G mochitest failures.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 06 Oct 2014 13:44:28 -0400
changeset 209033 b2d92cb448730745ab54c54167cd423ae8347469
parent 209032 8f91f44a4e3ec476466fb56ab2faff603bb76957
child 209034 8be54e6c4dcd2f69d8c27ab6038e828dee126f63
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs879717
milestone35.0a1
backs out353aee81348432381174cb0957fc8f84661dc8c1
cd7d8b93923f3fe80129955917d78e83ebce5da8
78b01186ff855234e43e2968afc9fd3bbc7e354b
29f4a39efc29b864b0d61009ad536f57b2a2d66d
Backed out 4 changesets (bug 879717) for OSX/Android/B2G mochitest failures. Backed out changeset 353aee813484 (bug 879717) Backed out changeset cd7d8b93923f (bug 879717) Backed out changeset 78b01186ff85 (bug 879717) Backed out changeset 29f4a39efc29 (bug 879717) CLOSED TREE
content/html/content/public/HTMLMediaElement.h
content/html/content/src/HTMLMediaElement.cpp
content/media/test/mochitest.ini
content/media/test/test_bug879717.html
--- a/content/html/content/public/HTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -1008,19 +1008,16 @@ protected:
   // These events get re-dispatched when the bfcache is exited.
   nsTArray<nsString> mPendingEvents;
 
   // Media loading flags. See:
   //   http://www.whatwg.org/specs/web-apps/current-work/#video)
   nsMediaNetworkState mNetworkState;
   nsMediaReadyState mReadyState;
 
-  // Last value passed from codec or stream source to UpdateReadyStateForData.
-  NextFrameStatus mLastNextFrameStatus;
-
   enum LoadAlgorithmState {
     // No load algorithm instance is waiting for a source to be added to the
     // media in order to continue loading.
     NOT_WAITING,
     // We've run the load algorithm, and we tried all source children of the
     // media element, and failed to load any successfully. We're waiting for
     // another source element to be added to the media element, and will try
     // to load any such element when its added.
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -66,18 +66,16 @@
 #include "nsURIHashKey.h"
 #include "nsJSUtils.h"
 #include "MediaStreamGraph.h"
 #include "nsIScriptError.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "mozilla/dom/MediaSource.h"
 #include "MediaMetadataManager.h"
 #include "MediaSourceDecoder.h"
-#include "AudioStreamTrack.h"
-#include "VideoStreamTrack.h"
 
 #include "AudioChannelService.h"
 
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/WakeLock.h"
 
 #include "mozilla/dom/AudioTrack.h"
 #include "mozilla/dom/AudioTrackList.h"
@@ -661,20 +659,17 @@ void HTMLMediaElement::AbortExistingLoad
   mLoadedDataFired = false;
   mAutoplaying = true;
   mIsLoadingFromSourceChildren = false;
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
   mHaveQueuedSelectResource = false;
   mSuspendedForPreloadNone = false;
   mDownloadSuspendedByCache = false;
-  mHasAudio = false;
-  mHasVideo = false;
   mSourcePointer = nullptr;
-  mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED;
 
   mTags = nullptr;
 
   if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     NS_ASSERTION(!mDecoder && !mSrcStream, "How did someone setup a new stream/decoder already?");
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
     mPaused = true;
@@ -1987,17 +1982,16 @@ HTMLMediaElement::LookupMediaElementURIT
 }
 
 HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
     mSrcStreamListener(nullptr),
     mCurrentLoadID(0),
     mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
     mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
-    mLastNextFrameStatus(NEXT_FRAME_UNINITIALIZED),
     mLoadWaitStatus(NOT_WAITING),
     mVolume(1.0),
     mPreloadAction(PRELOAD_UNDEFINED),
     mMediaSize(-1,-1),
     mLastCurrentTime(0.0),
     mFragmentStart(-1.0),
     mFragmentEnd(-1.0),
     mDefaultPlaybackRate(1.0),
@@ -2829,43 +2823,32 @@ void HTMLMediaElement::SetupSrcMediaStre
   mSrcStreamListener = new StreamListener(this);
   GetSrcMediaStream()->AddListener(mSrcStreamListener);
   if (mPaused) {
     GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
   }
   if (mPausedForInactiveDocumentOrChannel) {
     GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
   }
-
-  nsAutoTArray<nsRefPtr<AudioStreamTrack>,1> audioTracks;
-  aStream->GetAudioTracks(audioTracks);
-  nsAutoTArray<nsRefPtr<VideoStreamTrack>,1> videoTracks;
-  aStream->GetVideoTracks(videoTracks);
-
-  // Clear aTags, but set mHasAudio and mHasVideo
-  MediaInfo mediaInfo;
-  mediaInfo.mAudio.mHasAudio = !audioTracks.IsEmpty();
-  mediaInfo.mVideo.mHasVideo = !videoTracks.IsEmpty();
-  MetadataLoaded(&mediaInfo, nullptr);
-
-  DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
-  mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
-
   ChangeDelayLoadStatus(false);
   GetSrcMediaStream()->AddAudioOutput(this);
   GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume));
   VideoFrameContainer* container = GetVideoFrameContainer();
   if (container) {
     GetSrcMediaStream()->AddVideoOutput(container);
   }
 
   // Note: we must call DisconnectTrackListListeners(...)  before dropping
   // mSrcStream
   mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks());
 
+  ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
+  DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
+  DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
+  ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
   AddRemoveSelfReference();
   // FirstFrameLoaded() will be called when the stream has current data.
 }
 
 void HTMLMediaElement::EndSrcMediaStreamPlayback()
 {
   MediaStream* stream = GetSrcMediaStream();
   if (stream) {
@@ -2928,29 +2911,23 @@ void HTMLMediaElement::MetadataLoaded(co
   // delete the VideoFrameContainer. This happens when the src is changed to an
   // audio only file.
   if (!aInfo->HasVideo() && mVideoFrameContainer) {
     // call ForgetElement() such that callbacks from |mVideoFrameContainer|
     // won't reach us anymore.
     mVideoFrameContainer->ForgetElement();
     mVideoFrameContainer = nullptr;
   }
-
-  if (IsVideo()) {
-    // Update the screen wakelock in case mHasVideo changed
-    NotifyOwnerDocumentActivityChanged();
-  }
 }
 
 void HTMLMediaElement::FirstFrameLoaded()
 {
   NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
 
   ChangeDelayLoadStatus(false);
-  UpdateReadyStateForData(NEXT_FRAME_UNAVAILABLE);
 
   if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
       !HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
       mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
     mSuspendedAfterFirstFrame = true;
     mDecoder->Suspend();
   }
 }
@@ -3103,18 +3080,16 @@ void HTMLMediaElement::DownloadStalled()
 
 bool HTMLMediaElement::ShouldCheckAllowOrigin()
 {
   return mCORSMode != CORS_NONE;
 }
 
 void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame)
 {
-  mLastNextFrameStatus = aNextFrame;
-
   if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
     // aNextFrame might have a next frame because the decoder can advance
     // on its own thread before MetadataLoaded gets a chance to run.
     // The arrival of more data can't change us out of this readyState.
     return;
   }
 
   if (aNextFrame == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) {
@@ -3131,24 +3106,16 @@ void HTMLMediaElement::UpdateReadyStateF
     // this transition if the decoder is in ended state; the readyState
     // should remain at HAVE_CURRENT_DATA in this case.
     // Note that this state transition includes the case where we finished
     // downloaded the whole data stream.
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
     return;
   }
 
-  if (mReadyState < nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA && mHasVideo) {
-    VideoFrameContainer* container = GetVideoFrameContainer();
-    if (container && mMediaSize == nsIntSize(-1,-1)) {
-      // No frame has been set yet. Don't advance.
-      return;
-    }
-  }
-
   if (aNextFrame != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
     if (!mWaitingFired && aNextFrame == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
       FireTimeUpdate(false);
       DispatchAsyncEvent(NS_LITERAL_STRING("waiting"));
       mWaitingFired = true;
     }
     return;
@@ -3279,24 +3246,24 @@ void HTMLMediaElement::ChangeNetworkStat
   } else if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_IDLE && !mError) {
     // Fire 'suspend' event when entering NETWORK_IDLE and no error presented.
     DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   }
 }
 
 bool HTMLMediaElement::CanActivateAutoplay()
 {
-  // For stream inputs, we activate autoplay on HAVE_METADATA because
+  // For stream inputs, we activate autoplay on HAVE_CURRENT_DATA because
   // this element itself might be blocking the stream from making progress by
   // being paused.
   return !mPausedForInactiveDocumentOrChannel &&
          mAutoplaying &&
          mPaused &&
          ((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
-          (mSrcStream && mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA)) &&
+          (mSrcStream && mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA)) &&
          HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
          mAutoplayEnabled &&
          !IsEditable();
 }
 
 void HTMLMediaElement::CheckAutoplayDataReady()
 {
   if (CanActivateAutoplay()) {
@@ -3315,24 +3282,34 @@ void HTMLMediaElement::CheckAutoplayData
       GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
     }
     DispatchAsyncEvent(NS_LITERAL_STRING("play"));
   }
 }
 
 VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
 {
-  if (mVideoFrameContainer)
-    return mVideoFrameContainer;
+  // If we have loaded the metadata, and the size of the video is still
+  // (-1, -1), the media has no video. Don't go a create a video frame
+  // container.
+  if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
+      mMediaSize == nsIntSize(-1, -1)) {
+    return nullptr;
+  }
 
   // Only video frames need an image container.
   if (!IsVideo()) {
     return nullptr;
   }
 
+  mHasVideo = true;
+
+  if (mVideoFrameContainer)
+    return mVideoFrameContainer;
+
   mVideoFrameContainer =
     new VideoFrameContainer(this, LayerManager::CreateAsynchronousImageContainer());
 
   return mVideoFrameContainer;
 }
 
 nsresult HTMLMediaElement::DispatchEvent(const nsAString& aName)
 {
@@ -3430,17 +3407,16 @@ void HTMLMediaElement::NotifyDecoderPrin
     OutputMediaStream* ms = &mOutputStreams[i];
     ms->mStream->CombineWithPrincipal(principal);
   }
 }
 
 void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
 {
   mMediaSize = size;
-  UpdateReadyStateForData(mLastNextFrameStatus);
 }
 
 void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
 {
   if (aPauseElement != mPausedForInactiveDocumentOrChannel) {
     mPausedForInactiveDocumentOrChannel = aPauseElement;
     if (aPauseElement) {
 #ifdef MOZ_EME
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -314,17 +314,16 @@ skip-if = buildapp == 'mulet' || os == '
 [test_bug465498.html]
 [test_bug493187.html]
 [test_bug495145.html]
 [test_bug495300.html]
 [test_bug654550.html]
 [test_bug686942.html]
 [test_bug726904.html]
 [test_bug874897.html]
-[test_bug879717.html]
 [test_bug883173.html]
 [test_bug895091.html]
 [test_bug895305.html]
 [test_bug919265.html]
 [test_bug957847.html]
 [test_bug1018933.html]
 [test_can_play_type.html]
 [test_can_play_type_mpeg.html]
deleted file mode 100644
--- a/content/media/test/test_bug879717.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for bug 879717, check that a video element can be drawn into a canvas directly on 'play' event</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-  <script type="text/javascript" src="manifest.js"></script>
-</head>
-<body>
-<video id="v1" autoplay />
-<video id="v2" autoplay />
-<canvas id="c1" />
-<canvas id="c2" />
-<pre id="test">
-<script class="testbody" type="text/javascript">
-SimpleTest.waitForExplicitFinish();
-
-var media = getPlayableVideo(gSmallTests);
-
-var checkDrawImage = function(video, canvas, name) {
-  var exception = null;
-  var exceptionName = "nothing";
-  try {
-    var ctx = canvas.getContext('2d');
-    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
-  } catch (e) {
-    exception = e;
-    exceptionName = e.name;
-  }
-  ok(exception === null || video.ended,
-    "drawImage shouldn't throw an exception on play of " + name + ", got " + exceptionName);
-};
-
-if (media == null) {
-  todo(false, "No media supported.");
-  SimpleTest.finish();
-} else {
-  v1.src = media.name;
-  v2.mozSrcObject = v1.mozCaptureStream();
-
-  var v1Tested = false;
-  var v2Tested = false;
-
-  v1.addEventListener('play', function() {
-    checkDrawImage(v1, c1, media.name);
-
-    v1Tested = true;
-    if (v2Tested) {
-      SimpleTest.finish();
-    }
-  });
-
-  v2.addEventListener('play', function() {
-    checkDrawImage(v2, c2, "stream of " + media.name);
-
-    v2Tested = true;
-    if (v1Tested) {
-      SimpleTest.finish();
-    }
-  });
-}
-</script>
-</pre>
-</body>
-</html>