Bug 799344 - Flatten nsBultinDecoderStateMachine and nsDecoderStateMachine into a single class. r=roc
authorChris Pearce <cpearce@mozilla.com>
Wed, 07 Nov 2012 11:33:02 +1300
changeset 112771 dee39125618290b7348f5dd62aa99e9c7fe450f5
parent 112770 325b40aaa768db062e479bc148edbde099ca930b
child 112772 1a9be77a429cb83cd984e42472efa9e1389cbdf9
push id23838
push usereakhgari@mozilla.com
push dateFri, 09 Nov 2012 15:21:51 +0000
treeherdermozilla-central@c39596b46863 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs799344
milestone19.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
Bug 799344 - Flatten nsBultinDecoderStateMachine and nsDecoderStateMachine into a single class. r=roc
content/media/dash/nsDASHDecoder.cpp
content/media/dash/nsDASHDecoder.h
content/media/dash/nsDASHRepDecoder.cpp
content/media/dash/nsDASHRepDecoder.h
content/media/gstreamer/nsGStreamerDecoder.cpp
content/media/gstreamer/nsGStreamerDecoder.h
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/nsBuiltinDecoderStateMachine.h
content/media/ogg/nsOggDecoder.cpp
content/media/ogg/nsOggDecoder.h
content/media/ogg/nsOggReader.cpp
content/media/omx/nsMediaOmxDecoder.cpp
content/media/omx/nsMediaOmxDecoder.h
content/media/omx/nsMediaOmxReader.cpp
content/media/plugins/nsMediaPluginDecoder.cpp
content/media/plugins/nsMediaPluginDecoder.h
content/media/plugins/nsMediaPluginReader.cpp
content/media/raw/nsRawDecoder.cpp
content/media/raw/nsRawDecoder.h
content/media/wave/nsWaveDecoder.cpp
content/media/wave/nsWaveDecoder.h
content/media/wave/nsWaveReader.cpp
content/media/webm/nsWebMDecoder.cpp
content/media/webm/nsWebMDecoder.h
--- a/content/media/dash/nsDASHDecoder.cpp
+++ b/content/media/dash/nsDASHDecoder.cpp
@@ -153,17 +153,17 @@ nsDASHDecoder::nsDASHDecoder() :
   MOZ_COUNT_CTOR(nsDASHDecoder);
 }
 
 nsDASHDecoder::~nsDASHDecoder()
 {
   MOZ_COUNT_DTOR(nsDASHDecoder);
 }
 
-nsDecoderStateMachine*
+nsBuiltinDecoderStateMachine*
 nsDASHDecoder::CreateStateMachine()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   return new nsBuiltinDecoderStateMachine(this, mDASHReader);
 }
 
 void
 nsDASHDecoder::ReleaseStateMachine()
--- a/content/media/dash/nsDASHDecoder.h
+++ b/content/media/dash/nsDASHDecoder.h
@@ -45,17 +45,17 @@ public:
   nsDASHDecoder();
   ~nsDASHDecoder();
 
   // Clone not supported; just return nullptr.
   nsMediaDecoder* Clone() { return nullptr; }
 
   // Creates a single state machine for all stream decoders.
   // Called from Load on the main thread only.
-  nsDecoderStateMachine* CreateStateMachine();
+  nsBuiltinDecoderStateMachine* CreateStateMachine();
 
   // Loads the MPD from the network and subsequently loads the media streams.
   // Called from the main thread only.
   nsresult Load(MediaResource* aResource,
                 nsIStreamListener** aListener,
                 nsMediaDecoder* aCloneDonor);
 
   // Notifies download of MPD file has ended.
--- a/content/media/dash/nsDASHRepDecoder.cpp
+++ b/content/media/dash/nsDASHRepDecoder.cpp
@@ -26,26 +26,26 @@ extern PRLogModuleInfo* gBuiltinDecoderL
                              ("%p [nsDASHRepDecoder] " msg, this, __VA_ARGS__))
 #define LOG1(msg) PR_LOG(gBuiltinDecoderLog, PR_LOG_DEBUG, \
                          ("%p [nsDASHRepDecoder] " msg, this))
 #else
 #define LOG(msg, ...)
 #define LOG1(msg)
 #endif
 
-nsDecoderStateMachine*
+nsBuiltinDecoderStateMachine*
 nsDASHRepDecoder::CreateStateMachine()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   // Do not create; just return current state machine.
   return mDecoderStateMachine;
 }
 
 nsresult
-nsDASHRepDecoder::SetStateMachine(nsDecoderStateMachine* aSM)
+nsDASHRepDecoder::SetStateMachine(nsBuiltinDecoderStateMachine* aSM)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   mDecoderStateMachine = aSM;
   return NS_OK;
 }
 
 void
 nsDASHRepDecoder::SetResource(MediaResource* aResource)
--- a/content/media/dash/nsDASHRepDecoder.h
+++ b/content/media/dash/nsDASHRepDecoder.h
@@ -48,22 +48,22 @@ public:
     MOZ_COUNT_DTOR(nsDASHRepDecoder);
   }
 
   // Clone not supported; just return nullptr.
   virtual nsMediaDecoder* Clone() { return nullptr; }
 
   // Called by the main decoder at creation time; points to the main state
   // machine managed by the main decoder. Called on the main thread only.
-  nsresult SetStateMachine(nsDecoderStateMachine* aSM);
+  nsresult SetStateMachine(nsBuiltinDecoderStateMachine* aSM);
 
 private:
   // Overridden to return the ptr set by SetStateMachine. Called on the main
   // thread only.
-  nsDecoderStateMachine* CreateStateMachine();
+  nsBuiltinDecoderStateMachine* CreateStateMachine();
 
 public:
   // Called by nsDASHDecoder at creation time; points to the media resource
   // for this decoder's |Representation|. Called on the main thread only.
   void SetResource(MediaResource* aResource);
 
   // Sets the |Representation| object for this decoder. Called on the main
   // thread.
