Back out 7 changesets (bug 1231793) for Windows crashes in mozilla::MediaDecoderReader::~MediaDecoderReader()
authorPhil Ringnalda <philringnalda@gmail.com>
Mon, 15 Feb 2016 09:46:19 -0800
changeset 320578 52d290be7c7dab9c3dedbd372e131358c3e285e2
parent 320577 3e5b6df276a9a20fe7b3655656e62a09bc46aaa9
child 320579 b5a5b34ce7d2bee5be119883464bfcad048c4a0e
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1231793
milestone47.0a1
backs out273cc690d7cfcf155ca522499f08ba34430e2d07
d79218caeefc464cca4eb72a6db4146ab3d81c40
75c7942267f809bf71ebff8e1061e8ddda79883d
684e62a4d9f50293bf4ae2b9006916ed269a2434
a5a15d50a8e4f1c49bcc27ecab5ca9e5fa69392d
33d6f22d9b1f388219791679203bd9c63c630d1d
cd4fc7f2c80a3c54482e3c8d59245a861a033cd6
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
Back out 7 changesets (bug 1231793) for Windows crashes in mozilla::MediaDecoderReader::~MediaDecoderReader() Backed out changeset 273cc690d7cf (bug 1231793) Backed out changeset d79218caeefc (bug 1231793) Backed out changeset 75c7942267f8 (bug 1231793) Backed out changeset 684e62a4d9f5 (bug 1231793) Backed out changeset a5a15d50a8e4 (bug 1231793) Backed out changeset 33d6f22d9b1f (bug 1231793) Backed out changeset cd4fc7f2c80a (bug 1231793)
dom/media/AudioSampleFormat.h
dom/media/DecoderTraits.cpp
dom/media/MediaFormatReader.cpp
dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
dom/media/platforms/agnostic/WAVDecoder.cpp
dom/media/platforms/agnostic/WAVDecoder.h
dom/media/platforms/android/AndroidDecoderModule.cpp
dom/media/platforms/moz.build
dom/media/test/manifest.js
dom/media/test/test_decode_error.html
dom/media/wave/WaveDecoder.cpp
dom/media/wave/WaveDecoder.h
dom/media/wave/WaveDemuxer.cpp
dom/media/wave/WaveDemuxer.h
dom/media/wave/moz.build
dom/media/webaudio/test/test_decodeMultichannel.html
media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
modules/libpref/init/all.js
--- a/dom/media/AudioSampleFormat.h
+++ b/dom/media/AudioSampleFormat.h
@@ -91,55 +91,29 @@ FloatToAudioSample<float>(float aValue)
 template <> inline int16_t
 FloatToAudioSample<int16_t>(float aValue)
 {
   float v = aValue*32768.0f;
   float clamped = std::max(-32768.0f, std::min(32767.0f, v));
   return int16_t(clamped);
 }
 
-template <typename T> T UInt8bitToAudioSample(uint8_t aValue);
-
-template <> inline float
-UInt8bitToAudioSample<float>(uint8_t aValue)
-{
-  return aValue * (static_cast<float>(2) / UINT8_MAX) - static_cast<float>(1);
-}
-template <> inline int16_t
-UInt8bitToAudioSample<int16_t>(uint8_t aValue)
-{
-  return (int16_t(aValue) << 8) + aValue + INT16_MIN;
-}
-
 template <typename T> T IntegerToAudioSample(int16_t aValue);
 
 template <> inline float
 IntegerToAudioSample<float>(int16_t aValue)
 {
   return aValue / 32768.0f;
 }
 template <> inline int16_t
 IntegerToAudioSample<int16_t>(int16_t aValue)
 {
   return aValue;
 }
 
