Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 31 Jul 2013 13:47:57 -0400
changeset 153055 fd4e429db75ebb975e59aceb116384aaa671d2ae
parent 153054 0021058a0c88640f04a4717a520d8071265c4bf9 (current diff)
parent 153045 95870d5337eb479fa93898adc925fa60242e2858 (diff)
child 153056 036e937a22a264198aef8ab80c269207bfc488c5
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team.
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "12379f829ad18e0562c527e685e376ffc4c48994", 
+    "revision": "3ed7544ee8f48cec10bff2515c9393a4dbf21ae2", 
     "repo_path": "/integration/gaia-central"
 }
--- a/content/media/encoder/MediaEncoder.cpp
+++ b/content/media/encoder/MediaEncoder.cpp
@@ -179,17 +179,16 @@ MediaEncoder::GetEncodedData(nsTArray<ns
           break;
         }
 
         rv = mWriter->GetContainerData(aOutputBufs,
                                        ContainerWriter::FLUSH_NEEDED);
         if (NS_SUCCEEDED(rv)) {
           // Successfully get the copy of final container data from writer.
           reloop = false;
-          break;
         }
       } else {
         // No more headers, starts to encode tracks.
         mState = ENCODE_TRACK;
       }
       break;
     }
 
@@ -214,17 +213,16 @@ MediaEncoder::GetEncodedData(nsTArray<ns
       }
 
       rv = mWriter->GetContainerData(aOutputBufs,
                                      mAudioEncoder->IsEncodingComplete() ?
                                      ContainerWriter::FLUSH_NEEDED : 0);
       if (NS_SUCCEEDED(rv)) {
         // Successfully get the copy of final container data from writer.
         reloop = false;
-        break;
       }
 
       mState = (mAudioEncoder->IsEncodingComplete()) ? ENCODE_DONE : ENCODE_TRACK;
       break;
     }
 
     case ENCODE_DONE:
       LOG("MediaEncoder has been shutdown.");