--- a/content/media/gstreamer/nsGStreamerDecoder.cpp
+++ b/content/media/gstreamer/nsGStreamerDecoder.cpp
@@ -3,12 +3,12 @@
 /* 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 "nsBuiltinDecoderStateMachine.h"
 #include "nsGStreamerReader.h"
 #include "nsGStreamerDecoder.h"
 
-nsDecoderStateMachine* nsGStreamerDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsGStreamerDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsGStreamerReader(this));
 }
--- a/content/media/gstreamer/nsGStreamerDecoder.h
+++ b/content/media/gstreamer/nsGStreamerDecoder.h
@@ -8,12 +8,12 @@
 #define nsGStreamerDecoder_h_
 
 #include "nsBuiltinDecoder.h"
 
 class nsGStreamerDecoder : public nsBuiltinDecoder
 {
 public:
   virtual nsMediaDecoder* Clone() { return new nsGStreamerDecoder(); }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -1,40 +1,40 @@
 /* -*- 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 "nsBuiltinDecoder.h"
 #include <limits>
 #include "nsNetUtil.h"
 #include "nsAudioStream.h"
 #include "nsHTMLVideoElement.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsTArray.h"
 #include "VideoUtils.h"
-#include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "nsTimeRanges.h"
 #include "nsContentUtils.h"
 #include "ImageContainer.h"
 
 using namespace mozilla;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg) PR_LOG(gBuiltinDecoderLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsBuiltinDecoder, nsIObserver)
 
-void nsBuiltinDecoder::Pause() 
+void nsBuiltinDecoder::Pause()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   if (mPlayState == PLAY_STATE_SEEKING || mPlayState == PLAY_STATE_ENDED) {
     mNextState = PLAY_STATE_PAUSED;
     return;
   }
 
@@ -248,17 +248,17 @@ bool nsBuiltinDecoder::Init(nsHTMLMediaE
 
   nsContentUtils::RegisterShutdownObserver(this);
   return true;
 }
 
 void nsBuiltinDecoder::Shutdown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  
+
   if (mShuttingDown)
     return;
 
   mShuttingDown = true;
 
   {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
     DestroyDecodedStream();
@@ -345,17 +345,17 @@ nsresult nsBuiltinDecoder::InitializeSta
     return NS_ERROR_FAILURE;
   }
   {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
     mDecoderStateMachine->SetSeekable(mSeekable);
     mDecoderStateMachine->SetDuration(mDuration);
     mDecoderStateMachine->SetVolume(mInitialVolume);
     mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
-    
+
     if (mFrameBufferLength > 0) {
       // The valid mFrameBufferLength value was specified earlier
       mDecoderStateMachine->SetFrameBufferLength(mFrameBufferLength);
     }
   }
 
   ChangeState(PLAY_STATE_LOADING);
 
@@ -739,17 +739,17 @@ nsMediaDecoder::Statistics
 nsBuiltinDecoder::GetStatistics()
 {
   NS_ASSERTION(NS_IsMainThread() || OnStateMachineThread(),
                "Should be on main or state machine thread.");
   Statistics result;
 
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   if (mResource) {
-    result.mDownloadRate = 
+    result.mDownloadRate =
       mResource->GetDownloadRate(&result.mDownloadRateReliable);
     result.mDownloadPosition =
       mResource->GetCachedDataEnd(mDecoderPosition);
     result.mTotalBytes = mResource->GetLength();
     result.mPlaybackRate = ComputePlaybackRate(&result.mPlaybackRateReliable);
     result.mDecoderPosition = mDecoderPosition;
     result.mPlaybackPosition = mPlaybackPosition;
   }
@@ -804,26 +804,26 @@ void nsBuiltinDecoder::UpdatePlaybackRat
 
 void nsBuiltinDecoder::NotifySuspendedStatusChanged()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (!mResource)
     return;
   MediaResource* activeStream;
   bool suspended = mResource->IsSuspendedByCache(&activeStream);
-  
+
   if (mElement) {
     if (suspended) {
       // If this is an autoplay element, we need to kick off its autoplaying
       // now so we consume data and hopefully free up cache space.
       mElement->NotifyAutoplayDataReady();
     }
     mElement->NotifySuspendedByCache(suspended);
     UpdateReadyStateForData();
-  } 
+  }
 }
 
 void nsBuiltinDecoder::NotifyBytesDownloaded()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   UpdateReadyStateForData();
   Progress(false);
 }
@@ -984,17 +984,17 @@ void nsBuiltinDecoder::SeekingStarted()
   if (mElement) {
     UpdateReadyStateForData();
     mElement->SeekStarted();
   }
 }
 
 void nsBuiltinDecoder::ChangeState(PlayState aState)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");   
+  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
   if (mNextState == aState) {
     mNextState = PLAY_STATE_PAUSED;
   }
 
   if (mPlayState == PLAY_STATE_SHUTDOWN) {
     GetReentrantMonitor().NotifyAll();
@@ -1206,8 +1206,61 @@ bool nsBuiltinDecoder::OnStateMachineThr
 void nsBuiltinDecoder::NotifyAudioAvailableListener()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mDecoderStateMachine) {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
     mDecoderStateMachine->NotifyAudioAvailableListener();
   }
 }
+
+bool nsBuiltinDecoder::OnDecodeThread() const {
+  return mDecoderStateMachine->OnDecodeThread();
+}
+
+ReentrantMonitor& nsBuiltinDecoder::GetReentrantMonitor() {
+  return mReentrantMonitor.GetReentrantMonitor();
+}
+
+// Constructs the time ranges representing what segments of the media
+// are buffered and playable.
+nsresult nsBuiltinDecoder::GetBuffered(nsTimeRanges* aBuffered) {
+  if (mDecoderStateMachine) {
+    return mDecoderStateMachine->GetBuffered(aBuffered);
+  }
+  return NS_ERROR_FAILURE;
+}
+
+int64_t nsBuiltinDecoder::VideoQueueMemoryInUse() {
+  if (mDecoderStateMachine) {
+    return mDecoderStateMachine->VideoQueueMemoryInUse();
+  }
+  return 0;
+}
+
+int64_t nsBuiltinDecoder::AudioQueueMemoryInUse() {
+  if (mDecoderStateMachine) {
+    return mDecoderStateMachine->AudioQueueMemoryInUse();
+  }
+  return 0;
+}
+
+void nsBuiltinDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {
+  if (mDecoderStateMachine) {
+    mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
+  }
+}
+
+void nsBuiltinDecoder::UpdatePlaybackPosition(int64_t aTime)
+{
+  mDecoderStateMachine->UpdatePlaybackPosition(aTime);
+}
+
+// Provide access to the state machine object
+nsBuiltinDecoderStateMachine* nsBuiltinDecoder::GetStateMachine() {
+  return mDecoderStateMachine;
+}
+
+// Drop reference to state machine.  Only called during shutdown dance.
+void nsBuiltinDecoder::ReleaseStateMachine() {
+  mDecoderStateMachine = nullptr;
+}
+
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -8,20 +8,19 @@ Each video element based on nsBuiltinDec
 its play state and keep the current frame up to date. All state machines
 share time in a single shared thread. Each decoder also has one thread
 dedicated to decoding audio and video data. This thread is shutdown when
 playback is paused. Each decoder also has a thread to push decoded audio
 to the hardware. This thread is not created until playback starts, but
 currently is not destroyed when paused, only when playback ends.
 
 The decoder owns the resources for downloading the media file, and the
-high level state. It holds an owning reference to the state machine
-(a subclass of nsDecoderStateMachine; nsBuiltinDecoderStateMachine) that
+high level state. It holds an owning reference to the state machine that
 owns all the resources related to decoding data, and manages the low level
-decoding operations and A/V sync. 
+decoding operations and A/V sync.
 
 Each state machine runs on the shared state machine thread. Every time some
 action is required for a state machine, it is scheduled to run on the shared
 the state machine thread. The state machine runs one "cycle" on the state
 machine thread, and then returns. If necessary, it will schedule itself to
 run again in future. While running this cycle, it must not block the
 thread, as other state machines' events may need to run. State shared
 between a state machine's threads is synchronised via the monitor owned
@@ -30,17 +29,17 @@ by its nsBuiltinDecoder object.
 The Main thread controls the decode state machine by setting the value
 of a mPlayState variable and notifying on the monitor based on the
 high level player actions required (Seek, Pause, Play, etc).
 
 The player states are the states requested by the client through the
 DOM API.  They represent the desired state of the player, while the
 decoder's state represents the actual state of the decoder.
 
-The high level state of the player is maintained via a PlayState value. 
+The high level state of the player is maintained via a PlayState value.
 It can have the following states:
 
 START
   The decoder has been initialized but has no resource loaded.
 PAUSED
   A request via the API has been received to pause playback.
 LOADING
   A request via the API has been received to load a resource.
@@ -55,17 +54,17 @@ SHUTDOWN
 
 State transition occurs when the Media Element calls the Play, Seek,
 etc methods on the nsBuiltinDecoder object. When the transition
 occurs nsBuiltinDecoder then calls the methods on the decoder state
 machine object to cause it to behave as required by the play state.
 State transitions will likely schedule the state machine to run to
 affect the change.
 
-An implementation of the nsDecoderStateMachine class is the event
+An implementation of the nsBuiltinDecoderStateMachine class is the event
 that gets dispatched to the state machine thread. Each time the event is run,
 the state machine must cycle the state machine once, and then return.
 
 The state machine has the following states:
 
 DECODING_METADATA
   The media headers are being loaded, and things like framerate, etc are
   being determined, and the first frame of audio/video data is being decoded.
@@ -86,17 +85,17 @@ COMPLETED
 SHUTDOWN
   The decoder object and its state machine are about to be destroyed.
   Once the last state machine has been destroyed, the shared state machine
   thread will also be destroyed. It will be recreated later if needed.
 
 The following result in state transitions.
 
 Shutdown()
-  Clean up any resources the nsDecoderStateMachine owns.
+  Clean up any resources the nsBuiltinDecoderStateMachine owns.
 Play()
   Start decoding and playback of media data.
 Buffer
   This is not user initiated. It occurs when the
   available data in the stream drops below a certain point.
 Complete
   This is not user initiated. It occurs when the
   stream is completely decoded.
@@ -122,31 +121,31 @@ DECODING             |          |  |    
   |          Play()  |Seek(t)   |Buffer()         |
   -----------<--------<-------BUFFERING           |
                                 |                 ^
                                 v Shutdown()      |
                                 |                 |
                                 ------------>-----|
 
 The following represents the states that the nsBuiltinDecoder object
-can be in, and the valid states the nsDecoderStateMachine can be in at that
+can be in, and the valid states the nsBuiltinDecoderStateMachine can be in at that
 time:
 
 player LOADING   decoder DECODING_METADATA
 player PLAYING   decoder DECODING, BUFFERING, SEEKING, COMPLETED
 player PAUSED    decoder DECODING, BUFFERING, SEEKING, COMPLETED
 player SEEKING   decoder SEEKING
 player COMPLETED decoder SHUTDOWN
 player SHUTDOWN  decoder SHUTDOWN
 
 The general sequence of events is:
 
 1) The video element calls Load on nsMediaDecoder. This creates the
    state machine and starts the channel for downloading the
-   file. It instantiates and schedules the nsDecoderStateMachine. The
+   file. It instantiates and schedules the nsBuiltinDecoderStateMachine. The
    high level LOADING state is entered, which results in the decode
    thread being created and starting to decode metadata. These are
    the headers that give the video size, framerate, etc. Load() returns
    immediately to the calling video element.
 
 2) When the metadata has been loaded by the decode thread, the state machine
    will call a method on the video element object to inform it that this
    step is done, so it can do the things required by the video specification
@@ -200,143 +199,22 @@ namespace mozilla {
 namespace layers {
 class Image;
 } //namespace
 } //namespace
 
 typedef mozilla::layers::Image Image;
 
 class nsAudioStream;
+class nsBuiltinDecoderStateMachine;
 
 static inline bool IsCurrentThread(nsIThread* aThread) {
   return NS_GetCurrentThread() == aThread;
 }
 
-// Decoder backends must implement this class to perform the codec
-// specific parts of decoding the video/audio format.
-class nsDecoderStateMachine : public nsRunnable
-{
-public:
-  // Enumeration for the valid decoding states
-  enum State {
-    DECODER_STATE_DECODING_METADATA,
-    DECODER_STATE_DECODING,
-    DECODER_STATE_SEEKING,
-    DECODER_STATE_BUFFERING,
-    DECODER_STATE_COMPLETED,
-    DECODER_STATE_SHUTDOWN
-  };
-
-  // Initializes the state machine, returns NS_OK on success, or
-  // NS_ERROR_FAILURE on failure.
-  virtual nsresult Init(nsDecoderStateMachine* aCloneDonor) = 0;
-
-  // Return the current decode state. The decoder monitor must be
-  // obtained before calling this.
-  virtual State GetState() = 0;
-
-  // Set the audio volume. The decoder monitor must be obtained before
-  // calling this.
-  virtual void SetVolume(double aVolume) = 0;
-  virtual void SetAudioCaptured(bool aCapture) = 0;
-
-  virtual void Shutdown() = 0;
-
-  // True if the state machine has shutdown, or is in the process of
-  // shutting down. The decoder monitor must be obtained before calling this.
-  virtual bool IsShutdown() = 0;
-
-  // Called from the main thread to get the duration. The decoder monitor
-  // must be obtained before calling this. It is in units of microseconds.
-  virtual int64_t GetDuration() = 0;
-
-  // Called from the main thread to set the duration of the media resource
-  // if it is able to be obtained via HTTP headers. Called from the 
-  // state machine thread to set the duration if it is obtained from the
-  // media metadata. The decoder monitor must be obtained before calling this.
-  // aDuration is in microseconds.
-  virtual void SetDuration(int64_t aDuration) = 0;
-
-  // Called while decoding metadata to set the end time of the media
-  // resource. The decoder monitor must be obtained before calling this.
-  // aEndTime is in microseconds.
-  virtual void SetEndTime(int64_t aEndTime) = 0;
-
-  // Set the media fragment end time. aEndTime is in microseconds.
-  virtual void SetFragmentEndTime(int64_t aEndTime) = 0;
-
-  // Functions used by assertions to ensure we're calling things
-  // on the appropriate threads.
-  virtual bool OnDecodeThread() const = 0;
-
-  // Returns true if the current thread is the state machine thread.
-  virtual bool OnStateMachineThread() const = 0;
-
-  virtual nsHTMLMediaElement::NextFrameStatus GetNextFrameStatus() = 0;
-
-  // Cause state transitions. These methods obtain the decoder monitor
-  // to synchronise the change of state, and to notify other threads
-  // that the state has changed.
-  virtual void Play() = 0;
-
-  // Seeks to aTime in seconds
-  virtual void Seek(double aTime) = 0;
-
-  // Returns the current playback position in seconds.
-  // Called from the main thread to get the current frame time. The decoder
-  // monitor must be obtained before calling this.
-  virtual double GetCurrentTime() const = 0;
-
-  // Clear the flag indicating that a playback position change event
-  // is currently queued. This is called from the main thread and must
-  // be called with the decode monitor held.
-  virtual void ClearPositionChangeFlag() = 0;
-
-  // Called from the main thread to set whether the media resource can
-  // seek into unbuffered ranges. The decoder monitor must be obtained
-  // before calling this.
-  virtual void SetSeekable(bool aSeekable) = 0;
-
-  // Returns true if the media resource can seek into unbuffered ranges,
-  // as set by SetSeekable(). The decoder monitor must be obtained before
-  // calling this.
-  virtual bool IsSeekable() = 0;
-
-  // Update the playback position. This can result in a timeupdate event
-  // and an invalidate of the frame being dispatched asynchronously if
-  // there is no such event currently queued.
-  // Only called on the decoder thread. Must be called with
-  // the decode monitor held.
-  virtual void UpdatePlaybackPosition(int64_t aTime) = 0;
-
-  virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
-
-  // Return true if the media is seekable using only buffered ranges.
-  virtual bool IsSeekableInBufferedRanges() = 0;
-
-  virtual int64_t VideoQueueMemoryInUse() = 0;
-  virtual int64_t AudioQueueMemoryInUse() = 0;
-
-  virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) = 0;
-
-  // Causes the state machine to switch to buffering state, and to
-  // immediately stop playback and buffer downloaded data. Must be called
-  // with the decode monitor held. Called on the state machine thread and
-  // the main thread.
-  virtual void StartBuffering() = 0;
-
-  // Sets the current size of the framebuffer used in MozAudioAvailable events.
-  // Called on the state machine thread and the main thread.
-  virtual void SetFrameBufferLength(uint32_t aLength) = 0;
-
-  // Called when a "MozAudioAvailable" event listener is added to the media
-  // element. Called on the main thread.
-  virtual void NotifyAudioAvailableListener() = 0;
-};
-
 class nsBuiltinDecoder : public nsMediaDecoder
 {
 public:
   typedef mozilla::MediaChannelStatistics MediaChannelStatistics;
   class DecodedStreamMainThreadListener;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
@@ -349,34 +227,34 @@ public:
     PLAY_STATE_PLAYING,
     PLAY_STATE_SEEKING,
     PLAY_STATE_ENDED,
     PLAY_STATE_SHUTDOWN
   };
 
   nsBuiltinDecoder();
   ~nsBuiltinDecoder();
-  
+
   virtual bool Init(nsHTMLMediaElement* aElement);
 
   // This method must be called by the owning object before that
   // object disposes of this decoder object.
   virtual void Shutdown();
-  
+
   virtual double GetCurrentTime();
 
   virtual nsresult Load(MediaResource* aResource,
                         nsIStreamListener** aListener,
                         nsMediaDecoder* aCloneDonor);
 
   // Called in |Load| to open the media resource.
   nsresult OpenResource(MediaResource* aResource,
                         nsIStreamListener** aStreamListener);
 
-  virtual nsDecoderStateMachine* CreateStateMachine() = 0;
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine() = 0;
 
   // Initialize state machine and schedule it.
   nsresult InitializeStateMachine(nsMediaDecoder* aCloneDonor);
 
   // Start playback of a video. 'Load' must have previously been
   // called.
   virtual nsresult Play();
 
@@ -397,17 +275,17 @@ public:
   // not connected to streams created by captureStreamUntilEnded.
 
   struct DecodedStreamData {
     DecodedStreamData(nsBuiltinDecoder* aDecoder,
                       int64_t aInitialTime, SourceMediaStream* aStream);
     ~DecodedStreamData();
 
     // The following group of fields are protected by the decoder's monitor
-    // and can be read or written on any thread.    
+    // and can be read or written on any thread.
     int64_t mLastAudioPacketTime; // microseconds
     int64_t mLastAudioPacketEndTime; // microseconds
     // Count of audio frames written to the stream
     int64_t mAudioFramesWritten;
     // Saved value of aInitialTime. Timestamp of the first audio and/or
     // video packet written.
     int64_t mInitialTime; // microseconds
     // mNextVideoTime is the end timestamp for the last packet sent to the stream.
@@ -557,54 +435,31 @@ public:
   void AudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength, float aTime);
 
   // Called by the state machine to notify the decoder that the duration
   // has changed.
   void DurationChanged();
 
   virtual bool OnStateMachineThread() const;
 
-  virtual bool OnDecodeThread() const {
-    return mDecoderStateMachine->OnDecodeThread();
-  }
+  virtual bool OnDecodeThread() const;
 
   // Returns the monitor for other threads to synchronise access to
   // state.
-  virtual ReentrantMonitor& GetReentrantMonitor() {
-    return mReentrantMonitor.GetReentrantMonitor();
-  }
+  virtual ReentrantMonitor& GetReentrantMonitor();
 
   // Constructs the time ranges representing what segments of the media
   // are buffered and playable.
-  virtual nsresult GetBuffered(nsTimeRanges* aBuffered) {
-    if (mDecoderStateMachine) {
-      return mDecoderStateMachine->GetBuffered(aBuffered);
-    }
-    return NS_ERROR_FAILURE;
-  }
+  virtual nsresult GetBuffered(nsTimeRanges* aBuffered);
+
+  virtual int64_t VideoQueueMemoryInUse();
 
-  virtual int64_t VideoQueueMemoryInUse() {
-    if (mDecoderStateMachine) {
-      return mDecoderStateMachine->VideoQueueMemoryInUse();
-    }
-    return 0;
-  }
+  virtual int64_t AudioQueueMemoryInUse();
 
-  virtual int64_t AudioQueueMemoryInUse() {
-    if (mDecoderStateMachine) {
-      return mDecoderStateMachine->AudioQueueMemoryInUse();
-    }
-    return 0;
-  }
-
-  virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {
-    if (mDecoderStateMachine) {
-      mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
-    }
-  }
+  virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
 
   // Sets the length of the framebuffer used in MozAudioAvailable events.
   // The new size must be between 512 and 16384.
   virtual nsresult RequestFrameBufferLength(uint32_t aLength);
 
   // Return the current state. Can be called on any thread. If called from
   // a non-main thread, the decoder monitor must be held.
   PlayState GetState() {
@@ -623,25 +478,21 @@ public:
   // Something has changed that could affect the computed playback rate,
   // so recompute it. The monitor must be held.
   void UpdatePlaybackRate();
 
   // The actual playback rate computation. The monitor must be held.
   double ComputePlaybackRate(bool* aReliable);
 
   // Make the decoder state machine update the playback position. Called by
-  // the reader on the decoder thread (Assertions for this checked by 
+  // the reader on the decoder thread (Assertions for this checked by
   // mDecoderStateMachine). This must be called with the decode monitor
   // held.
-  void UpdatePlaybackPosition(int64_t aTime)
-  {
-    mDecoderStateMachine->UpdatePlaybackPosition(aTime);
-  }
-
-  /****** 
+  void UpdatePlaybackPosition(int64_t aTime);
+  /******
    * The following methods must only be called on the main
    * thread.
    ******/
 
   // Change to a new play state. This updates the mState variable and
   // notifies any thread blocking on this object's monitor of the
   // change. Call on the main thread only.
   void ChangeState(PlayState aState);