-template <typename T> T Int24bitToAudioSample(int32_t aValue);
-
-template <> inline float
-Int24bitToAudioSample<float>(int32_t aValue)
-{
-  return aValue / static_cast<float>(1 << 23);
-}
-template <> inline int16_t
-Int24bitToAudioSample<int16_t>(int32_t aValue)
-{
-  return aValue / 256;
-}
-
 template<typename SrcT, typename DstT>
 inline void
 ConvertAudioSample(SrcT aIn, DstT& aOut);
 
 template<>
 inline void
 ConvertAudioSample(int16_t aIn, int16_t & aOut)
 {
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -8,16 +8,19 @@
 #include "MediaDecoder.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsMimeTypes.h"
 #include "mozilla/Preferences.h"
 
 #include "OggDecoder.h"
 #include "OggReader.h"
 
+#include "WaveDecoder.h"
+#include "WaveReader.h"
+
 #include "WebMDecoder.h"
 #include "WebMDemuxer.h"
 
 #ifdef MOZ_RAW
 #include "RawDecoder.h"
 #include "RawReader.h"
 #endif
 #ifdef MOZ_ANDROID_OMX
@@ -43,19 +46,16 @@
 #include "MP4Decoder.h"
 #include "MP4Demuxer.h"
 #endif
 #include "MediaFormatReader.h"
 
 #include "MP3Decoder.h"
 #include "MP3Demuxer.h"
 
-#include "WaveDecoder.h"
-#include "WaveDemuxer.h"
-
 #include "ADTSDecoder.h"
 #include "ADTSDemuxer.h"
 
 namespace mozilla
 {
 
 template <class String>
 static bool
@@ -328,23 +328,16 @@ IsMP3SupportedType(const nsACString& aTy
 
 static bool
 IsAACSupportedType(const nsACString& aType,
                    const nsAString& aCodecs = EmptyString())
 {
   return ADTSDecoder::CanHandleMediaType(aType, aCodecs);
 }
 
-static bool
-IsWAVSupportedType(const nsACString& aType,
-                   const nsAString& aCodecs = EmptyString())
-{
-  return WaveDecoder::CanHandleMediaType(aType, aCodecs);
-}
-
 /* static */
 bool DecoderTraits::ShouldHandleMediaType(const char* aMIMEType)
 {
   if (IsWaveType(nsDependentCString(aMIMEType))) {
     // We should not return true for Wave types, since there are some
     // Wave codecs actually in use in the wild that we don't support, and
     // we should allow those to be handled by plugins or helper apps.
     // Furthermore people can play Wave files on most platforms by other
@@ -620,27 +613,27 @@ MediaDecoderReader* DecoderTraits::Creat
   } else
 #endif
   if (IsMP3SupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new mp3::MP3Demuxer(aDecoder->GetResource()));
   } else
   if (IsAACSupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
   } else
-  if (IsWAVSupportedType(aType)) {
-    decoderReader = new MediaFormatReader(aDecoder, new WAVDemuxer(aDecoder->GetResource()));
-  }
 #ifdef MOZ_RAW
   if (IsRawType(aType)) {
     decoderReader = new RawReader(aDecoder);
   } else
 #endif
   if (IsOggType(aType)) {
     decoderReader = new OggReader(aDecoder);
   } else
+  if (IsWaveType(aType)) {
+    decoderReader = new WaveReader(aDecoder);
+  } else
 #ifdef MOZ_OMX_DECODER
   if (IsOmxSupportedType(aType)) {
     decoderReader = new MediaOmxReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -336,17 +336,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
   if (!videoActive && !audioActive) {
     mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
     return;
   }
 
   mInitDone = true;
   RefPtr<MetadataHolder> metadata = new MetadataHolder();
   metadata->mInfo = mInfo;
-  metadata->mTags = tags->Count() ? tags.release() : nullptr;
+  metadata->mTags = nullptr;
   mMetadataPromise.Resolve(metadata, __func__);
 }
 
 void
 MediaFormatReader::OnDemuxerInitFailed(DemuxerFailureReason aFailure)
 {
   mDemuxerInitRequest.Complete();
   mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
--- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
@@ -3,27 +3,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AgnosticDecoderModule.h"
 #include "OpusDecoder.h"
 #include "VorbisDecoder.h"
 #include "VPXDecoder.h"
-#include "WAVDecoder.h"
 
 namespace mozilla {
 
 bool
 AgnosticDecoderModule::SupportsMimeType(const nsACString& aMimeType) const
 {
   return VPXDecoder::IsVPX(aMimeType) ||
     OpusDataDecoder::IsOpus(aMimeType) ||
-    VorbisDataDecoder::IsVorbis(aMimeType) ||
-    WaveDataDecoder::IsWave(aMimeType);
+    VorbisDataDecoder::IsVorbis(aMimeType);
 }
 
 already_AddRefed<MediaDataDecoder>
 AgnosticDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
                                           layers::LayersBackend aLayersBackend,
                                           layers::ImageContainer* aImageContainer,
                                           FlushableTaskQueue* aVideoTaskQueue,
                                           MediaDataDecoderCallback* aCallback)
@@ -50,18 +48,14 @@ AgnosticDecoderModule::CreateAudioDecode
   if (VorbisDataDecoder::IsVorbis(aConfig.mMimeType)) {
     m = new VorbisDataDecoder(*aConfig.GetAsAudioInfo(),
                               aAudioTaskQueue,
                               aCallback);
   } else if (OpusDataDecoder::IsOpus(aConfig.mMimeType)) {
     m = new OpusDataDecoder(*aConfig.GetAsAudioInfo(),
                             aAudioTaskQueue,
                             aCallback);
-  } else if (WaveDataDecoder::IsWave(aConfig.mMimeType)) {
-    m = new WaveDataDecoder(*aConfig.GetAsAudioInfo(),
-                            aAudioTaskQueue,
-                            aCallback);
   }
 
   return m.forget();
 }
 
 } // namespace mozilla
deleted file mode 100644
--- a/dom/media/platforms/agnostic/WAVDecoder.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WAVDecoder.h"
-#include "AudioSampleFormat.h"
-#include "nsAutoPtr.h"
-
-using mp4_demuxer::ByteReader;
-
-namespace mozilla {
-
-WaveDataDecoder::WaveDataDecoder(const AudioInfo& aConfig,
-                                 FlushableTaskQueue* aTaskQueue,
-                                 MediaDataDecoderCallback* aCallback)
-  : mInfo(aConfig)
-  , mTaskQueue(aTaskQueue)
-  , mCallback(aCallback)
-  , mFrames(0)
-{
-}
-
-nsresult
-WaveDataDecoder::Shutdown()
-{
-  return NS_OK;
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-WaveDataDecoder::Init()
-{
-  return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
-}
-
-nsresult
-WaveDataDecoder::Input(MediaRawData* aSample)
-{
-  nsCOMPtr<nsIRunnable> runnable(
-    NS_NewRunnableMethodWithArg<RefPtr<MediaRawData>>(
-      this, &WaveDataDecoder::Decode,
-      RefPtr<MediaRawData>(aSample)));
-  mTaskQueue->Dispatch(runnable.forget());
-
-  return NS_OK;
-}
-
-void
-WaveDataDecoder::Decode(MediaRawData* aSample)
-{
-  if (!DoDecode(aSample)) {
-    mCallback->Error();
-  } else if (mTaskQueue->IsEmpty()) {
-    mCallback->InputExhausted();
-  }
-}
-
-bool
-WaveDataDecoder::DoDecode(MediaRawData* aSample)
-{
-  size_t aLength = aSample->Size();
-  ByteReader aReader = ByteReader(aSample->Data(), aLength);
-  int64_t aOffset = aSample->mOffset;
-  uint64_t aTstampUsecs = aSample->mTime;
-
-  int32_t frames = aLength * 8 / mInfo.mBitDepth / mInfo.mChannels;
-
-  auto buffer = MakeUnique<AudioDataValue[]>(frames * mInfo.mChannels);
-  for (int i = 0; i < frames; ++i) {
-    for (unsigned int j = 0; j < mInfo.mChannels; ++j) {
-      if (mInfo.mBitDepth == 8) {
-        uint8_t v = aReader.ReadU8();
-        buffer[i * mInfo.mChannels + j] =
-            UInt8bitToAudioSample<AudioDataValue>(v);
-      } else if (mInfo.mBitDepth == 16) {
-        int16_t v = aReader.ReadLE16();
-        buffer[i * mInfo.mChannels + j] =
-            IntegerToAudioSample<AudioDataValue>(v);
-      } else if (mInfo.mBitDepth == 24) {
-        int32_t v = aReader.ReadLE24();
-        buffer[i * mInfo.mChannels + j] =
-            Int24bitToAudioSample<AudioDataValue>(v);
-      }
-    }
-  }
-
-  aReader.DiscardRemaining();
-
-  int64_t duration = frames / mInfo.mRate;
-
-  mCallback->Output(new AudioData(aOffset,
-                                  aTstampUsecs,
-                                  duration,
-                                  frames,
-                                  Move(buffer),
-                                  mInfo.mChannels,
-                                  mInfo.mRate));
-  mFrames += frames;
-
-  return true;
-}
-
-void
-WaveDataDecoder::DoDrain()
-{
-  mCallback->DrainComplete();
-}
-
-nsresult
-WaveDataDecoder::Drain()
-{
-  nsCOMPtr<nsIRunnable> runnable(
-    NS_NewRunnableMethod(this, &WaveDataDecoder::DoDrain));
-  mTaskQueue->Dispatch(runnable.forget());
-  return NS_OK;
-}
-
-nsresult
-WaveDataDecoder::Flush()
-{
-  mTaskQueue->Flush();
-  mFrames = 0;
-  return NS_OK;
-}
-
-/* static */
-bool
-WaveDataDecoder::IsWave(const nsACString& aMimeType)
-{
-  // Some WebAudio uses "audio/x-wav",
-  // WAVdemuxer uses "audio/wave; codecs=aNum".
-  return aMimeType.EqualsLiteral("audio/x-wav") ||
-         aMimeType.EqualsLiteral("audio/wave; codecs=1") ||
-         aMimeType.EqualsLiteral("audio/wave; codecs=65534");
-}
-
-} // namespace mozilla
-#undef LOG
\ No newline at end of file
deleted file mode 100644
--- a/dom/media/platforms/agnostic/WAVDecoder.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(WaveDecoder_h_)
-#define WaveDecoder_h_
-
-#include "PlatformDecoderModule.h"
-#include "mp4_demuxer/ByteReader.h"
-
-namespace mozilla {
-
-class WaveDataDecoder : public MediaDataDecoder
-{
-public:
-  WaveDataDecoder(const AudioInfo& aConfig,
-                  FlushableTaskQueue* aTaskQueue,
-                  MediaDataDecoderCallback* aCallback);
-
-  RefPtr<InitPromise> Init() override;
-  nsresult Input(MediaRawData* aSample) override;
-  nsresult Flush() override;
-  nsresult Drain() override;
-  nsresult Shutdown() override;
-  const char* GetDescriptionName() const override
-  {
-    return "wave audio decoder";
-  }
-
-  // Return true if mimetype is Wave
-  static bool IsWave(const nsACString& aMimeType);
-
-private:
-  void Decode (MediaRawData* aSample);
-  bool DoDecode (MediaRawData* aSample);
-  void DoDrain ();
-
-  const AudioInfo& mInfo;
-  RefPtr<FlushableTaskQueue> mTaskQueue;
-  MediaDataDecoderCallback* mCallback;
-
-  int64_t mFrames;
-};
-
-} // namespace mozilla
-#endif
\ No newline at end of file
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -253,25 +253,16 @@ AndroidDecoderModule::SupportsMimeType(c
     return false;
   }
 
   if (aMimeType.EqualsLiteral("video/mp4") ||
       aMimeType.EqualsLiteral("video/avc")) {
     return true;
   }
 
-  // When checking "audio/x-wav", CreateDecoder can cause a JNI ERROR by
-  // Accessing a stale local reference leading to a SIGSEGV crash.
-  // To avoid this we check for wav types here.
-  if (aMimeType.EqualsLiteral("audio/x-wav") ||
-      aMimeType.EqualsLiteral("audio/wave; codecs=1") ||
-      aMimeType.EqualsLiteral("audio/wave; codecs=65534")) {
-    return false;
-  }  
-
   return widget::HardwareCodecCapabilityUtils::FindDecoderCodecInfoForMimeType(
       nsCString(TranslateMimeType(aMimeType)));
 }
 
 already_AddRefed<MediaDataDecoder>
 AndroidDecoderModule::CreateVideoDecoder(
     const VideoInfo& aConfig, layers::LayersBackend aLayersBackend,
     layers::ImageContainer* aImageContainer, FlushableTaskQueue* aVideoTaskQueue,
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -16,17 +16,16 @@ EXPORTS += [
 ]
 
 UNIFIED_SOURCES += [
     'agnostic/AgnosticDecoderModule.cpp',
     'agnostic/BlankDecoderModule.cpp',
     'agnostic/OpusDecoder.cpp',
     'agnostic/VorbisDecoder.cpp',
     'agnostic/VPXDecoder.cpp',
-    'agnostic/WAVDecoder.cpp',
     'PDMFactory.cpp',
     'PlatformDecoderModule.cpp',
     'wrappers/FuzzingWrapper.cpp',
     'wrappers/H264Converter.cpp'
 ]
 
 DIRS += [
     'agnostic/gmp',
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -676,17 +676,16 @@ var gMetadataTests = [
   { name:"wave_metadata_unknown_tag.wav", tags: {
       name:"Track Title",
       comments:"Comments",
     }
   },
   { name:"wave_metadata_bad_len.wav", tags: {
       name:"Track Title",
       artist:"Artist Name",
-      comments:"Comments",
     }
   },
   { name:"wave_metadata_bad_no_null.wav", tags: {
       name:"Track Title",
       artist:"Artist Name",
       comments:"Comments!!",
     }
   },
--- a/dom/media/test/test_decode_error.html
+++ b/dom/media/test/test_decode_error.html
@@ -15,29 +15,34 @@ function startTest(test, token) {
   var v = document.createElement("video");
   manager.started(token);
   v.addEventListener("error", function (event) {
     var el = event.currentTarget;
     is(event.type, "error", "Expected event of type 'error'");
     ok(el.error, "Element 'error' attr expected to have a value");
     ok(el.error instanceof MediaError, "Element 'error' attr expected to be MediaError");
     is(el.error.code, MediaError.MEDIA_ERR_DECODE, "Expected a decode error");
+    is(el.networkState, HTMLMediaElement.NETWORK_EMPTY, "networkState should be EMPTY");
     el._sawError = true;
+  }, false);
+
+  v.addEventListener("emptied", function (event) {
+    var el = event.currentTarget;
+    is(el.networkState, HTMLMediaElement.NETWORK_EMPTY, "networkState should be EMPTY");
+    ok(el._sawError, "Expected error event");
     manager.finished(token);
   }, false);
 
-  v.addEventListener("loadeddata", function () {
-    ok(false, "Unexpected loadeddata event");
-    manager.finished(token);
+  v.addEventListener("loadedmetadata", function () {
+    ok(false, "Unexpected loadedmetadata event");
   }, false);
 
   v.autoplay = true;
   v.addEventListener("ended", function () {
     ok(false, "Unexpected ended event");
-    manager.finished(token);
   }, false);
 
   v.src = test.name; // implicitly starts a load.
 }
 
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest);
 function beginTest() {
--- a/dom/media/wave/WaveDecoder.cpp
+++ b/dom/media/wave/WaveDecoder.cpp
@@ -1,60 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WaveDemuxer.h"
-#include "mozilla/Preferences.h"
 #include "MediaDecoderStateMachine.h"
 #include "WaveReader.h"
 #include "WaveDecoder.h"
-#include "MediaFormatReader.h"
-#include "PDMFactory.h"
 
 namespace mozilla {
 
-MediaDecoder*
-WaveDecoder::Clone(MediaDecoderOwner* aOwner)
-{
-  if (!IsEnabled())
-    return nullptr;
-
-  return new WaveDecoder(aOwner);
-}
-
-MediaDecoderStateMachine*
-WaveDecoder::CreateStateMachine()
+MediaDecoderStateMachine* WaveDecoder::CreateStateMachine()
 {
-  if (Preferences::GetBool("media.wave.decoder.enabled")) {
-    RefPtr<MediaDecoderReader> reader =
-        new MediaFormatReader(this, new WAVDemuxer(GetResource()));
-    return new MediaDecoderStateMachine(this, reader);
-  } else {
-    return new MediaDecoderStateMachine(this, new WaveReader(this));
-  }
-}
-
-/* static */
-bool
-WaveDecoder::IsEnabled()
-{
-  PDMFactory::Init();
-  RefPtr<PDMFactory> platform = new PDMFactory();
-  return platform->SupportsMimeType(NS_LITERAL_CSTRING("audio/x-wav"));
-}
-
-/* static */
-bool
-WaveDecoder::CanHandleMediaType(const nsACString& aType,
-                               const nsAString& aCodecs)
-{
-  if (aType.EqualsASCII("audio/wave") || aType.EqualsASCII("audio/x-wav") ||
-      aType.EqualsASCII("audio/wav")  || aType.EqualsASCII("audio/x-pn-wav")) {
-    return IsEnabled() && (aCodecs.IsEmpty() || aCodecs.EqualsASCII("1"));
-  }
-
-  return false;
+  return new MediaDecoderStateMachine(this, new WaveReader(this));
 }
 
 } // namespace mozilla
--- a/dom/media/wave/WaveDecoder.h
+++ b/dom/media/wave/WaveDecoder.h
@@ -3,27 +3,37 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(WaveDecoder_h_)
 #define WaveDecoder_h_
 
 #include "MediaDecoder.h"
 
+/**
+ * The decoder implementation is currently limited to Linear PCM encoded
+ * audio data with one or two channels of 8- or 16-bit samples at sample
+ * rates from 100 Hz to 96 kHz.  The number of channels is limited by what
+ * the audio backend (via AudioStream) currently supports.  The supported
+ * sample rate is artificially limited to arbitrarily selected sane values.
+ * Support for additional channels (and other new features) would
+ * require extending WaveDecoder to support parsing the newer
+ * WAVE_FORMAT_EXTENSIBLE chunk format.
+**/
+
 namespace mozilla {
 
-class WaveDecoder : public MediaDecoder {
+class WaveDecoder : public MediaDecoder
+{
 public:
-  // MediaDecoder interface.
   explicit WaveDecoder(MediaDecoderOwner* aOwner) : MediaDecoder(aOwner) {}
-  MediaDecoder* Clone(MediaDecoderOwner* aOwner) override;
+  MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
+    if (!IsWaveEnabled()) {
+      return nullptr;
+    }
+    return new WaveDecoder(aOwner);
+  }
   MediaDecoderStateMachine* CreateStateMachine() override;
-
-  // Returns true if the WAV backend is pref'ed on, and we're running on a
-  // platform that is likely to have decoders for the format.
-  static bool IsEnabled();
-  static bool CanHandleMediaType(const nsACString& aType,
-                                 const nsAString& aCodecs);
 };
 
 } // namespace mozilla
 
 #endif
deleted file mode 100644
--- a/dom/media/wave/WaveDemuxer.cpp
+++ /dev/null
@@ -1,889 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WaveDemuxer.h"
-
-#include <inttypes.h>
-#include <algorithm>
-
-#include "mozilla/Assertions.h"
-#include "mozilla/Endian.h"
-#include "VideoUtils.h"
-#include "TimeUnits.h"
-#include "prenv.h"
-
-using mozilla::media::TimeUnit;
-using mozilla::media::TimeIntervals;
-using mp4_demuxer::ByteReader;
-
-namespace mozilla {
-
-// WAVDemuxer
-
-WAVDemuxer::WAVDemuxer(MediaResource* aSource)
-  : mSource(aSource)
-{
-}
-
-bool
-WAVDemuxer::InitInternal()
-{
-  if (!mTrackDemuxer) {
-    mTrackDemuxer = new WAVTrackDemuxer(mSource);
-  }
-  return mTrackDemuxer->Init();
-}
-
-RefPtr<WAVDemuxer::InitPromise>
-WAVDemuxer::Init()
-{
-  if (!InitInternal()) {
-    return InitPromise::CreateAndReject(
-      DemuxerFailureReason::DEMUXER_ERROR, __func__);
-  }
-  return InitPromise::CreateAndResolve(NS_OK, __func__);
-}
-
-bool
-WAVDemuxer::HasTrackType(TrackInfo::TrackType aType) const
-{
-  return aType == TrackInfo::kAudioTrack;
-}
-
-uint32_t
-WAVDemuxer::GetNumberTracks(TrackInfo::TrackType aType) const
-{
-  return aType == TrackInfo::kAudioTrack ? 1u : 0u;
-}
-
-already_AddRefed<MediaTrackDemuxer>
-WAVDemuxer::GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber)
-{
-  if (!mTrackDemuxer) {
-    return nullptr;
-  }
-  return RefPtr<WAVTrackDemuxer>(mTrackDemuxer).forget();
-}
-
-bool
-WAVDemuxer::IsSeekable() const
-{
-  return true;
-}
-
-// WAVTrackDemuxer
-
-WAVTrackDemuxer::WAVTrackDemuxer(MediaResourceIndex aSource)
-  : mSource(aSource)
-  , mOffset(0)
-  , mFirstChunkOffset(0)
-  , mNumParsedChunks(0)
-  , mChunkIndex(0)
-  , mTotalChunkLen(0)
-  , mSamplesPerChunk(0)
-  , mSamplesPerSecond(0)
-  , mChannels(0)
-{
-  Reset();
-}
-
-bool
-WAVTrackDemuxer::Init()
-{
-  Reset();
-  FastSeek(TimeUnit());
-
-  if (!mInfo) {
-    mInfo = MakeUnique<AudioInfo>();
-  }
-
-  if (!RIFFParserInit()) {
-    return false;
-  }
-
-  while (true) {
-    if (!HeaderParserInit()) {
-      return false;
-    }
-
-    uint32_t aChunkName = mHeaderParser.GiveHeader().ChunkName();
-    uint32_t aChunkSize = mHeaderParser.GiveHeader().ChunkSize();
-
-    aChunkSize += aChunkSize % 2;
-
-    if (aChunkName == FRMT_CODE) {
-      if (!FmtChunkParserInit()) {
-        return false;
-      }
-    } else if (aChunkName == LIST_CODE) {
-      mHeaderParser.Reset();
-      uint32_t endOfListChunk = mOffset + aChunkSize;
-      if (!ListChunkParserInit(aChunkSize)) {
-        mOffset = endOfListChunk;
-      }
-    } else if (aChunkName == DATA_CODE) {
-      mDataLength = aChunkSize;
-      if (mFirstChunkOffset != mOffset) {
-        mFirstChunkOffset = mOffset;
-      }
-      break;
-    } else {
-      mOffset += aChunkSize; // Skip other irrelevant chunks.
-    }
-    mHeaderParser.Reset();
-  }
-
-  if (mDataLength > StreamLength() - mFirstChunkOffset) {
-    mDataLength = StreamLength() - mFirstChunkOffset;
-  }
-
-  mSamplesPerSecond = mFmtParser.FmtChunk().SampleRate();
-  mChannels = mFmtParser.FmtChunk().Channels();
-  mSampleFormat = mFmtParser.FmtChunk().SampleFormat();
-  mSamplesPerChunk = DATA_CHUNK_SIZE * 8 / mChannels / mSampleFormat;
-
-  mInfo->mRate = mSamplesPerSecond;
-  mInfo->mChannels = mChannels;
-  mInfo->mBitDepth = mSampleFormat;
-  mInfo->mProfile = mFmtParser.FmtChunk().WaveFormat() & 0x00FF;
-  mInfo->mExtendedProfile = (mFmtParser.FmtChunk().WaveFormat() & 0xFF00) >> 8;
-  mInfo->mMimeType = "audio/wave; codecs=";
-  mInfo->mMimeType.AppendInt(mFmtParser.FmtChunk().WaveFormat());
-  mInfo->mDuration = Duration().ToMicroseconds();
-
-  return !!(mInfo->mDuration);
-}
-
-bool
-WAVTrackDemuxer::RIFFParserInit()
-{
-  RefPtr<MediaRawData> riffHeader = GetFileHeader(FindRIFFHeader());
-  if (!riffHeader) {
-    return false;
-  }
-  ByteReader RIFFReader = ByteReader(riffHeader->Data(), 12);
-  mRIFFParser.Parse(RIFFReader);
-  return mRIFFParser.RiffHeader().IsValid(11);
-}
-
-bool
-WAVTrackDemuxer::HeaderParserInit()
-{
-  RefPtr<MediaRawData> header = GetFileHeader(FindChunkHeader());
-  if (!header) {
-    return false;
-  }
-  ByteReader HeaderReader = ByteReader(header->Data(), 8);
-  mHeaderParser.Parse(HeaderReader);
-  return true;
-}
-
-bool
-WAVTrackDemuxer::FmtChunkParserInit()
-{
-  RefPtr<MediaRawData> fmtChunk = GetFileHeader(FindFmtChunk());
-  if (!fmtChunk) {
-    return false;
-  }
-  ByteReader fmtReader = ByteReader(fmtChunk->Data(),
-                                    mHeaderParser.GiveHeader().ChunkSize());
-  mFmtParser.Parse(fmtReader);
-  return true;
-}
-
-bool
-WAVTrackDemuxer::ListChunkParserInit(uint32_t aChunkSize)
-{
-  uint32_t bytesRead = 0;
-
-  RefPtr<MediaRawData> infoTag = GetFileHeader(FindInfoTag());
-  if (!infoTag) {
-    return false;
-  }
-  ByteReader infoTagReader = ByteReader(infoTag->Data(), 4);
-  if (!infoTagReader.CanRead32() || infoTagReader.ReadU32() != INFO_CODE) {
-    return false;
-  }
-
-  bytesRead += 4;
-
-  while (bytesRead < aChunkSize) {
-    if (!HeaderParserInit()) {
-      return false;
-    }
-
-    bytesRead += 8;
-
-    uint32_t id = mHeaderParser.GiveHeader().ChunkName();
-    uint32_t length = mHeaderParser.GiveHeader().ChunkSize();
-
-    // SubChunk Length Cannot Exceed List Chunk length.
-    if (length > aChunkSize - bytesRead) {
-      length = aChunkSize - bytesRead;
-    }
-
-    MediaByteRange mRange = { mOffset, mOffset + length };
-    RefPtr<MediaRawData> mChunkData = GetFileHeader(mRange);
-    if (!mChunkData) {
-      return false;
-    }
-
-    const char* mRawData = reinterpret_cast<const char*>(mChunkData->Data());
-
-    nsCString val(mRawData, length);
-    if (length > 0 && val[length - 1] == '\0') {
-      val.SetLength(length - 1);
-    }
-
-    if (length % 2) {
-      mOffset += 1;
-      length += length % 2;
-    }
-
-    bytesRead += length;
-
-    if (!IsUTF8(val)) {
-      mHeaderParser.Reset();
-      continue;
-    }
-
-    switch (id) {
-      case 0x49415254:                // IART
-        mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("artist"), val));
-        break;
-      case 0x49434d54:                // ICMT
-        mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("comments"), val));
-        break;
-      case 0x49474e52:                // IGNR
-        mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("genre"), val));
-        break;
-      case 0x494e414d:                // INAM
-        mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("name"), val));
-        break;
-    }
-
-    mHeaderParser.Reset();
-  }
-  return true;
-}
-
-media::TimeUnit
-WAVTrackDemuxer::SeekPosition() const
-{
-  TimeUnit pos = Duration(mChunkIndex);
-  if (Duration() > TimeUnit()) {
-    pos = std::min(Duration(), pos);
-  }
-  return pos;
-}
-
-RefPtr<MediaRawData>
-WAVTrackDemuxer::DemuxSample()
-{
-  return GetNextChunk(FindNextChunk());
-}
-
-UniquePtr<TrackInfo>
-WAVTrackDemuxer::GetInfo() const
-{
-  return mInfo->Clone();
-}
-
-RefPtr<WAVTrackDemuxer::SeekPromise>
-WAVTrackDemuxer::Seek(TimeUnit aTime)
-{
-  FastSeek(aTime);
-  const TimeUnit seekTime = ScanUntil(aTime);
-  return SeekPromise::CreateAndResolve(seekTime, __func__);
-}
-
-TimeUnit
-WAVTrackDemuxer::FastSeek(const TimeUnit& aTime)
-{
-  if (aTime.ToMicroseconds()) {
-    mChunkIndex = ChunkIndexFromTime(aTime);
-  } else {
-    mChunkIndex = 0;
-  }
-
-  mOffset = OffsetFromChunkIndex(mChunkIndex);
-
-  if (mOffset > mFirstChunkOffset && StreamLength() > 0) {
-    mOffset = std::min(StreamLength() - 1, mOffset);
-  }
-
-  return Duration(mChunkIndex);
-}
-
-TimeUnit
-WAVTrackDemuxer::ScanUntil(const TimeUnit& aTime)
-{
-  if (!aTime.ToMicroseconds()) {
-    return FastSeek(aTime);
-  }
-
-  if (Duration(mChunkIndex) > aTime) {
-    FastSeek(aTime);
-  }
-
-  return SeekPosition();
-}
-
-RefPtr<WAVTrackDemuxer::SamplesPromise>
-WAVTrackDemuxer::GetSamples(int32_t aNumSamples)
-{
-  if (!aNumSamples) {
-    return SamplesPromise::CreateAndReject(
-        DemuxerFailureReason::DEMUXER_ERROR, __func__);
-  }
-
-  RefPtr<SamplesHolder> datachunks = new SamplesHolder();
-
-  while (aNumSamples--) {
-    RefPtr<MediaRawData> datachunk = GetNextChunk(FindNextChunk());
-    if (!datachunk) {
-      break;
-    }
-    datachunks->mSamples.AppendElement(datachunk);
-  }
-
-  if (datachunks->mSamples.IsEmpty()) {
-    return SamplesPromise::CreateAndReject(
-        DemuxerFailureReason::END_OF_STREAM, __func__);
-  }
-
-  return SamplesPromise::CreateAndResolve(datachunks, __func__);
-}
-
-void
-WAVTrackDemuxer::Reset()
-{
-  FastSeek(TimeUnit());
-  mParser.Reset();
-  mHeaderParser.Reset();
-  mRIFFParser.Reset();
-  mFmtParser.Reset();
-}
-
-RefPtr<WAVTrackDemuxer::SkipAccessPointPromise>
-WAVTrackDemuxer::SkipToNextRandomAccessPoint(TimeUnit aTimeThreshold)
-{
-  return SkipAccessPointPromise::CreateAndReject(
-    SkipFailureHolder(DemuxerFailureReason::DEMUXER_ERROR, 0), __func__);
-}
-
-int64_t
-WAVTrackDemuxer::GetResourceOffset() const
-{
-  return mOffset;
-}
-
-TimeIntervals
-WAVTrackDemuxer::GetBuffered()
-{
-  TimeUnit duration = Duration();
-
-  if (duration <= TimeUnit()) {
-    return TimeIntervals();
-  }
-
-  AutoPinned<MediaResource> stream(mSource.GetResource());
-  return GetEstimatedBufferedTimeRanges(stream, duration.ToMicroseconds());
-}
-
-int64_t
-WAVTrackDemuxer::StreamLength() const
-{
-  return mSource.GetLength();
-}
-
-TimeUnit
-WAVTrackDemuxer::Duration() const
-{
-  if (!mDataLength) {
-    return TimeUnit();
-  }
-
-  int64_t numSamples = mDataLength * 8 / mChannels / mSampleFormat;
-
-  int64_t numUSeconds = USECS_PER_S * numSamples / mSamplesPerSecond;
-
-  if (USECS_PER_S * numSamples % mSamplesPerSecond > mSamplesPerSecond / 2) {
-    numUSeconds++;
-  }
-
-  return TimeUnit::FromMicroseconds(numUSeconds);
-}
-
-TimeUnit
-WAVTrackDemuxer::Duration(int64_t aNumDataChunks) const
-{
-  if (!mSamplesPerSecond) {
-    return TimeUnit();
-  }
-  const double usPerDataChunk = USECS_PER_S * mSamplesPerChunk /
-                                mSamplesPerSecond;
-  return TimeUnit::FromMicroseconds(aNumDataChunks * usPerDataChunk);
-}
-
-TimeUnit
-WAVTrackDemuxer::DurationFromBytes(uint32_t aNumBytes) const
-{
-  if (!mSamplesPerSecond) {
-    return TimeUnit();
-  }
-
-  int64_t numSamples = aNumBytes * 8 / mChannels / mSampleFormat;
-
-  int64_t numUSeconds = USECS_PER_S * numSamples / mSamplesPerSecond;
-
-  if (USECS_PER_S * numSamples % mSamplesPerSecond > mSamplesPerSecond / 2) {
-    numUSeconds++;
-  }
-
-  return TimeUnit::FromMicroseconds(numUSeconds);
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindNextChunk()
-{
-  if (mOffset + DATA_CHUNK_SIZE < mFirstChunkOffset + mDataLength) {
-    return { mOffset, mOffset + DATA_CHUNK_SIZE };
-  } else {
-    return { mOffset, mFirstChunkOffset + mDataLength };
-  }
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindChunkHeader()
-{
-  return { mOffset, mOffset + CHUNK_HEAD_SIZE };
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindRIFFHeader()
-{
-  return { mOffset, mOffset + RIFF_CHUNK_SIZE };
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindFmtChunk()
-{
-  return { mOffset, mOffset + mHeaderParser.GiveHeader().ChunkSize() };
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindListChunk()
-{
-  return { mOffset, mOffset + mHeaderParser.GiveHeader().ChunkSize() };
-}
-
-MediaByteRange
-WAVTrackDemuxer::FindInfoTag()
-{
-  return { mOffset, mOffset + 4 };
-}
-
-bool
-WAVTrackDemuxer::SkipNextChunk(const MediaByteRange& aRange)
-{
-  UpdateState(aRange);
-  return true;
-}
-
-already_AddRefed<MediaRawData>
-WAVTrackDemuxer::GetNextChunk(const MediaByteRange& aRange)
-{
-  if (!aRange.Length()) {
-    return nullptr;
-  }
-
-  RefPtr<MediaRawData> datachunk = new MediaRawData();
-  datachunk->mOffset = aRange.mStart;
-
-  nsAutoPtr<MediaRawDataWriter> chunkWriter(datachunk->CreateWriter());
-  if (!chunkWriter->SetSize(aRange.Length())) {
-    return nullptr;
-  }
-
-  const uint32_t read = Read(chunkWriter->Data(),
-                             datachunk->mOffset,
-                             datachunk->Size());
-
-  if (read != aRange.Length()) {
-    return nullptr;
-  }
-
-  UpdateState(aRange);
-  ++mNumParsedChunks;
-  ++mChunkIndex;
-
-  datachunk->mTime = Duration(mChunkIndex - 1).ToMicroseconds();
-
-  if (static_cast<uint32_t>(mChunkIndex) * DATA_CHUNK_SIZE < mDataLength) {
-    datachunk->mDuration = Duration(1).ToMicroseconds();
-  } else {
-    uint32_t mBytesRemaining =
-      mDataLength - mChunkIndex * DATA_CHUNK_SIZE;
-    datachunk->mDuration = DurationFromBytes(mBytesRemaining).ToMicroseconds();
-  }
-  datachunk->mTimecode = datachunk->mTime;
-  datachunk->mKeyframe = true;
-
-  MOZ_ASSERT(datachunk->mTime >= 0);
-  MOZ_ASSERT(datachunk->mDuration >= 0);
-
-  return datachunk.forget();
-}
-
-already_AddRefed<MediaRawData>
-WAVTrackDemuxer::GetFileHeader(const MediaByteRange& aRange)
-{
-  if (!aRange.Length()) {
-    return nullptr;
-  }
-
-  RefPtr<MediaRawData> fileHeader = new MediaRawData();
-  fileHeader->mOffset = aRange.mStart;
-
-  nsAutoPtr<MediaRawDataWriter> headerWriter(fileHeader->CreateWriter());
-  if (!headerWriter->SetSize(aRange.Length())) {
-    return nullptr;
-  }
-
-  const uint32_t read = Read(headerWriter->Data(),
-                             fileHeader->mOffset,
-                             fileHeader->Size());
-
-  if (read != aRange.Length()) {
-    return nullptr;
-  }
-
-  UpdateState(aRange);
-
-  return fileHeader.forget();
-}
-
-int64_t
-WAVTrackDemuxer::OffsetFromChunkIndex(int64_t aChunkIndex) const
-{
-  return mFirstChunkOffset + aChunkIndex * DATA_CHUNK_SIZE;
-}
-
-int64_t
-WAVTrackDemuxer::ChunkIndexFromOffset(int64_t aOffset) const
-{
-  int64_t chunkIndex = (aOffset - mFirstChunkOffset) / DATA_CHUNK_SIZE;
-  return std::max<int64_t>(0, chunkIndex);
-}
-
-int64_t
-WAVTrackDemuxer::ChunkIndexFromTime(const media::TimeUnit& aTime) const
-{
-  int64_t chunkIndex =
-    (aTime.ToSeconds() * mSamplesPerSecond / mSamplesPerChunk) - 1;
-  return chunkIndex;
-}
-
-void
-WAVTrackDemuxer::UpdateState(const MediaByteRange& aRange)
-{
-  // Full chunk parsed, move offset to its end.
-  mOffset = aRange.mEnd;
-  mTotalChunkLen += aRange.Length();
-}
-
-int32_t
-WAVTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize)
-{
-  const int64_t streamLen = StreamLength();
-  if (mInfo && streamLen > 0) {
-    aSize = std::min<int64_t>(aSize, streamLen - aOffset);
-  }
-  uint32_t read = 0;
-  const nsresult rv = mSource.ReadAt(aOffset,
-                                     reinterpret_cast<char*>(aBuffer),
-                                     static_cast<uint32_t>(aSize),
-                                     &read);
-  NS_ENSURE_SUCCESS(rv, 0);
-  return static_cast<int32_t>(read);
-}
-
-// RIFFParser
-
-uint32_t
-RIFFParser::Parse(ByteReader& aReader)
-{
-  MOZ_ASSERT(&aReader);
-
-  while (aReader.CanRead8() && !mRiffHeader.ParseNext(aReader.ReadU8())) { }
-
-  if (mRiffHeader.IsValid()) {
-    return RIFF_CHUNK_SIZE;
-  }
-
-  return 0;
-}
-
-void
-RIFFParser::Reset()
-{
-  mRiffHeader.Reset();
-}
-
-const RIFFParser::RIFFHeader&
-RIFFParser::RiffHeader() const
-{
-  return mRiffHeader;
-}
-
-// RIFFParser::RIFFHeader
-
-RIFFParser::RIFFHeader::RIFFHeader()
-{
-  Reset();
-}
-
-void
-RIFFParser::RIFFHeader::Reset()
-{
-  mPos = 0;
-}
-
-bool
-RIFFParser::RIFFHeader::ParseNext(uint8_t c)
-{
-  if (!Update(c)) {
-    Reset();
-    if (!Update(c)) {
-      Reset();
-    }
-  }
-  return IsValid();
-}
-
-bool
-RIFFParser::RIFFHeader::IsValid(int aPos) const
-{
-  if (aPos > -1 && aPos < 4) {
-    return RIFF[aPos] == mRaw[aPos];
-  } else if (aPos > 7 && aPos < 12) {
-    return WAVE[aPos - 8] == mRaw[aPos];
-  } else {
-    return true;
-  }
-}
-
-bool
-RIFFParser::RIFFHeader::IsValid() const
-{
-  return mPos >= RIFF_CHUNK_SIZE;
-}
-
-bool
-RIFFParser::RIFFHeader::Update(uint8_t c)
-{
-  if (mPos < RIFF_CHUNK_SIZE) {
-    mRaw[mPos] = c;
-  }
-  return IsValid(mPos++);
-}
-
-// HeaderParser
-
-uint32_t
-HeaderParser::Parse(ByteReader& aReader)
-{
-  while (aReader.CanRead8() && !mHeader.ParseNext(aReader.ReadU8())) { }
-
-  if (mHeader.IsValid()) {
-    return CHUNK_HEAD_SIZE;
-  }
-
-  return 0;
-}
-
-void
-HeaderParser::Reset()
-{
-  mHeader.Reset();
-}
-
-const HeaderParser::ChunkHeader&
-HeaderParser::GiveHeader() const
-{
-  return mHeader;
-}
-
-// HeaderParser::ChunkHeader
-
-HeaderParser::ChunkHeader::ChunkHeader()
-{
-  Reset();
-}
-
-void
-HeaderParser::ChunkHeader::Reset()
-{
-  mPos = 0;
-}
-
-bool
-HeaderParser::ChunkHeader::ParseNext(uint8_t c)
-{
-  Update(c);
-  return IsValid();
-}
-
-bool
-HeaderParser::ChunkHeader::IsValid() const
-{
-  return mPos >= CHUNK_HEAD_SIZE;
-}
-
-uint32_t
-HeaderParser::ChunkHeader::ChunkName() const
-{
-  return ((mRaw[0] << 24) | (mRaw[1] << 16) |
-          (mRaw[2] << 8 ) | (mRaw[3]));
-}
-
-uint32_t
-HeaderParser::ChunkHeader::ChunkSize() const
-{
-  return ((mRaw[7] << 24) | (mRaw[6] << 16) |
-          (mRaw[5] << 8 ) | (mRaw[4]));
-}
-
-void
-HeaderParser::ChunkHeader::Update(uint8_t c)
-{
-  if (mPos < CHUNK_HEAD_SIZE) {
-    mRaw[mPos++] = c;
-  }
-}
-
-// FormatParser
-
-uint32_t
-FormatParser::Parse(ByteReader& aReader)
-{
-  MOZ_ASSERT(&aReader);
-
-  while (aReader.CanRead8() && !mFmtChunk.ParseNext(aReader.ReadU8())) { }
-
-  if (mFmtChunk.IsValid()) {
-    return FMT_CHUNK_MIN_SIZE;
-  }
-
-  return 0;
-}
-
-void
-FormatParser::Reset()
-{
-  mFmtChunk.Reset();
-}
-
-const FormatParser::FormatChunk&
-FormatParser::FmtChunk() const
-{
-  return mFmtChunk;
-}
-
-// FormatParser::FormatChunk
-
-FormatParser::FormatChunk::FormatChunk()
-{
-  Reset();
-}
-
-void
-FormatParser::FormatChunk::Reset()
-{
-  mPos = 0;
-}
-
-uint16_t
-FormatParser::FormatChunk::WaveFormat() const
-{
-  return (mRaw[1] << 8) | (mRaw[0]);
-}
-
-uint16_t
-FormatParser::FormatChunk::Channels() const
-{
-  return (mRaw[3] << 8) | (mRaw[2]);
-}
-
-uint32_t
-FormatParser::FormatChunk::SampleRate() const
-{
-  return (mRaw[7] << 24) | (mRaw[6] << 16) |
-         (mRaw[5] << 8 ) | (mRaw[4]);
-}
-
-uint16_t
-FormatParser::FormatChunk::FrameSize() const
-{
-  return (mRaw[13] << 8) | (mRaw[12]);
-}
-
-uint16_t
-FormatParser::FormatChunk::SampleFormat() const
-{
-  return (mRaw[15] << 8) | (mRaw[14]);
-}
-
-bool
-FormatParser::FormatChunk::ParseNext(uint8_t c)
-{
-  Update(c);
-  return IsValid();
-}
-
-bool
-FormatParser::FormatChunk::IsValid() const
-{
-  return (FrameSize() == SampleRate() * Channels() / 8) &&
-         (mPos >= FMT_CHUNK_MIN_SIZE);
-}
-
-void
-FormatParser::FormatChunk::Update(uint8_t c)
-{
-  if (mPos < FMT_CHUNK_MIN_SIZE) {
-    mRaw[mPos++] = c;
-  }
-}
-
-// DataParser
-
-DataParser::DataParser()
-{
-}
-
-void
-DataParser::Reset()
-{
-  mChunk.Reset();
-}
-
-const DataParser::DataChunk&
-DataParser::CurrentChunk() const
-{
-  return mChunk;
-}
-
-// DataParser::DataChunk
-
-void
-DataParser::DataChunk::Reset()
-{
-  mPos = 0;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/wave/WaveDemuxer.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * Licence, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WAV_DEMUXER_H_
-#define WAV_DEMUXER_H_
-
-#include "mozilla/Attributes.h"
-#include "mozilla/Maybe.h"
-#include "MediaDataDemuxer.h"
-#include "MediaResource.h"
-#include "mp4_demuxer/ByteReader.h"
-
-using mp4_demuxer::ByteReader;
-
-namespace mozilla {
-
-static const uint32_t FRMT_CODE = 0x666d7420;
-static const uint32_t DATA_CODE = 0x64617461;
-static const uint32_t LIST_CODE = 0x4c495354;
-static const uint32_t INFO_CODE = 0x494e464f;
-
-static const uint8_t RIFF[4] = {'R', 'I', 'F', 'F'};
-static const uint8_t WAVE[4] = {'W', 'A', 'V', 'E'};
-
-static const uint16_t RIFF_CHUNK_SIZE = 12;
-static const uint16_t CHUNK_HEAD_SIZE = 8;
-static const uint16_t FMT_CHUNK_MIN_SIZE = 16;
-static const uint16_t DATA_CHUNK_SIZE = 768;
-
-class WAVTrackDemuxer;
-
-class WAVDemuxer : public MediaDataDemuxer {
-public:
-  // MediaDataDemuxer interface.
-  explicit WAVDemuxer(MediaResource* aSource);
-  RefPtr<InitPromise> Init() override;
-  bool HasTrackType(TrackInfo::TrackType aType) const override;
-  uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
-  already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
-      TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
-  bool IsSeekable() const override;
-
-private:
-  // Synchronous Initialization.
-  bool InitInternal();
-
-  MediaResourceIndex mSource;
-  RefPtr<WAVTrackDemuxer> mTrackDemuxer;
-};
-
-class RIFFParser {
-private:
-  class RIFFHeader;
-public:
-  const RIFFHeader& RiffHeader() const;
-
-  uint32_t Parse(ByteReader& aReader);
-
-  void Reset();
-
-private:
-  class RIFFHeader {
-  public:
-    RIFFHeader();
-    void Reset();
-
-    bool IsValid() const;
-    bool IsValid(int aPos) const;
-
-    bool ParseNext(uint8_t c);
-
-  private:
-    bool Update(uint8_t c);
-
-    uint8_t mRaw[RIFF_CHUNK_SIZE];
-
-    int mPos;
-  };
-
-  RIFFHeader mRiffHeader;
-};
-
-class HeaderParser {
-private:
-  class ChunkHeader;
-public:
-  const ChunkHeader& GiveHeader() const;
-
-  uint32_t Parse(ByteReader& aReader);
-
-  void Reset();
-
-private:
-  class ChunkHeader {
-  public:
-    ChunkHeader();
-    void Reset();
-
-    bool IsValid() const;
-
-    uint32_t ChunkName() const;
-    uint32_t ChunkSize() const;
-
-    bool ParseNext(uint8_t c);
-
-  private:
-    void Update(uint8_t c);
-
-    uint8_t mRaw[CHUNK_HEAD_SIZE];
-
-    int mPos;
-  };
-
-  ChunkHeader mHeader;
-};
-
-class FormatParser {
-private:
-  class FormatChunk;
-public:
-  const FormatChunk& FmtChunk() const;
-
-  uint32_t Parse(ByteReader& aReader);
-
-  void Reset();
-
-private:
-  class FormatChunk {
-  public:
-    FormatChunk();
-    void Reset();
-
-    uint16_t WaveFormat() const;
-    uint16_t Channels() const;
-    uint32_t SampleRate() const;
-    uint16_t FrameSize() const;
-    uint16_t SampleFormat() const;
-
-    bool IsValid() const;
-    bool ParseNext(uint8_t c);
-
-  private:
-    void Update(uint8_t c);
-
-    uint8_t mRaw[FMT_CHUNK_MIN_SIZE];
-
-    int mPos;
-  };
-
-  FormatChunk mFmtChunk;
-};
-
-class DataParser {
-private:
-  class DataChunk;
-public:
-  DataParser();
-
-  const DataChunk& CurrentChunk() const;
-
-  void Reset();
-
-private:
-  class DataChunk {
-  public:
-    void Reset();
-  private:
-    int mPos; // To Check Alignment
-  };
-
-  DataChunk mChunk;
-};
-
-class WAVTrackDemuxer : public MediaTrackDemuxer {
-public:
-  explicit WAVTrackDemuxer(MediaResourceIndex aSource);
-
-  bool Init();
-
-  int64_t StreamLength() const;
-
-  media::TimeUnit Duration() const;
-  media::TimeUnit Duration(int64_t aNumDataChunks) const;
-  media::TimeUnit DurationFromBytes(uint32_t aNumBytes) const;
-
-  media::TimeUnit SeekPosition() const;
-
-  RefPtr<MediaRawData> DemuxSample();
-
-  // MediaTrackDemuxer interface.
-  UniquePtr<TrackInfo> GetInfo() const override;
-  RefPtr<SeekPromise> Seek(media::TimeUnit aTime) override;
-  RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples) override;
-  void Reset() override;
-  RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
-    media::TimeUnit aTimeThreshold) override;
-  int64_t GetResourceOffset() const override;
-  media::TimeIntervals GetBuffered() override;
-
-private:
-  ~WAVTrackDemuxer() {}
-
-  media::TimeUnit FastSeek(const media::TimeUnit& aTime);
-  media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
-
-  MediaByteRange FindNextChunk();
-
-  MediaByteRange FindChunkHeader();
-  MediaByteRange FindRIFFHeader();
-  MediaByteRange FindFmtChunk();
-  MediaByteRange FindListChunk();
-  MediaByteRange FindInfoTag();
-
-  bool RIFFParserInit();
-  bool HeaderParserInit();
-  bool FmtChunkParserInit();
-  bool ListChunkParserInit(uint32_t aChunkSize);
-
-  bool SkipNextChunk(const MediaByteRange& aRange);
-
-  already_AddRefed<MediaRawData> GetNextChunk(const MediaByteRange& aRange);
-  already_AddRefed<MediaRawData> GetFileHeader(const MediaByteRange& aRange);
-
-  void UpdateState(const MediaByteRange& aRange);
-
-  int64_t OffsetFromChunkIndex(int64_t aChunkIndex) const;
-  int64_t ChunkIndexFromOffset(int64_t aOffet) const;
-  int64_t ChunkIndexFromTime(const media::TimeUnit& aTime) const;
-
-  int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);
-
-  MediaResourceIndex mSource;
-
-  DataParser mParser;
-  RIFFParser mRIFFParser;
-  HeaderParser mHeaderParser;
-
-  FormatParser mFmtParser;
-  // ListChunkParser mListChunkParser;
-
-  int64_t mOffset;
-  int64_t mFirstChunkOffset;
-
-  uint32_t mNumParsedChunks;
-  int32_t mChunkIndex;
-
-  uint32_t mDataLength;
-  uint64_t mTotalChunkLen;
-
-  int32_t mSamplesPerChunk;
-  int32_t mSamplesPerSecond;
-
-  int32_t mChannels;
-  int32_t mSampleFormat;
-
-  UniquePtr<AudioInfo> mInfo;
-};
-
-} // namespace mozilla
-
-#endif
--- a/dom/media/wave/moz.build
+++ b/dom/media/wave/moz.build
@@ -1,19 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'WaveDecoder.h',
-    'WaveDemuxer.h',
     'WaveReader.h',
 ]
 
 UNIFIED_SOURCES += [
     'WaveDecoder.cpp',
-    'WaveDemuxer.cpp',
     'WaveReader.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/dom/media/webaudio/test/test_decodeMultichannel.html
+++ b/dom/media/webaudio/test/test_decodeMultichannel.html
@@ -18,21 +18,21 @@ function finishTest(a) {
     a = null;
     SimpleTest.finish();
   }
 }
 
 function decodeUsingAudioElement() {
   var a = new Audio();
   a.addEventListener("error", function() {
-    ok(false, "Error loading metadata");
+    ok(true, "We should not be able to decode this file using an HTMLAudioElement");
     finishTest(a);
   });
   a.addEventListener("loadedmetadata", function() {
-    ok(true, "Metadata Loaded");
+    ok(false, "We should not be able to decode this file using an HTMLMediaElement.");
     finishTest(a);
   });
 
   a.src = filename;
   a.load();
 }
 
 addLoadEvent(function() {
--- a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
@@ -82,55 +82,31 @@ public:
     auto ptr = Read(2);
     if (!ptr) {
       MOZ_ASSERT(false);
       return 0;
     }
     return mozilla::BigEndian::readUint16(ptr);
   }
 
-  int16_t ReadLE16()
-  {
-    auto ptr = Read(2);
-    if (!ptr) {
-      MOZ_ASSERT(false);
-      return 0;
-    }
-    return mozilla::LittleEndian::readInt16(ptr);
-  }
-
   uint32_t ReadU24()
   {
     auto ptr = Read(3);
     if (!ptr) {
       MOZ_ASSERT(false);
       return 0;
     }
     return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
   }
 
   uint32_t Read24()
   {
     return (uint32_t)ReadU24();
   }
 
-  int32_t ReadLE24()
-  {
-    auto ptr = Read(3);
-    if (!ptr) {
-      MOZ_ASSERT(false);
-      return 0;
-    }
-    int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]);
-    if (result & 0x00800000u) {
-      result -= 0x1000000;
-    }
-    return result;
-  }
-
   bool CanRead32() { return mRemaining >= 4; }
 
   uint32_t ReadU32()
   {
     auto ptr = Read(4);
     if (!ptr) {
       MOZ_ASSERT(false);
       return 0;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -344,17 +344,16 @@ pref("media.gmp.decoder.enabled", false)
 pref("media.gmp.decoder.aac", 0);
 pref("media.gmp.decoder.h264", 0);
 #ifdef MOZ_RAW
 pref("media.raw.enabled", true);
 #endif
 pref("media.ogg.enabled", true);
 pref("media.opus.enabled", true);
 pref("media.wave.enabled", true);
-pref("media.wave.decoder.enabled", true);
 pref("media.webm.enabled", true);
 #if defined(MOZ_FMP4) && defined(MOZ_WMF)
 pref("media.webm.intel_decoder.enabled", false);
 #endif
 
 #ifdef MOZ_APPLEMEDIA
 #ifdef MOZ_WIDGET_UIKIT
 pref("media.mp3.enabled", true);