Bug 467972 - Load() invoked to do seek in onended results in sending onloadedmetadata; r=chris.double sr=roc
authorChris Pearce <chris@pearce.org.nz>
Wed, 10 Dec 2008 15:23:23 +0100
changeset 22567 6de3075c652247346ad51fd2ec9fad5d5d460f92
parent 22566 865af0f2587a92b05947ec50fdb2838f5c53aaa0
child 22568 28f45bf33ba97a819659111bd5eeef7bb2fee162
push idunknown
push userunknown
push dateunknown
reviewerschris.double, roc
bugs467972
milestone1.9.2a1pre
Bug 467972 - Load() invoked to do seek in onended results in sending onloadedmetadata; r=chris.double sr=roc
content/media/video/src/nsOggDecoder.cpp
content/media/video/test/Makefile.in
content/media/video/test/test_onloadedmetadata.html
--- a/content/media/video/src/nsOggDecoder.cpp
+++ b/content/media/video/src/nsOggDecoder.cpp
@@ -1381,32 +1381,44 @@ nsIPrincipal* nsOggDecoder::GetCurrentPr
   return mReader->GetCurrentPrincipal();
 }
 
 void nsOggDecoder::MetadataLoaded()
 {
   if (mShuttingDown)
     return;
 
+  // Only inform the element of MetadataLoaded if not doing a load() in order
+  // to fulfill a seek, otherwise we'll get multiple metadataloaded events.
+  PRBool notifyElement = PR_TRUE;
   {
     nsAutoMonitor mon(mMonitor);
     mDuration = mDecodeStateMachine ? mDecodeStateMachine->GetDuration() : -1;
+    notifyElement = mNextState != PLAY_STATE_SEEKING;
   }
 
-  if (mElement) {
+  if (mElement && notifyElement) {
     mElement->MetadataLoaded();
   }
 }
 
 void nsOggDecoder::FirstFrameLoaded()
 {
   if (mShuttingDown)
     return;
+ 
+  // Only inform the element of FirstFrameLoaded if not doing a load() in order
+  // to fulfill a seek, otherwise we'll get multiple loadedfirstframe events.
+  PRBool notifyElement = PR_TRUE;
+  {
+    nsAutoMonitor mon(mMonitor);
+    notifyElement = mNextState != PLAY_STATE_SEEKING;
+  }  
 
-  if (mElement) {
+  if (mElement && notifyElement) {
     mElement->FirstFrameLoaded();
   }
 
   // The element can run javascript via events
   // before reaching here, so only change the 
   // state if we're still set to the original
   // loading state.
   nsAutoMonitor mon(mMonitor);
--- a/content/media/video/test/Makefile.in
+++ b/content/media/video/test/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/rules.mk
                 test_bug461281.html \
                 test_constants.html \
                 test_controls.html \
                 test_currentTime.html \
                 test_duration1.html \
                 test_ended1.html \
                 test_ended2.html \
                 test_networkState.html \
+                test_onloadedmetadata.html \
                 test_paused.html \
                 test_readyState.html \
                 test_seek1.html \
                 test_seek2.html \
                 test_seek3.html \
                 test_seek4.html \
                 test_seek5.html \
                 test_seek6.html \
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_onloadedmetadata.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=467972
+-->
+<head>
+  <title>Test for Bug 467972</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=467972">Mozilla Bug 467972</a>
+
+<video id="v"
+       src="320x240.ogg"
+       onloadedmetadata="return loadedMetaData();"
+       onended="playbackEnded();"
+       onloadedfirstframe="return loadedFirstFrame();"       
+       onseeking="seekStarted();"
+       onseeked="seekEnded();"       
+       controls></video>
+
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 467972 **/
+
+
+var gEnded = false;
+var gSeekStarted = false;
+var gSeekEnded = false;
+var gLoadedFirstFrameCount = 0;
+var gLoadedMetaDataCount = 0;
+
+function get(id) {
+  return document.getElementById(id);
+}
+
+function video() {
+  return get('v');
+}
+
+function seekStarted() {
+  gSeekStarted = true;
+}
+
+function seekEnded() {
+  gSeekEnded = true;
+  video().play();
+}
+
+function loadedFirstFrame() {
+  gLoadedFirstFrameCount++;
+  ok(gLoadedFirstFrameCount <= 1, "No more than 1 onloadedfirstframe events");
+}
+
+function loadedMetaData() {
+  gLoadedMetaDataCount++;
+  ok(gLoadedMetaDataCount <= 1, "No more than 1 onloadedmetadata events");
+  video().play();
+  return false;
+}
+
+function playbackEnded() {
+  if (!gEnded) {
+    video().currentTime = 0;
+    gEnded = true;
+  } else {
+    ok(gSeekEnded, "Should have received seekended");
+    ok(gSeekStarted, "Should have received seekstarted");
+    ok(gLoadedFirstFrameCount == 1, "Should have 1 onloadedfirstframe event");
+    ok(gLoadedMetaDataCount == 1, "Should have 1 onloadedmetadata event");
+    SimpleTest.finish();    
+  }  
+  return false;
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>