@@ -696,20 +547,20 @@ public:
   // position.
   int64_t GetDownloadPosition();
 
   // Updates the approximate byte offset which playback has reached. This is
   // used to calculate the readyState transitions.
   void UpdatePlaybackOffset(int64_t aOffset);
 
   // Provide access to the state machine object
-  nsDecoderStateMachine* GetStateMachine() { return mDecoderStateMachine; }
+  nsBuiltinDecoderStateMachine* GetStateMachine();
 
   // Drop reference to state machine.  Only called during shutdown dance.
-  virtual void ReleaseStateMachine() { mDecoderStateMachine = nullptr; }
+  virtual void ReleaseStateMachine();
 
    // Called when a "MozAudioAvailable" event listener is added to the media
    // element. Called on the main thread.
    virtual void NotifyAudioAvailableListener();
 
   // Notifies the element that decoding has failed.
   virtual void DecodeError();
 
@@ -769,17 +620,17 @@ public:
    * The following member variables can be accessed from any thread.
    ******/
 
   // The state machine object for handling the decoding. It is safe to
   // call methods of this object from other threads. Its internal data
   // is synchronised on a monitor. The lifetime of this object is
   // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
   // is safe to access it during this period.
-  nsCOMPtr<nsDecoderStateMachine> mDecoderStateMachine;
+  nsCOMPtr<nsBuiltinDecoderStateMachine> mDecoderStateMachine;
 
   // Media data resource.
   nsAutoPtr<MediaResource> mResource;
 
   // |ReentrantMonitor| for detecting when the video play state changes. A call
   // to |Wait| on this monitor will block the thread until the next state
   // change.
   // Using a wrapper class to restrict direct access to the |ReentrantMonitor|
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -1210,17 +1210,17 @@ uint32_t nsBuiltinDecoderStateMachine::P
                                       audio->mFrames * aChannels,
                                       (aFrameOffset + frames) * aChannels);
   if (offset != -1) {
     mDecoder->UpdatePlaybackOffset(offset);
   }
   return frames;
 }
 
-nsresult nsBuiltinDecoderStateMachine::Init(nsDecoderStateMachine* aCloneDonor)
+nsresult nsBuiltinDecoderStateMachine::Init(nsBuiltinDecoderStateMachine* aCloneDonor)
 {
   nsBuiltinDecoderReader* cloneReader = nullptr;
   if (aCloneDonor) {
     cloneReader = static_cast<nsBuiltinDecoderStateMachine*>(aCloneDonor)->mReader;
   }
   return mReader->Init(cloneReader);
 }
 
--- a/content/media/nsBuiltinDecoderStateMachine.h
+++ b/content/media/nsBuiltinDecoderStateMachine.h
@@ -73,75 +73,139 @@ audio data off the queue and plays it wi
 hardware (via nsAudioStream and libsydneyaudio).
 
 */
 #if !defined(nsBuiltinDecoderStateMachine_h__)
 #define nsBuiltinDecoderStateMachine_h__
 
 #include "nsThreadUtils.h"
 #include "nsBuiltinDecoder.h"
-#include "nsBuiltinDecoderReader.h"
 #include "nsAudioAvailableEventManager.h"
 #include "nsHTMLMediaElement.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsITimer.h"
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 
+
+class nsBuiltinDecoderReader;
+
 /*
   The state machine class. This manages the decoding and seeking in the
   nsBuiltinDecoderReader on the decode thread, and A/V sync on the shared
   state machine thread, and controls the audio "push" thread.
 
   All internal state is synchronised via the decoder monitor. State changes
   are either propagated by NotifyAll on the monitor (typically when state
   changes need to be propagated to non-state machine threads) or by scheduling
   the state machine to run another cycle on the shared state machine thread.
 
   See nsBuiltinDecoder.h for more details.
 */
-class nsBuiltinDecoderStateMachine : public nsDecoderStateMachine
+class nsBuiltinDecoderStateMachine : public nsRunnable
 {
 public:
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::TimeDuration TimeDuration;
   typedef mozilla::VideoFrameContainer VideoFrameContainer;
   typedef nsBuiltinDecoder::DecodedStreamData DecodedStreamData;
   typedef mozilla::SourceMediaStream SourceMediaStream;
   typedef mozilla::AudioSegment AudioSegment;
   typedef mozilla::VideoSegment VideoSegment;
 
   nsBuiltinDecoderStateMachine(nsBuiltinDecoder* aDecoder, nsBuiltinDecoderReader* aReader, bool aRealTime = false);
   ~nsBuiltinDecoderStateMachine();
 
   // nsDecoderStateMachine interface
-  virtual nsresult Init(nsDecoderStateMachine* aCloneDonor);
-  State GetState()
-  {
+  virtual nsresult Init(nsBuiltinDecoderStateMachine* aCloneDonor);
+
+  // Enumeration for the valid decoding states
+  enum State {
+    DECODER_STATE_DECODING_METADATA,
+    DECODER_STATE_DECODING,
+    DECODER_STATE_SEEKING,
+    DECODER_STATE_BUFFERING,
+    DECODER_STATE_COMPLETED,
+    DECODER_STATE_SHUTDOWN
+  };
+
+  State GetState() {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mState;
   }
+
+  // Set the audio volume. The decoder monitor must be obtained before
+  // calling this.
   virtual void SetVolume(double aVolume);
   virtual void SetAudioCaptured(bool aCapture);
   virtual void Shutdown();
+
+  // Called from the main thread to get the duration. The decoder monitor
+  // must be obtained before calling this. It is in units of microseconds.
   virtual int64_t GetDuration();
+
+  // Called from the main thread to set the duration of the media resource
+  // if it is able to be obtained via HTTP headers. Called from the
+  // state machine thread to set the duration if it is obtained from the
+  // media metadata. The decoder monitor must be obtained before calling this.
+  // aDuration is in microseconds.
   virtual void SetDuration(int64_t aDuration);
+
+  // Called while decoding metadata to set the end time of the media
+  // resource. The decoder monitor must be obtained before calling this.
+  // aEndTime is in microseconds.
   void SetEndTime(int64_t aEndTime);
+
+  // Functions used by assertions to ensure we're calling things
+  // on the appropriate threads.
   virtual bool OnDecodeThread() const {
     return IsCurrentThread(mDecodeThread);
   }
+  bool OnStateMachineThread() const;
+  bool OnAudioThread() const {
+    return IsCurrentThread(mAudioThread);
+  }
 
   virtual nsHTMLMediaElement::NextFrameStatus GetNextFrameStatus();
+
+  // Cause state transitions. These methods obtain the decoder monitor
+  // to synchronise the change of state, and to notify other threads
+  // that the state has changed.
   virtual void Play();
+
+  // Seeks to aTime in seconds.
   virtual void Seek(double aTime);
+
+  // Returns the current playback position in seconds.
+  // Called from the main thread to get the current frame time. The decoder
+  // monitor must be obtained before calling this.
   virtual double GetCurrentTime() const;
+
+  // Clear the flag indicating that a playback position change event
+  // is currently queued. This is called from the main thread and must
+  // be called with the decode monitor held.
   virtual void ClearPositionChangeFlag();
+
+  // Called from the main thread to set whether the media resource can
+  // seek into unbuffered ranges. The decoder monitor must be obtained
+  // before calling this.
   virtual void SetSeekable(bool aSeekable);
+
+  // Update the playback position. This can result in a timeupdate event
+  // and an invalidate of the frame being dispatched asynchronously if
+  // there is no such event currently queued.
+  // Only called on the decoder thread. Must be called with
+  // the decode monitor held.
   virtual void UpdatePlaybackPosition(int64_t aTime);
+
+  // Causes the state machine to switch to buffering state, and to
+  // immediately stop playback and buffer downloaded data. Must be called
+  // with the decode monitor held. Called on the state machine thread and
+  // the main thread.
   virtual void StartBuffering();
 
   // State machine thread run function. Defers to RunStateMachine().
   NS_IMETHOD Run();
 
   // This is called on the state machine thread and audio thread.
   // The decoder monitor must be obtained before calling this.
   bool HasAudio() const {
@@ -158,34 +222,26 @@ public:
 
   // Should be called by main thread.
   bool HaveNextFrameData() const;
 
   // Must be called with the decode monitor held.
   bool IsBuffering() const {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
-    return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_BUFFERING;
+    return mState == DECODER_STATE_BUFFERING;
   }
 
   // Must be called with the decode monitor held.
   bool IsSeeking() const {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
-    return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_SEEKING;
+    return mState == DECODER_STATE_SEEKING;
   }
 
-  // Functions used by assertions to ensure we're calling things
-  // on the appropriate threads.
-  bool OnAudioThread() const {
-    return IsCurrentThread(mAudioThread);
-  }
-
-  bool OnStateMachineThread() const;
- 
   nsresult GetBuffered(nsTimeRanges* aBuffered);
 
   int64_t VideoQueueMemoryInUse() {
     if (mReader) {
       return mReader->VideoQueueMemoryInUse();
     }
     return 0;
   }
@@ -204,16 +260,17 @@ public:
     return mEndTime;
   }
 
   bool IsSeekable() {
     mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mSeekable;
   }
 
+  // Return true if the media is seekable using only buffered ranges.
   bool IsSeekableInBufferedRanges() {
     if (mReader) {
       return mReader->IsSeekableInBufferedRanges();
     }
     return false;
   }
 
   // Sets the current frame buffer length for the MozAudioAvailable event.
--- a/content/media/ogg/nsOggDecoder.cpp
+++ b/content/media/ogg/nsOggDecoder.cpp
@@ -3,12 +3,12 @@
 /* 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 "nsBuiltinDecoderStateMachine.h"
 #include "nsOggReader.h"
 #include "nsOggDecoder.h"
 
-nsDecoderStateMachine* nsOggDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsOggDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsOggReader(this));
 }
--- a/content/media/ogg/nsOggDecoder.h
+++ b/content/media/ogg/nsOggDecoder.h
@@ -12,12 +12,12 @@ class nsOggDecoder : public nsBuiltinDec
 {
 public:
   virtual nsMediaDecoder* Clone() {
     if (!nsHTMLMediaElement::IsOggEnabled()) {
       return nullptr;
     }
     return new nsOggDecoder();
   }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -331,17 +331,17 @@ nsresult nsOggReader::ReadMetadata(nsVid
     }
   }
 
   if (HasAudio() || HasVideo()) {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
     MediaResource* resource = mDecoder->GetResource();
     if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
-        mDecoder->GetStateMachine()->GetState() != nsDecoderStateMachine::DECODER_STATE_SHUTDOWN &&
+        !mDecoder->GetStateMachine()->IsShutdown() &&
         resource->GetLength() >= 0 &&
         mDecoder->GetStateMachine()->IsSeekable())
     {
       // We didn't get a duration from the index or a Content-Duration header.
       // Seek to the end of file to find the end time.
       mDecoder->GetResource()->StartSeekingForMetadata();
       int64_t length = resource->GetLength();
 
--- a/content/media/omx/nsMediaOmxDecoder.cpp
+++ b/content/media/omx/nsMediaOmxDecoder.cpp
@@ -13,16 +13,16 @@ nsMediaOmxDecoder::nsMediaOmxDecoder() :
 {
 }
 
 nsMediaDecoder* nsMediaOmxDecoder::Clone()
 {
   return new nsMediaOmxDecoder();
 }
 
-nsDecoderStateMachine* nsMediaOmxDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsMediaOmxDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsMediaOmxReader(this));
 }
 
 nsMediaOmxDecoder::~nsMediaOmxDecoder()
 {
 }
--- a/content/media/omx/nsMediaOmxDecoder.h
+++ b/content/media/omx/nsMediaOmxDecoder.h
@@ -11,12 +11,12 @@
 
 class nsMediaOmxDecoder : public nsBuiltinDecoder
 {
 public:
   nsMediaOmxDecoder();
   ~nsMediaOmxDecoder();
 
   virtual nsMediaDecoder* Clone();
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/omx/nsMediaOmxReader.cpp
+++ b/content/media/omx/nsMediaOmxReader.cpp
@@ -1,16 +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 "nsMediaOmxReader.h"
 
+#include "nsBuiltinDecoderStateMachine.h"
 #include "mozilla/TimeStamp.h"
 #include "nsTimeRanges.h"
 #include "MediaResource.h"
 #include "VideoUtils.h"
 #include "nsMediaOmxDecoder.h"
 
 using namespace android;
 using namespace mozilla;
--- a/content/media/plugins/nsMediaPluginDecoder.cpp
+++ b/content/media/plugins/nsMediaPluginDecoder.cpp
@@ -7,12 +7,12 @@
 #include "nsBuiltinDecoderStateMachine.h"
 #include "nsMediaPluginDecoder.h"
 #include "nsMediaPluginReader.h"
 
 nsMediaPluginDecoder::nsMediaPluginDecoder(const nsACString& aType) : mType(aType)
 {
 }
 
-nsDecoderStateMachine* nsMediaPluginDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsMediaPluginDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsMediaPluginReader(this));
 }
--- a/content/media/plugins/nsMediaPluginDecoder.h
+++ b/content/media/plugins/nsMediaPluginDecoder.h
@@ -16,12 +16,12 @@ public:
   nsMediaPluginDecoder(const nsACString& aType);
 
   const nsresult GetContentType(nsACString& aType) const {
     aType = mType;
     return NS_OK;
   }
 
   virtual nsMediaDecoder* Clone() { return new nsMediaPluginDecoder(mType); }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/plugins/nsMediaPluginReader.cpp
+++ b/content/media/plugins/nsMediaPluginReader.cpp
@@ -1,20 +1,21 @@
 /* -*- 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 "nsMediaPluginReader.h"
 #include "mozilla/TimeStamp.h"
 #include "nsTimeRanges.h"
 #include "MediaResource.h"
 #include "VideoUtils.h"
-#include "nsMediaPluginReader.h"
 #include "nsMediaPluginDecoder.h"
 #include "nsMediaPluginHost.h"
+#include "nsBuiltinDecoderStateMachine.h"
 
 using namespace mozilla;
 
 nsMediaPluginReader::nsMediaPluginReader(nsBuiltinDecoder *aDecoder) :
   nsBuiltinDecoderReader(aDecoder),
   mPlugin(NULL),
   mHasAudio(false),
   mHasVideo(false),
--- a/content/media/raw/nsRawDecoder.cpp
+++ b/content/media/raw/nsRawDecoder.cpp
@@ -1,12 +1,12 @@
 /* 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 "nsBuiltinDecoderStateMachine.h"
 #include "nsRawReader.h"
 #include "nsRawDecoder.h"
 
-nsDecoderStateMachine* nsRawDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsRawDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsRawReader(this), true);
 }
--- a/content/media/raw/nsRawDecoder.h
+++ b/content/media/raw/nsRawDecoder.h
@@ -11,12 +11,12 @@ class nsRawDecoder : public nsBuiltinDec
 {
 public:
   virtual nsMediaDecoder* Clone() { 
     if (!nsHTMLMediaElement::IsRawEnabled()) {
       return nullptr;
     }    
     return new nsRawDecoder();
   }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/wave/nsWaveDecoder.cpp
+++ b/content/media/wave/nsWaveDecoder.cpp
@@ -2,12 +2,12 @@
 /* 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 "nsBuiltinDecoderStateMachine.h"
 #include "nsWaveReader.h"
 #include "nsWaveDecoder.h"
 
-nsDecoderStateMachine* nsWaveDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsWaveDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsWaveReader(this));
 }
--- a/content/media/wave/nsWaveDecoder.h
+++ b/content/media/wave/nsWaveDecoder.h
@@ -24,12 +24,12 @@ class nsWaveDecoder : public nsBuiltinDe
 {
 public:
   virtual nsMediaDecoder* Clone() {
     if (!nsHTMLMediaElement::IsWaveEnabled()) {
       return nullptr;
     }
     return new nsWaveDecoder();
   }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -3,16 +3,17 @@
 /* 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 "nsError.h"
 #include "nsBuiltinDecoder.h"
 #include "MediaResource.h"
 #include "nsWaveReader.h"
 #include "nsTimeRanges.h"
+#include "nsBuiltinDecoderStateMachine.h"
 #include "VideoUtils.h"
 
 #include "mozilla/StandardInteger.h"
 
 using namespace mozilla;
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
--- a/content/media/webm/nsWebMDecoder.cpp
+++ b/content/media/webm/nsWebMDecoder.cpp
@@ -3,12 +3,12 @@
 /* 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 "nsBuiltinDecoderStateMachine.h"
 #include "nsWebMReader.h"
 #include "nsWebMDecoder.h"
 
-nsDecoderStateMachine* nsWebMDecoder::CreateStateMachine()
+nsBuiltinDecoderStateMachine* nsWebMDecoder::CreateStateMachine()
 {
   return new nsBuiltinDecoderStateMachine(this, new nsWebMReader(this));
 }
--- a/content/media/webm/nsWebMDecoder.h
+++ b/content/media/webm/nsWebMDecoder.h
@@ -12,12 +12,12 @@ class nsWebMDecoder : public nsBuiltinDe
 {
 public:
   virtual nsMediaDecoder* Clone() {
     if (!nsHTMLMediaElement::IsWebMEnabled()) {
       return nullptr;
     }
     return new nsWebMDecoder();
   }
-  virtual nsDecoderStateMachine* CreateStateMachine();
+  virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
 };
 
 #endif