--- a/content/media/encoder/OpusTrackEncoder.cpp
+++ b/content/media/encoder/OpusTrackEncoder.cpp
@@ -178,17 +178,17 @@ OpusTrackEncoder::GetHeader(nsTArray<uin
   {
     // Wait if mEncoder is not initialized.
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     while (!mCanceled && !mEncoder) {
       mReentrantMonitor.Wait();
     }
   }
 
-  if (mCanceled) {
+  if (mCanceled || mDoneEncoding) {
     return NS_ERROR_FAILURE;
   }
 
   switch (mEncoderState) {
   case ID_HEADER:
   {
     mLookahead = 0;
     int error = opus_encoder_ctl(mEncoder, OPUS_GET_LOOKAHEAD(&mLookahead));
@@ -237,17 +237,17 @@ OpusTrackEncoder::GetEncodedTrack(nsTArr
     // Wait if mEncoder is not initialized, or when not enough raw data, but is
     // not the end of stream nor is being canceled.
     while (!mCanceled && (!mEncoder || (mRawSegment->GetDuration() +
            mSourceSegment->GetDuration() < GetPacketDuration() &&
            !mEndOfStream))) {
       mReentrantMonitor.Wait();
     }
 
-    if (mCanceled) {
+    if (mCanceled || mDoneEncoding) {
       return NS_ERROR_FAILURE;
     }
 
     mSourceSegment->AppendFrom(mRawSegment);
 
     // Pad |mLookahead| samples to the end of source stream to prevent lost of
     // original data, the pcm duration will be calculated at rate 48K later.
     if (mEndOfStream) {
--- a/content/media/encoder/TrackEncoder.cpp
+++ b/content/media/encoder/TrackEncoder.cpp
@@ -11,17 +11,18 @@
 #include <android/log.h>
 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediakEncoder", ## args);
 #else
 #define LOG(args, ...)
 #endif
 
 namespace mozilla {
 
-#define MAX_FRAMES_TO_DROP  48000
+static const int  DEFAULT_CHANNELS = 1;
+static const int  DEFAULT_SAMPLING_RATE = 16000;
 
 void
 AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
                                             TrackID aID,
                                             TrackRate aTrackRate,
                                             TrackTicks aTrackOffset,
                                             uint32_t aTrackEvents,
                                             const MediaSegment& aQueuedMedia)
@@ -29,68 +30,84 @@ AudioTrackEncoder::NotifyQueuedTrackChan
   AudioSegment* audio = const_cast<AudioSegment*>
                         (static_cast<const AudioSegment*>(&aQueuedMedia));
 
   // Check and initialize parameters for codec encoder.
   if (!mInitialized) {
     AudioSegment::ChunkIterator iter(*audio);
     while (!iter.IsEnded()) {
       AudioChunk chunk = *iter;
-      if (chunk.mBuffer) {
-        Init(chunk.mChannelData.Length(), aTrackRate);
-        break;
+
+      // The number of channels is determined by the first non-null chunk, and
+      // thus the audio encoder is initialized at this time.
+      if (!chunk.IsNull()) {
+        nsresult rv = Init(chunk.mChannelData.Length(), aTrackRate);
+        if (NS_SUCCEEDED(rv)) {
+          break;
+        }
+      } else {
+        mSilentDuration += chunk.mDuration;
       }
       iter.Next();
     }
   }
 
   // Append and consume this raw segment.
-  AppendAudioSegment(audio);
+  if (mInitialized) {
+    AppendAudioSegment(audio);
+  }
 
   // The stream has stopped and reached the end of track.
   if (aTrackEvents == MediaStreamListener::TRACK_EVENT_ENDED) {
     LOG("[AudioTrackEncoder]: Receive TRACK_EVENT_ENDED .");
     NotifyEndOfStream();
   }
 }
 
 void
 AudioTrackEncoder::NotifyRemoved(MediaStreamGraph* aGraph)
 {
   // In case that MediaEncoder does not receive a TRACK_EVENT_ENDED event.
   LOG("[AudioTrackEncoder]: NotifyRemoved.");
+
+  // If source audio chunks are completely silent till the end of encoding,
+  // initialize the encoder with default channel counts and sampling rate, and
+  // append this many null data to the segment of track encoder.
+  if (!mInitialized && mSilentDuration > 0) {
+    Init(DEFAULT_CHANNELS, DEFAULT_SAMPLING_RATE);
+    mRawSegment->AppendNullData(mSilentDuration);
+    mSilentDuration = 0;
+  }
   NotifyEndOfStream();
 }
 
 nsresult
 AudioTrackEncoder::AppendAudioSegment(MediaSegment* aSegment)
 {
-  // Drop the in-coming segment if buffer(mRawSegment) is overflow.
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   AudioSegment* audio = static_cast<AudioSegment*>(aSegment);
   AudioSegment::ChunkIterator iter(*audio);
 
-  if (mRawSegment->GetDuration() < MAX_FRAMES_TO_DROP) {
-    while(!iter.IsEnded()) {
-      AudioChunk chunk = *iter;
-      if (chunk.mBuffer) {
-        mRawSegment->AppendAndConsumeChunk(&chunk);
-      }
-      iter.Next();
-    }
-    if (mRawSegment->GetDuration() >= GetPacketDuration()) {
-      mReentrantMonitor.NotifyAll();
-    }
+  // Append this many null data to our queued segment if there is a complete
+  // silence before the audio track encoder has initialized.
+  if (mSilentDuration > 0) {
+    mRawSegment->AppendNullData(mSilentDuration);
+    mSilentDuration = 0;
   }
-#ifdef DEBUG
-  else {
-    LOG("[AudioTrackEncoder]: A segment has dropped!");
+
+  while (!iter.IsEnded()) {
+    AudioChunk chunk = *iter;
+    // Append and consume both non-null and null chunks.
+    mRawSegment->AppendAndConsumeChunk(&chunk);
+    iter.Next();
   }
-#endif
+  if (mRawSegment->GetDuration() >= GetPacketDuration()) {
+    mReentrantMonitor.NotifyAll();
+  }
 
   return NS_OK;
 }
 
 static const int AUDIO_PROCESSING_FRAMES = 640; /* > 10ms of 48KHz audio */
 static const uint8_t gZeroChannel[MAX_AUDIO_SAMPLE_SIZE*AUDIO_PROCESSING_FRAMES] = {0};
 
 void
--- a/content/media/encoder/TrackEncoder.h
+++ b/content/media/encoder/TrackEncoder.h
@@ -69,16 +69,17 @@ public:
     , mChannels(0)
     , mSamplingRate(0)
     , mInitialized(false)
     , mDoneEncoding(false)
     , mReentrantMonitor("media.AudioEncoder")
     , mRawSegment(new AudioSegment())
     , mEndOfStream(false)
     , mCanceled(false)
+    , mSilentDuration(0)
   {}
 
   void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
                                 TrackRate aTrackRate,
                                 TrackTicks aTrackOffset,
                                 uint32_t aTrackEvents,
                                 const MediaSegment& aQueuedMedia) MOZ_OVERRIDE;
 
@@ -171,16 +172,22 @@ protected:
    */
   bool mEndOfStream;
 
   /**
    * True if a cancellation of encoding is sent from MediaEncoder, protected by
    * mReentrantMonitor.
    */
   bool mCanceled;
+
+  /**
+   * The total duration of null chunks we have received from MediaStreamGraph
+   * before initializing the audio track encoder.
+   */
+  TrackTicks mSilentDuration;
 };
 
 class VideoTrackEncoder : public TrackEncoder
 {
 
 };
 
 }
--- a/content/media/test/test_autoplay_contentEditable.html
+++ b/content/media/test/test_autoplay_contentEditable.html
@@ -32,16 +32,17 @@ function gotPlayEvent(event) {
 
 function goToNext(v) {
   v.parentNode.removeChild(v);
   manager.finished(v.token);
 }
 
 function initTest(test, token) {
   var v = document.createElement('video');
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
   v._state = 0;
  
   ["play", "canplay", "playing", "canplaythrough", "ended"].forEach(function (e) {
     v.addEventListener(e, gotPlayEvent, false);
   });
 
--- a/content/media/test/test_buffered.html
+++ b/content/media/test/test_buffered.html
@@ -67,16 +67,17 @@ function ended(e) {
 
   v.src = "";
   v.parentNode.removeChild(v);
   manager.finished(v.token);
 }
 
 function startTest(test, token) {
   var v = document.createElement('video');
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
 
   v.src = test.name;
   v._name = test.name;
   v._test = test;
   v._finished = false;
   v.autoplay = true;
--- a/content/media/test/test_bug448534.html
+++ b/content/media/test/test_bug448534.html
@@ -40,16 +40,17 @@ function stopped(event) {
   v._finished = true;
   ok(v.paused, "Video should be paused after removing from the Document");
   manager.finished(v.token);
 }
 
 
 function startTest(test, token) {
   var v = document.createElement('video');
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
   v.src = test.name;
   v._played = false;
   v._finished = false;
   v.addEventListener("loadedmetadata", loaded, false);
   v.addEventListener("play", started, false);
   v.addEventListener("pause", stopped, false);
--- a/content/media/test/test_bug463162.xhtml
+++ b/content/media/test/test_bug463162.xhtml
@@ -40,20 +40,20 @@ function onMetaData(id) {
   dump('onMetaData('+id+') expected ' + gExpectedResult[id] + ' gResultCount=' + gResultCount + '\n');
   if (gResultCount == 4)
     SimpleTest.finish();
 }
 
 ]]>
 </script>
 
-<video id='a1' onloadedmetadata="onMetaData('a1');"><sauce/><source type="bad" src="404" onerror="onError(event, 'a1');"/></video>
-<video id='a2' onloadedmetadata="onMetaData('a2');"><source onerror="onError(event, 'a2');"/></video>
-<video id='a3' onloadedmetadata="onMetaData('a3');"><html:source onerror="onError(event, 'a3');"/></video>
-<video id='a4' onloadedmetadata="onMetaData('a4');"><svg:source/><source onerror="onError(event, 'a4');" type="bad" src="404"/></video>
+<video id="a1" preload="metadata" onloadedmetadata="onMetaData('a1');"><sauce/><source type="bad" src="404" onerror="onError(event, 'a1');"/></video>
+<video id="a2" preload="metadata" onloadedmetadata="onMetaData('a2');"><source onerror="onError(event, 'a2');"/></video>
+<video id="a3" preload="metadata" onloadedmetadata="onMetaData('a3');"><html:source onerror="onError(event, 'a3');"/></video>
+<video id="a4" preload="metadata" onloadedmetadata="onMetaData('a4');"><svg:source/><source onerror="onError(event, 'a4');" type="bad" src="404"/></video>
 
 <script class="testbody" type="text/javascript">
 <![CDATA[
 
 function setSource(id, res) {
   var v = document.getElementById(id);
   v.firstChild.src = res.name;
   v.firstChild.type = res.type;
--- a/content/media/test/test_bug465498.html
+++ b/content/media/test/test_bug465498.html
@@ -42,16 +42,17 @@ function seekEnded(e) {
   manager.finished(v.token);
 }
 
 function initTest(test, token) {
   var type = getMajorMimeType(test.type);
   var v = document.createElement(type);
   if (!v.canPlayType(test.type))
     return;
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
   v._name = test.name;
   
   var s = document.createElement("source");
   s.type = test.type;
   s.src = test.name;
   v.appendChild(s);
--- a/content/media/test/test_bug686137.html
+++ b/content/media/test/test_bug686137.html
@@ -7,17 +7,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <head>
   <title>Media test: changing mozFrameBufferLength</title>
   <script type="text/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=686137">Mozilla Bug 686137</a>
 
-<audio id='a1' controls muted></audio>
+<audio id="a1" controls muted preload="metadata"></audio>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var testFile = "bug495794.ogg";
 var a1 = document.getElementById('a1');
 
 function audioAvailable(event) {
   a1.removeEventListener("MozAudioAvailable", audioAvailable);
--- a/content/media/test/test_contentDuration1.html
+++ b/content/media/test/test_contentDuration1.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d == 233, "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration1.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration2.html
+++ b/content/media/test/test_contentDuration2.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d == 233, "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration2.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration3.html
+++ b/content/media/test/test_contentDuration3.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d.toString() == "Infinity", "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration3.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration4.html
+++ b/content/media/test/test_contentDuration4.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d.toString() == "Infinity", "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration4.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration5.html
+++ b/content/media/test/test_contentDuration5.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d.toString() == "Infinity", "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration5.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration6.html
+++ b/content/media/test/test_contentDuration6.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d.toString() == "Infinity", "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration6.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_contentDuration7.html
+++ b/content/media/test/test_contentDuration7.html
@@ -20,12 +20,13 @@ function on_metadataloaded() {
   ok(d == 233, "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='contentDuration7.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_decoder_disable.html
+++ b/content/media/test/test_decoder_disable.html
@@ -6,40 +6,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 <head>
   <title>Test for Bug 448600</title>
   <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=448600">Mozilla Bug 448600</a>
 <p id="display"></p>
-<div id="content" style="display: none">
-</div>
+
 
 <pre id="test">
 <script type="application/javascript">
 
 function filename(uri) {
   return uri.substr(uri.lastIndexOf("/")+1);
 }
 
 function e(id) {
   return document.getElementById(id);
 }
 
-netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-var prefService = Components.classes["@mozilla.org/preferences-service;1"]
-               .getService(Components.interfaces.nsIPrefService);
-var branch = prefService.getBranch("media.");
-var gOldOggPref = branch.getBoolPref("ogg.enabled");
-var gOldWavePref = branch.getBoolPref("wave.enabled");
-
-branch.setBoolPref("ogg.enabled", false);
-branch.setBoolPref("wave.enabled", false);
-
 var gLoadError = new Object();
 
 gLoadError['video1'] = 0; 
 gLoadError['video2'] = 0;
 gLoadError['video3'] = 0;
 
 var gErrorCount = 0;
 
@@ -54,39 +43,36 @@ function finishTest() {
      'video2 currentSrc should match src');
   is(filename(e('video3').currentSrc),
      filename(e('video3').src),
      'video3 currentSrc should match src');
 
   is(gLoadError['video1'], 2, "Expect one error per invalid source child on video1");
   is(gLoadError['video2'], 1, "Expect one error on video2");
   is(gLoadError['video3'], 1, "Expect one error on video3");
-  
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
-  branch.setBoolPref("ogg.enabled", gOldOggPref);
-  branch.setBoolPref("wave.enabled", gOldWavePref);
 
   SimpleTest.finish();
 }
 
 function videoError(event, id) {
   gLoadError[id]++;
   gErrorCount++;
   if (gErrorCount >= 4) {
     finishTest();
   }
 }
 
 </script>
 <!-- We make the resource URIs unique to ensure that they are (re)loaded with the new disable-decoder prefs. -->
-<video id="video1">
-  <source type="video/ogg" src="320x240.ogv?decoder_disabled=1" onerror="videoError(event, 'video1');"/>
-  <source type="audio/wave" src="r11025_u8_c1.wav?decoder_disabled=1" id='s2' onerror="videoError(event, 'video1');"/>
-</video>
+<div id="content">
+</div>
+<script>
+function makeVideos() {
+  document.getElementById('content').innerHTML = '<video id="video1" preload="metadata"><source type="video/ogg" src="320x240.ogv?decoder_disabled=1" onerror="videoError(event, \'video1\');"/><source type="audio/wave" src="r11025_u8_c1.wav?decoder_disabled=1" id=\'s2\' onerror="videoError(event, \'video1\');"/></video><video id="video2" preload="metadata" src="320x240.ogv?decoder_disabled=2" onerror="videoError(event, \'video2\');"></video><video id="video3" preload="metadata" src="r11025_u8_c1.wav?decoder_disabled=2" onerror="videoError(event, \'video3\');"></video>';
+}
 
-<video id="video2" src="320x240.ogv?decoder_disabled=2" onerror="videoError(event, 'video2');"></video>
-<video id="video3" src="r11025_u8_c1.wav?decoder_disabled=2" onerror="videoError(event, 'video3');"></video>
+SpecialPowers.pushPrefEnv({"set": [["media.ogg.enabled", false], ["media.wave.enabled", false]]}, makeVideos);
+</script>
 
 </pre>
 
 </body>
 </html>
--- a/content/media/test/test_fragment_noplay.html
+++ b/content/media/test/test_fragment_noplay.html
@@ -96,16 +96,17 @@ function createTestArray() {
     }
   }
   return tests;
 }
 
 function startTest(test, token) {
   var v = document.createElement('video');
   manager.started(token);
+  v.preload = "metadata";
   v.src = test.name;
   v.token = token;
   v.controls = true;
   document.body.appendChild(v);
   var name = test.name + " fragment test";
   var localIs = function(name) { return function(a, b, msg) {
     is(a, b, name + ": " + msg);
   }}(name);
--- a/content/media/test/test_fragment_play.html
+++ b/content/media/test/test_fragment_play.html
@@ -60,16 +60,17 @@ function createTestArray() {
 
 function startTest(test, token) {
   if (test.todo) {
     todo(false, test.todo);
     return;
   }
   var v = document.createElement('video');
   manager.started(token);
+  v.preload = "metadata";
   v.src = test.name;
   v.token = token;
   v.controls = true;
   document.body.appendChild(v);
   var name = test.name + " fragment test";
   var localIs = function(name) { return function(a, b, msg) {
     is(a, b, name + ": " + msg);
   }}(name);
--- a/content/media/test/test_framebuffer.html
+++ b/content/media/test/test_framebuffer.html
@@ -8,17 +8,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Media test: framebuffer size checks</title>
   <script type="text/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=490705">Mozilla Bug 490705</a>
 
 <!-- mute audio, since there is no need to hear the sound for these tests -->
-<audio id='a1' controls></audio>
+<audio id="a1" preload="metadata" controls></audio>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var testFile = "bug495794.ogg";
 var testFileDuration = 0.30;
 var testFileChannelCount = 2;
 var testFileSampleRate = 48000;
 var testFileFrameBufferLength = testFileChannelCount * 1024;
--- a/content/media/test/test_media_selection.html
+++ b/content/media/test/test_media_selection.html
@@ -9,16 +9,17 @@
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var manager = new MediaTestManager;
 
 function maketest(attach_media, name, type, check_metadata) {
   return function (token) {
     var e = document.createElement('video');
+    e.preload = "metadata";
     manager.started(token);
     var errorRun = false;
     if (check_metadata) {
       e.addEventListener('loadedmetadata', function () {
           ok(e.readyState >= HTMLMediaElement.HAVE_METADATA,
              'test ' +  token + ' readyState ' + e.readyState + ' expected >= ' + HTMLMediaElement.HAVE_METADATA);
           is(e.currentSrc.substring(e.currentSrc.length - name.length), name, 'test ' + token);
           // The load can go idle due to cache size limits
--- a/content/media/test/test_play_twice.html
+++ b/content/media/test/test_play_twice.html
@@ -9,16 +9,17 @@
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
   var v = document.createElement('video');
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
   v.src = test.name;
   v.name = test.name;
   v.playingCount = 0;
   var check = function(test, v) { return function() {
     checkMetadata(test.name, v, test);
   }}(test, v);
--- a/content/media/test/test_playback.html
+++ b/content/media/test/test_playback.html
@@ -9,16 +9,17 @@
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
   var v = document.createElement('video');
+  v.preload = "metadata";
   v.token = token;
   manager.started(token);
 
   v.src = test.name;
   v.name = test.name;
   var check = function(test, v) { return function() {
     is(test.name, v.name, "Name should match test.name #1");
     checkMetadata(test.name, v, test);
--- a/content/media/test/test_playback_rate.html
+++ b/content/media/test/test_playback_rate.html
@@ -150,16 +150,17 @@ function onwaiting(e) {
 function onvolumechange(e) {
   ok(false, "We should not receive a volumechange event when changing the playback rate.");
 }
 
 function startTest(test, token) {
   let elemType = /^audio/.test(test.type) ? "audio" : "video";
   let element = document.createElement(elemType);
   element.src = test.name;
+  element.preload = "metadata";
   element.token = token;
   element.controls = true;
   element.bufferingTime = 0;
   document.body.appendChild(element);
   element.addEventListener("ratechange", onratechange);
   element.addEventListener("timeupdate", ontimeupdate);
   element.addEventListener("ended", onended);
   element.addEventListener("waiting", onwaiting);
--- a/content/media/test/test_seek.html
+++ b/content/media/test/test_seek.html
@@ -57,16 +57,17 @@ function createTestArray() {
   }
   return tests;
 }
 
 function startTest(test, token) {
   var v = document.createElement('video');
   manager.started(token);
   v.src = test.name;
+  v.preload = "metadata";
   v.token = token;
   document.body.appendChild(v);
   var name = test.name + " seek test " + test.number;
   var localIs = function(name) { return function(a, b, msg) {
     is(a, b, name + ": " + msg);
   }}(name);
   var localOk = function(name) { return function(a, msg) {
     ok(a, name + ": " + msg);
--- a/content/media/test/test_seekLies.html
+++ b/content/media/test/test_seekLies.html
@@ -19,12 +19,13 @@ function on_metadataloaded() {
   ok(d == 4000, "Checking duration: " + d);
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+       preload="metadata"
        src='seekLies.sjs'
        onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_seekable2.html
+++ b/content/media/test/test_seekable2.html
@@ -25,12 +25,13 @@ function on_metadataloaded() {
 
   v.play();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <video id='v'
+preload="metadata"
 src='contentDuration6.sjs'
 onloadedmetadata='on_metadataloaded();'></video>
 </body>
 </html>
--- a/content/media/test/test_wave_data_s16.html
+++ b/content/media/test/test_wave_data_s16.html
@@ -38,13 +38,14 @@ function startTest() {
   v.addEventListener('MozAudioAvailable', audioavailable, false);
   v.play();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <audio id='v'
+       preload="metadata"
        onloadedmetadata='return startTest();'>
   <source type='audio/x-wav' src='wavedata_s16.wav'>
 </audio>
 </body>
 </html>
--- a/content/media/test/test_wave_data_u8.html
+++ b/content/media/test/test_wave_data_u8.html
@@ -38,13 +38,14 @@ function startTest() {
   v.addEventListener('MozAudioAvailable', audioavailable, false);
   v.play();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 <audio id='v'
+       preload="metadata"
        onloadedmetadata='return startTest();'>
   <source type='audio/x-wav' src='wavedata_u8.wav'>
 </audio>
 </body>
 </html>
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -1845,18 +1845,17 @@ BluetoothDBusService::SendDiscoveryMessa
 }
 
 nsresult
 BluetoothDBusService::SendSinkMessage(const nsAString& aDeviceAddress,
                                       const nsAString& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mConnection);
-
-  NS_ENSURE_TRUE(IsReady(), NS_ERROR_FAILURE);
+  MOZ_ASSERT(IsEnabled());
 
   SinkCallback callback;
   if (aMessage.EqualsLiteral("Connect")) {
     callback = SinkConnectCallback;
   } else if (aMessage.EqualsLiteral("Disconnect")) {
     callback = SinkDisconnectCallback;
   } else {
     BT_WARNING("Unknown sink message");
--- a/testing/marionette/client/setup.py
+++ b/testing/marionette/client/setup.py
@@ -1,12 +1,12 @@
 import os
 from setuptools import setup, find_packages
 
-version = '0.5.35'
+version = '0.5.36'
 
 # get documentation from the README
 try:
     here = os.path.dirname(os.path.abspath(__file__))
     description = file(os.path.join(here, 'README.md')).read()
 except (OSError, IOError):
     description = ''
 
--- a/testing/mochitest/android.json
+++ b/testing/mochitest/android.json
@@ -93,40 +93,17 @@
  "content/html/content/test/test_object_plugin_nav.html": "TIMED_OUT",
  "content/html/content/test/test_video_wakelock.html": "bug 871015",
  "content/html/document/test/test_bug199692.html": "bug 811644",
  "content/html/document/test/test_bug369370.html": "",
  "content/html/document/test/test_bug391777.html": "",
  "content/html/document/test/test_bug445004.html": "",
  "content/html/document/test/test_bug446483.html": "",
  "content/html/document/test/test_bug741266.html": "",
- "content/media/test/test_autoplay_contentEditable.html": "",
  "content/media/test/test_buffered.html": "",
- "content/media/test/test_bug448534.html": "",
- "content/media/test/test_bug463162.xhtml": "",
- "content/media/test/test_bug686137.html": "TIMED_OUT",
- "content/media/test/test_contentDuration1.html": "TIMED_OUT",
- "content/media/test/test_contentDuration2.html": "TIMED_OUT",
- "content/media/test/test_contentDuration3.html": "TIMED_OUT",
- "content/media/test/test_contentDuration4.html": "TIMED_OUT",
- "content/media/test/test_contentDuration5.html": "TIMED_OUT",
- "content/media/test/test_contentDuration6.html": "TIMED_OUT",
- "content/media/test/test_contentDuration7.html": "",
- "content/media/test/test_decoder_disable.html": "",
- "content/media/test/test_fragment_noplay.html": "",
- "content/media/test/test_fragment_play.html": "",
- "content/media/test/test_framebuffer.html": "",
- "content/media/test/test_media_selection.html": "",
- "content/media/test/test_playback.html": "",
- "content/media/test/test_playback_rate.html": "bug 845162",
- "content/media/test/test_seek.html": "bug 845162",
- "content/media/test/test_seekLies.html": "TIMED_OUT",
- "content/media/test/test_seekable2.html": "",
- "content/media/test/test_wave_data_s16.html": "TIMED_OUT",
- "content/media/test/test_wave_data_u8.html": "TIMED_OUT",
  "content/media/webspeech/synth/ipc/test/test_ipc.html": "bug 857673",
  "content/media/webspeech/recognition/test/test_nested_eventloop.html": "",
  "content/smil/test/test_smilRepeatTiming.xhtml": "TIMED_OUT",
  "content/smil/test/test_smilExtDoc.xhtml": "",
  "content/xul/content/test/test_bug486990.xul": "TIMED_OUT",
  "docshell/test/navigation/test_bug13871.html": "RANDOM",
  "docshell/test/navigation/test_bug430723.html": "TIMED_OUT",
  "docshell/test/navigation/test_popup-navigates-children.html": "bug 783589",
--- a/testing/mochitest/androidx86.json
+++ b/testing/mochitest/androidx86.json
@@ -90,38 +90,17 @@
  "content/html/content/test/test_iframe_sandbox_plugins.html": "",
  "content/html/content/test/test_object_plugin_nav.html": "TIMED_OUT",
  "content/html/document/test/test_bug199692.html": "bug 811644",
  "content/html/document/test/test_bug369370.html": "",
  "content/html/document/test/test_bug391777.html": "",
  "content/html/document/test/test_bug445004.html": "",
  "content/html/document/test/test_bug446483.html": "",
  "content/html/document/test/test_bug741266.html": "",
- "content/media/test/test_autoplay_contentEditable.html": "",
  "content/media/test/test_buffered.html": "",
- "content/media/test/test_bug448534.html": "",
- "content/media/test/test_bug463162.xhtml": "",
- "content/media/test/test_bug686137.html": "TIMED_OUT",
- "content/media/test/test_contentDuration1.html": "TIMED_OUT",
- "content/media/test/test_contentDuration2.html": "TIMED_OUT",
- "content/media/test/test_contentDuration3.html": "TIMED_OUT",
- "content/media/test/test_contentDuration4.html": "TIMED_OUT",
- "content/media/test/test_contentDuration5.html": "TIMED_OUT",
- "content/media/test/test_contentDuration6.html": "TIMED_OUT",
- "content/media/test/test_contentDuration7.html": "",
- "content/media/test/test_decoder_disable.html": "",
- "content/media/test/test_fragment_noplay.html": "",
- "content/media/test/test_fragment_play.html": "",
- "content/media/test/test_framebuffer.html": "",
- "content/media/test/test_media_selection.html": "",
- "content/media/test/test_playback.html": "",
- "content/media/test/test_seekLies.html": "TIMED_OUT",
- "content/media/test/test_seekable2.html": "",
- "content/media/test/test_wave_data_s16.html": "TIMED_OUT",
- "content/media/test/test_wave_data_u8.html": "TIMED_OUT",
  "content/media/webaudio/test/test_currentTime.html": "bug 868116",
  "content/media/webaudio/test/test_delayNode.html": "bug 865642",
  "content/media/webaudio/test/test_delayNodeWithGain.html": "bug 865642",
  "content/media/webaudio/test/test_gainNode.html": "bug 865642",
  "content/media/webaudio/test/test_scriptProcessorNode.html": "bug 865642",
  "content/media/webaudio/test/test_scriptProcessorNodeChannelCount.html": "bug 865642",
  "content/media/webspeech/synth/ipc/test/test_ipc.html": "bug 857673",
  "content/media/webspeech/recognition/test/test_nested_eventloop.html": "",
--- a/testing/mochitest/b2g.json
+++ b/testing/mochitest/b2g.json
@@ -5,73 +5,51 @@
     "docshell": "",
     "dom": "",
     "layout": ""
   },
 "excludetests": {
     "content/xbl/":"",
     "content/xul":"",
 
-    "content/media/test/test_bug448534.html": "",
+    "content/media/test/test_bug448534.html": "Timed out, bug 894922?",
     "content/media/test/test_bug495300.html":"",
-    "content/media/test/test_bug495300.html":"",
-    "content/media/test/test_bug463162.xhtml":"",
     "content/media/test/test_bug495145.html": "timed out",
     "content/media/test/test_bug686942.html": "timed out",
-    "content/media/test/test_bug686137.html": "TIMED_OUT",
     "content/media/test/test_can_play_type.html":"timed out",
     "content/media/test/test_chaining.html": "timed out",
-    "content/media/test/test_contentDuration1.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration2.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration3.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration4.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration5.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration6.html": "TIMED_OUT",
-    "content/media/test/test_contentDuration7.html": "timed out",
-    "content/media/test/test_decoder_disable.html":"timed out",
     "content/media/test/test_error_on_404.html": "timed out",
-    "content/media/test/test_fragment_noplay.html": "timed out",
-    "content/media/test/test_fragment_play.html": "",
     "content/media/test/test_load.html": "Timed out after gizmo.mp4",
     "content/media/test/test_load_candidates.html": "timed out",
     "content/media/test/test_load_same_resource.html": "",
-    "content/media/test/test_media_selection.html": "",
+    "content/media/test/test_media_selection.html": "timed out",
     "content/media/test/test_metadata.html": "",
     "content/media/test/test_mozHasAudio.html": "",
     "content/media/test/test_playback_rate_playpause.html": "",
     "content/media/test/test_reactivate.html": "timed out in small-shot.mp3",
     "content/media/test/test_referer.html":"",
     "content/media/test/test_replay_metadata.html": "",
     "content/media/test/test_seekable1.html": "",
     "content/media/test/test_seek_out_of_range.html": "",
-    "content/media/test/test_seekLies.html": "",
-    "content/media/test/test_wave_data_s16.html": "",
     "content/media/test/test_source.html": "",
     "content/media/test/test_source_media.html": "",
-    "content/media/test/test_wave_data_u8.html": "",
 
     "content/media/mediasource/test/test_MediaSource.html": " ReferenceError: MediaSource is not defined",
     "content/media/test/test_bug654550.html": "timed out",
     "content/media/test/test_delay_load.html": "6 failures",
     "content/media/test/test_info_leak.html": "2 failures",
     "content/media/test/test_play_events.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough",
     "content/media/test/test_play_events_2.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough",
-    "content/media/test/test_playback.html": "Test timed out",
-    "content/media/test/test_play_events.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough",
-    "content/media/test/test_play_events_2.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough",
-    "content/media/test/test_playback.html": "Test timed out",
+    "content/media/test/test_playback.html": "Test timed out, bug 668973?",
     "content/media/test/test_streams_gc.html": "Value being assigned to HTMLMediaElement.currentTime is not a finite floating-point value",
-    "content/media/webaudio/test/test_audioBufferSourceNodeNeutered.html": "Test timed out",
-    "content/media/webaudio/test/test_audioBufferSourceNodeNeutered.html": " Test timed out",
     "content/media/webspeech/recognition/test/test_nested_eventloop.html": "NS_ERROR_NOT_AVAILABLE: [nsIDOMWindow.showModalDialog]",
     "content/media/webspeech/synth/ipc/test/test_ipc.html": "comp.classes['@mozilla.org/special-powers-observer;1'] is undefined",
     "content/media/webspeech/synth/test/test_speech_queue.html": "Test timed out",
     "content/media/webspeech/synth/test/test_speech_simple.html": "Test timed out",
     "content/media/test/test_framebuffer.html": "timed out",
-    "content/media/test/test_seekable2.html": "timed out",
     "content/media/test/test_seekable3.html": "timed out",
     "content/media/webspeech/recognition/test/test_recognition_service_error.html": "timed out",
     "content/media/test/test_can_play_type_mpeg.html":"7 failures out of 27",
     "content/media/test/test_unseekable.html":"",
     "content/media/webaudio/test/test_audioBufferSourceNodeOffset.html":"",
     "content/media/test/test_can_play_type_ogg.html":"",
     "content/media/test/test_can_play_type_no_dash.html":"",