Bug 945475 - Clear |mVideoFrameContainer| to stop staled callbacks which give incorrect videoWidth/videoHeight. r=roc, a=sledru
authorJW Wang <jwwang@mozilla.com>
Fri, 11 Apr 2014 12:52:02 -0400
changeset 183704 eaf92a872145643b29d4fd6849720abea7027eb9
parent 183703 e7806ccfe24f41f8727a8c9b5c3b698d9913eadb
child 183705 5be8148fea1f002fae2f286dff5785cff8656998
push id3453
push userryanvm@gmail.com
push dateFri, 11 Apr 2014 16:50:59 +0000
treeherdermozilla-beta@5be8148fea1f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs945475
milestone29.0
Bug 945475 - Clear |mVideoFrameContainer| to stop staled callbacks which give incorrect videoWidth/videoHeight. r=roc, a=sledru
content/html/content/src/HTMLMediaElement.cpp
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -738,19 +738,23 @@ NS_IMETHODIMP HTMLMediaElement::Load()
   mIsRunningLoadMethod = false;
 
   return NS_OK;
 }
 
 void HTMLMediaElement::ResetState()
 {
   mMediaSize = nsIntSize(-1, -1);
-  VideoFrameContainer* container = GetVideoFrameContainer();
-  if (container) {
-    container->Reset();
+  // There might be a pending MediaDecoder::PlaybackPositionChanged() which
+  // will overwrite |mMediaSize| in UpdateMediaSize() to give staled videoWidth
+  // and videoHeight. We have to call ForgetElement() here such that the staled
+  // callbacks won't reach us.
+  if (mVideoFrameContainer) {
+    mVideoFrameContainer->ForgetElement();
+    mVideoFrameContainer = nullptr;
   }
 }
 
 static bool HasSourceChildren(nsIContent* aElement)
 {
   for (nsIContent* child = aElement->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
@@ -2851,17 +2855,20 @@ void HTMLMediaElement::MetadataLoaded(in
   if (mDecoder && mDecoder->IsTransportSeekable() && mDecoder->IsMediaSeekable()) {
     ProcessMediaFragmentURI();
     mDecoder->SetFragmentEndTime(mFragmentEnd);
   }
 
   // If this element had a video track, but consists only of an audio track now,
   // delete the VideoFrameContainer. This happens when the src is changed to an
   // audio only file.
-  if (!aHasVideo) {
+  if (!aHasVideo && mVideoFrameContainer) {
+    // call ForgetElement() such that callbacks from |mVideoFrameContainer|
+    // won't reach us anymore.
+    mVideoFrameContainer->ForgetElement();
     mVideoFrameContainer = nullptr;
   }
 }
 
 void HTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded)
 {
   ChangeReadyState(aResourceFullyLoaded ?
     nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA :