content/media/MediaDecoderStateMachine.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7 Each video element for a media file has two threads:
     9   1) The Audio thread writes the decoded audio data to the audio
    10      hardware. This is done in a separate thread to ensure that the
    11      audio hardware gets a constant stream of data without
    12      interruption due to decoding or display. At some point
    13      AudioStream will be refactored to have a callback interface
    14      where it asks for data and an extra thread will no longer be
    15      needed.
    17   2) The decode thread. This thread reads from the media stream and
    18      decodes the Theora and Vorbis data. It places the decoded data into
    19      queues for the other threads to pull from.
    21 All file reads, seeks, and all decoding must occur on the decode thread.
    22 Synchronisation of state between the thread is done via a monitor owned
    23 by MediaDecoder.
    25 The lifetime of the decode and audio threads is controlled by the state
    26 machine when it runs on the shared state machine thread. When playback
    27 needs to occur they are created and events dispatched to them to run
    28 them. These events exit when decoding/audio playback is completed or
    29 no longer required.
    31 A/V synchronisation is handled by the state machine. It examines the audio
    32 playback time and compares this to the next frame in the queue of video
    33 frames. If it is time to play the video frame it is then displayed, otherwise
    34 it schedules the state machine to run again at the time of the next frame.
    36 Frame skipping is done in the following ways:
    38   1) The state machine will skip all frames in the video queue whose
    39      display time is less than the current audio time. This ensures
    40      the correct frame for the current time is always displayed.
    42   2) The decode thread will stop decoding interframes and read to the
    43      next keyframe if it determines that decoding the remaining
    44      interframes will cause playback issues. It detects this by:
    45        a) If the amount of audio data in the audio queue drops
    46           below a threshold whereby audio may start to skip.
    47        b) If the video queue drops below a threshold where it
    48           will be decoding video data that won't be displayed due
    49           to the decode thread dropping the frame immediately.
    51 When hardware accelerated graphics is not available, YCbCr conversion
    52 is done on the decode thread when video frames are decoded.
    54 The decode thread pushes decoded audio and videos frames into two
    55 separate queues - one for audio and one for video. These are kept
    56 separate to make it easy to constantly feed audio data to the audio
    57 hardware while allowing frame skipping of video data. These queues are
    58 threadsafe, and neither the decode, audio, or state machine should
    59 be able to monopolize them, and cause starvation of the other threads.
    61 Both queues are bounded by a maximum size. When this size is reached
    62 the decode thread will no longer decode video or audio depending on the
    63 queue that has reached the threshold. If both queues are full, the decode
    64 thread will wait on the decoder monitor.
    66 When the decode queues are full (they've reaced their maximum size) and
    67 the decoder is not in PLAYING play state, the state machine may opt
    68 to shut down the decode thread in order to conserve resources.
    70 During playback the audio thread will be idle (via a Wait() on the
    71 monitor) if the audio queue is empty. Otherwise it constantly pops
    72 audio data off the queue and plays it with a blocking write to the audio
    73 hardware (via AudioStream).
    75 */
    76 #if !defined(MediaDecoderStateMachine_h__)
    77 #define MediaDecoderStateMachine_h__
    79 #include "mozilla/Attributes.h"
    80 #include "nsThreadUtils.h"
    81 #include "MediaDecoder.h"
    82 #include "mozilla/ReentrantMonitor.h"
    83 #include "MediaDecoderReader.h"
    84 #include "MediaDecoderOwner.h"
    85 #include "MediaMetadataManager.h"
    87 class nsITimer;
    89 namespace mozilla {
    91 class AudioSegment;
    92 class VideoSegment;
    93 class MediaTaskQueue;
    94 class SharedThreadPool;
    96 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
    97 // GetTickCount() and conflicts with MediaDecoderStateMachine::GetCurrentTime
    98 // implementation.
    99 #ifdef GetCurrentTime
   100 #undef GetCurrentTime
   101 #endif
   103 /*
   104   The state machine class. This manages the decoding and seeking in the
   105   MediaDecoderReader on the decode thread, and A/V sync on the shared
   106   state machine thread, and controls the audio "push" thread.
   108   All internal state is synchronised via the decoder monitor. State changes
   109   are either propagated by NotifyAll on the monitor (typically when state
   110   changes need to be propagated to non-state machine threads) or by scheduling
   111   the state machine to run another cycle on the shared state machine thread.
   113   See MediaDecoder.h for more details.
   114 */
   115 class MediaDecoderStateMachine
   116 {
   117   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderStateMachine)
   118 public:
   119   typedef MediaDecoder::DecodedStreamData DecodedStreamData;
   120   MediaDecoderStateMachine(MediaDecoder* aDecoder,
   121                                MediaDecoderReader* aReader,
   122                                bool aRealTime = false);
   124   nsresult Init(MediaDecoderStateMachine* aCloneDonor);
   126   // Enumeration for the valid decoding states
   127   enum State {
   128     DECODER_STATE_DECODING_METADATA,
   129     DECODER_STATE_WAIT_FOR_RESOURCES,
   130     DECODER_STATE_DORMANT,
   131     DECODER_STATE_DECODING,
   132     DECODER_STATE_SEEKING,
   133     DECODER_STATE_BUFFERING,
   134     DECODER_STATE_COMPLETED,
   135     DECODER_STATE_SHUTDOWN
   136   };
   138   State GetState() {
   139     AssertCurrentThreadInMonitor();
   140     return mState;
   141   }
   143   // Set the audio volume. The decoder monitor must be obtained before
   144   // calling this.
   145   void SetVolume(double aVolume);
   146   void SetAudioCaptured(bool aCapture);
   148   // Check if the decoder needs to become dormant state.
   149   bool IsDormantNeeded();
   150   // Set/Unset dormant state.
   151   void SetDormant(bool aDormant);
   152   void Shutdown();
   154   // Called from the main thread to get the duration. The decoder monitor
   155   // must be obtained before calling this. It is in units of microseconds.
   156   int64_t GetDuration();
   158   // Called from the main thread to set the duration of the media resource
   159   // if it is able to be obtained via HTTP headers. Called from the
   160   // state machine thread to set the duration if it is obtained from the
   161   // media metadata. The decoder monitor must be obtained before calling this.
   162   // aDuration is in microseconds.
   163   void SetDuration(int64_t aDuration);
   165   // Called while decoding metadata to set the end time of the media
   166   // resource. The decoder monitor must be obtained before calling this.
   167   // aEndTime is in microseconds.
   168   void SetMediaEndTime(int64_t aEndTime);
   170   // Called from main thread to update the duration with an estimated value.
   171   // The duration is only changed if its significantly different than the
   172   // the current duration, as the incoming duration is an estimate and so
   173   // often is unstable as more data is read and the estimate is updated.
   174   // Can result in a durationchangeevent. aDuration is in microseconds.
   175   void UpdateEstimatedDuration(int64_t aDuration);
   177   // Functions used by assertions to ensure we're calling things
   178   // on the appropriate threads.
   179   bool OnDecodeThread() const;
   180   bool OnStateMachineThread() const;
   181   bool OnAudioThread() const {
   182     return IsCurrentThread(mAudioThread);
   183   }
   185   MediaDecoderOwner::NextFrameStatus GetNextFrameStatus();
   187   // Cause state transitions. These methods obtain the decoder monitor
   188   // to synchronise the change of state, and to notify other threads
   189   // that the state has changed.
   190   void Play();
   192   // Seeks to the decoder to aTarget asynchronously.
   193   void Seek(const SeekTarget& aTarget);
   195   // Returns the current playback position in seconds.
   196   // Called from the main thread to get the current frame time. The decoder
   197   // monitor must be obtained before calling this.
   198   double GetCurrentTime() const;
   200   // Clear the flag indicating that a playback position change event
   201   // is currently queued. This is called from the main thread and must
   202   // be called with the decode monitor held.
   203   void ClearPositionChangeFlag();
   205   // Called from the main thread or the decoder thread to set whether the media
   206   // resource can seek into unbuffered ranges. The decoder monitor must be
   207   // obtained before calling this.
   208   void SetTransportSeekable(bool aSeekable);
   210   // Called from the main thread or the decoder thread to set whether the media
   211   // can seek to random location. This is not true for chained ogg and WebM
   212   // media without index. The decoder monitor must be obtained before calling
   213   // this.
   214   void SetMediaSeekable(bool aSeekable);
   216   // Update the playback position. This can result in a timeupdate event
   217   // and an invalidate of the frame being dispatched asynchronously if
   218   // there is no such event currently queued.
   219   // Only called on the decoder thread. Must be called with
   220   // the decode monitor held.
   221   void UpdatePlaybackPosition(int64_t aTime);
   223   // Causes the state machine to switch to buffering state, and to
   224   // immediately stop playback and buffer downloaded data. Must be called
   225   // with the decode monitor held. Called on the state machine thread and
   226   // the main thread.
   227   void StartBuffering();
   229   // This is called on the state machine thread and audio thread.
   230   // The decoder monitor must be obtained before calling this.
   231   bool HasAudio() const {
   232     AssertCurrentThreadInMonitor();
   233     return mInfo.HasAudio();
   234   }
   236   // This is called on the state machine thread and audio thread.
   237   // The decoder monitor must be obtained before calling this.
   238   bool HasVideo() const {
   239     AssertCurrentThreadInMonitor();
   240     return mInfo.HasVideo();
   241   }
   243   // Should be called by main thread.
   244   bool HaveNextFrameData();
   246   // Must be called with the decode monitor held.
   247   bool IsBuffering() const {
   248     AssertCurrentThreadInMonitor();
   250     return mState == DECODER_STATE_BUFFERING;
   251   }
   253   // Must be called with the decode monitor held.
   254   bool IsSeeking() const {
   255     AssertCurrentThreadInMonitor();
   257     return mState == DECODER_STATE_SEEKING;
   258   }
   260   nsresult GetBuffered(dom::TimeRanges* aBuffered);
   262   void SetPlaybackRate(double aPlaybackRate);
   263   void SetPreservesPitch(bool aPreservesPitch);
   265   size_t SizeOfVideoQueue() {
   266     if (mReader) {
   267       return mReader->SizeOfVideoQueueInBytes();
   268     }
   269     return 0;
   270   }
   272   size_t SizeOfAudioQueue() {
   273     if (mReader) {
   274       return mReader->SizeOfAudioQueueInBytes();
   275     }
   276     return 0;
   277   }
   279   void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
   281   int64_t GetEndMediaTime() const {
   282     AssertCurrentThreadInMonitor();
   283     return mEndTime;
   284   }
   286   bool IsTransportSeekable() {
   287     AssertCurrentThreadInMonitor();
   288     return mTransportSeekable;
   289   }
   291   bool IsMediaSeekable() {
   292     AssertCurrentThreadInMonitor();
   293     return mMediaSeekable;
   294   }
   296   // Returns the shared state machine thread.
   297   nsIEventTarget* GetStateMachineThread();
   299   // Calls ScheduleStateMachine() after taking the decoder lock. Also
   300   // notifies the decoder thread in case it's waiting on the decoder lock.
   301   void ScheduleStateMachineWithLockAndWakeDecoder();
   303   // Schedules the shared state machine thread to run the state machine
   304   // in aUsecs microseconds from now, if it's not already scheduled to run
   305   // earlier, in which case the request is discarded.
   306   nsresult ScheduleStateMachine(int64_t aUsecs = 0);
   308   // Timer function to implement ScheduleStateMachine(aUsecs).
   309   nsresult TimeoutExpired(int aGeneration);
   311   // Set the media fragment end time. aEndTime is in microseconds.
   312   void SetFragmentEndTime(int64_t aEndTime);
   314   // Drop reference to decoder.  Only called during shutdown dance.
   315   void ReleaseDecoder() {
   316     MOZ_ASSERT(mReader);
   317     if (mReader) {
   318       mReader->ReleaseDecoder();
   319     }
   320     mDecoder = nullptr;
   321   }
   323   // If we're playing into a MediaStream, record the current point in the
   324   // MediaStream and the current point in our media resource so later we can
   325   // convert MediaStream playback positions to media resource positions. Best to
   326   // call this while we're not playing (while the MediaStream is blocked). Can
   327   // be called on any thread with the decoder monitor held.
   328   void SetSyncPointForMediaStream();
   329   int64_t GetCurrentTimeViaMediaStreamSync();
   331   // Copy queued audio/video data in the reader to any output MediaStreams that
   332   // need it.
   333   void SendStreamData();
   334   void FinishStreamData();
   335   bool HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs);
   336   bool HaveEnoughDecodedVideo();
   338   // Returns true if the state machine has shutdown or is in the process of
   339   // shutting down. The decoder monitor must be held while calling this.
   340   bool IsShutdown();
   342   void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags);
   344   // Returns true if we're currently playing. The decoder monitor must
   345   // be held.
   346   bool IsPlaying();
   348   // Called when the reader may have acquired the hardware resources required
   349   // to begin decoding. The state machine may move into DECODING_METADATA if
   350   // appropriate. The decoder monitor must be held while calling this.
   351   void NotifyWaitingForResourcesStatusChanged();
   353   // Notifies the state machine that should minimize the number of samples
   354   // decoded we preroll, until playback starts. The first time playback starts
   355   // the state machine is free to return to prerolling normally. Note
   356   // "prerolling" in this context refers to when we decode and buffer decoded
   357   // samples in advance of when they're needed for playback.
   358   void SetMinimizePrerollUntilPlaybackStarts();
   360 protected:
   361   virtual ~MediaDecoderStateMachine();
   363   void AssertCurrentThreadInMonitor() const { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); }
   365   class WakeDecoderRunnable : public nsRunnable {
   366   public:
   367     WakeDecoderRunnable(MediaDecoderStateMachine* aSM)
   368       : mMutex("WakeDecoderRunnable"), mStateMachine(aSM) {}
   369     NS_IMETHOD Run() MOZ_OVERRIDE
   370     {
   371       nsRefPtr<MediaDecoderStateMachine> stateMachine;
   372       {
   373         // Don't let Run() (called by media stream graph thread) race with
   374         // Revoke() (called by decoder state machine thread)
   375         MutexAutoLock lock(mMutex);
   376         if (!mStateMachine)
   377           return NS_OK;
   378         stateMachine = mStateMachine;
   379       }
   380       stateMachine->ScheduleStateMachineWithLockAndWakeDecoder();
   381       return NS_OK;
   382     }
   383     void Revoke()
   384     {
   385       MutexAutoLock lock(mMutex);
   386       mStateMachine = nullptr;
   387     }
   389     Mutex mMutex;
   390     // Protected by mMutex.
   391     // We don't use an owning pointer here, because keeping mStateMachine alive
   392     // would mean in some cases we'd have to destroy mStateMachine from this
   393     // object, which would be problematic since MediaDecoderStateMachine can
   394     // only be destroyed on the main thread whereas this object can be destroyed
   395     // on the media stream graph thread.
   396     MediaDecoderStateMachine* mStateMachine;
   397   };
   398   WakeDecoderRunnable* GetWakeDecoderRunnable();
   400   MediaQueue<AudioData>& AudioQueue() { return mReader->AudioQueue(); }
   401   MediaQueue<VideoData>& VideoQueue() { return mReader->VideoQueue(); }
   403   // True if our buffers of decoded audio are not full, and we should
   404   // decode more.
   405   bool NeedToDecodeAudio();
   407   // Decodes some audio. This should be run on the decode task queue.
   408   void DecodeAudio();
   410   // True if our buffers of decoded video are not full, and we should
   411   // decode more.
   412   bool NeedToDecodeVideo();
   414   // Decodes some video. This should be run on the decode task queue.
   415   void DecodeVideo();
   417   // Returns true if we've got less than aAudioUsecs microseconds of decoded
   418   // and playable data. The decoder monitor must be held.
   419   bool HasLowDecodedData(int64_t aAudioUsecs);
   421   // Returns true if we're running low on data which is not yet decoded.
   422   // The decoder monitor must be held.
   423   bool HasLowUndecodedData();
   425   // Returns true if we have less than aUsecs of undecoded data available.
   426   bool HasLowUndecodedData(double aUsecs);
   428   // Returns the number of unplayed usecs of audio we've got decoded and/or
   429   // pushed to the hardware waiting to play. This is how much audio we can
   430   // play without having to run the audio decoder. The decoder monitor
   431   // must be held.
   432   int64_t AudioDecodedUsecs();
   434   // Returns true when there's decoded audio waiting to play.
   435   // The decoder monitor must be held.
   436   bool HasFutureAudio();
   438   // Returns true if we recently exited "quick buffering" mode.
   439   bool JustExitedQuickBuffering();
   441   // Waits on the decoder ReentrantMonitor for aUsecs microseconds. If the decoder
   442   // monitor is awoken by a Notify() call, we'll continue waiting, unless
   443   // we've moved into shutdown state. This enables us to ensure that we
   444   // wait for a specified time, and that the myriad of Notify()s we do on
   445   // the decoder monitor don't cause the audio thread to be starved. aUsecs
   446   // values of less than 1 millisecond are rounded up to 1 millisecond
   447   // (see bug 651023). The decoder monitor must be held. Called only on the
   448   // audio thread.
   449   void Wait(int64_t aUsecs);
   451   // Dispatches an asynchronous event to update the media element's ready state.
   452   void UpdateReadyState();
   454   // Resets playback timing data. Called when we seek, on the decode thread.
   455   void ResetPlayback();
   457   // Returns the audio clock, if we have audio, or -1 if we don't.
   458   // Called on the state machine thread.
   459   int64_t GetAudioClock();
   461   // Get the video stream position, taking the |playbackRate| change into
   462   // account. This is a position in the media, not the duration of the playback
   463   // so far.
   464   int64_t GetVideoStreamPosition();
   466   // Return the current time, either the audio clock if available (if the media
   467   // has audio, and the playback is possible), or a clock for the video.
   468   // Called on the state machine thread.
   469   int64_t GetClock();
   471   // Returns the presentation time of the first audio or video frame in the
   472   // media.  If the media has video, it returns the first video frame. The
   473   // decoder monitor must be held with exactly one lock count. Called on the
   474   // state machine thread.
   475   VideoData* FindStartTime();
   477   // Update only the state machine's current playback position (and duration,
   478   // if unknown).  Does not update the playback position on the decoder or
   479   // media element -- use UpdatePlaybackPosition for that.  Called on the state
   480   // machine thread, caller must hold the decoder lock.
   481   void UpdatePlaybackPositionInternal(int64_t aTime);
   483   // Pushes the image down the rendering pipeline. Called on the shared state
   484   // machine thread. The decoder monitor must *not* be held when calling this.
   485   void RenderVideoFrame(VideoData* aData, TimeStamp aTarget);
   487   // If we have video, display a video frame if it's time for display has
   488   // arrived, otherwise sleep until it's time for the next frame. Update the
   489   // current frame time as appropriate, and trigger ready state update.  The
   490   // decoder monitor must be held with exactly one lock count. Called on the
   491   // state machine thread.
   492   void AdvanceFrame();
   494   // Write aFrames of audio frames of silence to the audio hardware. Returns
   495   // the number of frames actually written. The write size is capped at
   496   // SILENCE_BYTES_CHUNK (32kB), so must be called in a loop to write the
   497   // desired number of frames. This ensures that the playback position
   498   // advances smoothly, and guarantees that we don't try to allocate an
   499   // impossibly large chunk of memory in order to play back silence. Called
   500   // on the audio thread.
   501   uint32_t PlaySilence(uint32_t aFrames,
   502                        uint32_t aChannels,
   503                        uint64_t aFrameOffset);
   505   // Pops an audio chunk from the front of the audio queue, and pushes its
   506   // audio data to the audio hardware.
   507   uint32_t PlayFromAudioQueue(uint64_t aFrameOffset, uint32_t aChannels);
   509   // Stops the audio thread. The decoder monitor must be held with exactly
   510   // one lock count. Called on the state machine thread.
   511   void StopAudioThread();
   513   // Starts the audio thread. The decoder monitor must be held with exactly
   514   // one lock count. Called on the state machine thread.
   515   nsresult StartAudioThread();
   517   // The main loop for the audio thread. Sent to the thread as
   518   // an nsRunnableMethod. This continually does blocking writes to
   519   // to audio stream to play audio data.
   520   void AudioLoop();
   522   // Sets internal state which causes playback of media to pause.
   523   // The decoder monitor must be held.
   524   void StopPlayback();
   526   // Sets internal state which causes playback of media to begin or resume.
   527   // Must be called with the decode monitor held.
   528   void StartPlayback();
   530   // Moves the decoder into decoding state. Called on the state machine
   531   // thread. The decoder monitor must be held.
   532   void StartDecoding();
   534   // Moves the decoder into the shutdown state, and dispatches an error
   535   // event to the media element. This begins shutting down the decoder.
   536   // The decoder monitor must be held. This is only called on the
   537   // decode thread.
   538   void DecodeError();
   540   void StartWaitForResources();
   542   // Dispatches a task to the decode task queue to begin decoding metadata.
   543   // This is threadsafe and can be called on any thread.
   544   // The decoder monitor must be held.
   545   nsresult EnqueueDecodeMetadataTask();
   547   nsresult DispatchAudioDecodeTaskIfNeeded();
   549   // Ensures a to decode audio has been dispatched to the decode task queue.
   550   // If a task to decode has already been dispatched, this does nothing,
   551   // otherwise this dispatches a task to do the decode.
   552   // This is called on the state machine or decode threads.
   553   // The decoder monitor must be held.
   554   nsresult EnsureAudioDecodeTaskQueued();
   556   nsresult DispatchVideoDecodeTaskIfNeeded();
   558   // Ensures a to decode video has been dispatched to the decode task queue.
   559   // If a task to decode has already been dispatched, this does nothing,
   560   // otherwise this dispatches a task to do the decode.
   561   // The decoder monitor must be held.
   562   nsresult EnsureVideoDecodeTaskQueued();
   564   // Dispatches a task to the decode task queue to seek the decoder.
   565   // The decoder monitor must be held.
   566   nsresult EnqueueDecodeSeekTask();
   568   // Calls the reader's SetIdle(), with aIsIdle as parameter. This is only
   569   // called in a task dispatched to the decode task queue, don't call it
   570   // directly.
   571   void SetReaderIdle();
   572   void SetReaderActive();
   574   // Re-evaluates the state and determines whether we need to dispatch
   575   // events to run the decode, or if not whether we should set the reader
   576   // to idle mode. This is threadsafe, and can be called from any thread.
   577   // The decoder monitor must be held.
   578   void DispatchDecodeTasksIfNeeded();
   580   // Called before we do anything on the decode task queue to set the reader
   581   // as not idle if it was idle. This is called before we decode, seek, or
   582   // decode metadata (in case we were dormant or awaiting resources).
   583   void EnsureActive();
   585   // Queries our state to see whether the decode has finished for all streams.
   586   // If so, we move into DECODER_STATE_COMPLETED and schedule the state machine
   587   // to run.
   588   // The decoder monitor must be held.
   589   void CheckIfDecodeComplete();
   591   // Returns the "media time". This is the absolute time which the media
   592   // playback has reached. i.e. this returns values in the range
   593   // [mStartTime, mEndTime], and mStartTime will not be 0 if the media does
   594   // not start at 0. Note this is different to the value returned
   595   // by GetCurrentTime(), which is in the range [0,duration].
   596   int64_t GetMediaTime() const {
   597     AssertCurrentThreadInMonitor();
   598     return mStartTime + mCurrentFrameTime;
   599   }
   601   // Returns an upper bound on the number of microseconds of audio that is
   602   // decoded and playable. This is the sum of the number of usecs of audio which
   603   // is decoded and in the reader's audio queue, and the usecs of unplayed audio
   604   // which has been pushed to the audio hardware for playback. Note that after
   605   // calling this, the audio hardware may play some of the audio pushed to
   606   // hardware, so this can only be used as a upper bound. The decoder monitor
   607   // must be held when calling this. Called on the decode thread.
   608   int64_t GetDecodedAudioDuration();
   610   // Load metadata. Called on the decode thread. The decoder monitor
   611   // must be held with exactly one lock count.
   612   nsresult DecodeMetadata();
   614   // Seeks to mSeekTarget. Called on the decode thread. The decoder monitor
   615   // must be held with exactly one lock count.
   616   void DecodeSeek();
   618   // Decode loop, decodes data until EOF or shutdown.
   619   // Called on the decode thread.
   620   void DecodeLoop();
   622   void CallDecodeMetadata();
   624   // Copy audio from an AudioData packet to aOutput. This may require
   625   // inserting silence depending on the timing of the audio packet.
   626   void SendStreamAudio(AudioData* aAudio, DecodedStreamData* aStream,
   627                        AudioSegment* aOutput);
   629   // State machine thread run function. Defers to RunStateMachine().
   630   nsresult CallRunStateMachine();
   632   // Performs one "cycle" of the state machine. Polls the state, and may send
   633   // a video frame to be displayed, and generally manages the decode. Called
   634   // periodically via timer to ensure the video stays in sync.
   635   nsresult RunStateMachine();
   637   bool IsStateMachineScheduled() const {
   638     AssertCurrentThreadInMonitor();
   639     return !mTimeout.IsNull();
   640   }
   642   // Returns true if we're not playing and the decode thread has filled its
   643   // decode buffers and is waiting. We can shut the decode thread down in this
   644   // case as it may not be needed again.
   645   bool IsPausedAndDecoderWaiting();
   647   // The decoder object that created this state machine. The state machine
   648   // holds a strong reference to the decoder to ensure that the decoder stays
   649   // alive once media element has started the decoder shutdown process, and has
   650   // dropped its reference to the decoder. This enables the state machine to
   651   // keep using the decoder's monitor until the state machine has finished
   652   // shutting down, without fear of the monitor being destroyed. After
   653   // shutting down, the state machine will then release this reference,
   654   // causing the decoder to be destroyed. This is accessed on the decode,
   655   // state machine, audio and main threads.
   656   nsRefPtr<MediaDecoder> mDecoder;
   658   // The decoder monitor must be obtained before modifying this state.
   659   // NotifyAll on the monitor must be called when the state is changed so
   660   // that interested threads can wake up and alter behaviour if appropriate
   661   // Accessed on state machine, audio, main, and AV thread.
   662   State mState;
   664   // Thread for pushing audio onto the audio hardware.
   665   // The "audio push thread".
   666   nsCOMPtr<nsIThread> mAudioThread;
   668   // The task queue in which we run decode tasks. This is referred to as
   669   // the "decode thread", though in practise tasks can run on a different
   670   // thread every time they're called.
   671   RefPtr<MediaTaskQueue> mDecodeTaskQueue;
   673   RefPtr<SharedThreadPool> mStateMachineThreadPool;
   675   // Timer to run the state machine cycles. Used by
   676   // ScheduleStateMachine(). Access protected by decoder monitor.
   677   nsCOMPtr<nsITimer> mTimer;
   679   // Timestamp at which the next state machine cycle will run.
   680   // Access protected by decoder monitor.
   681   TimeStamp mTimeout;
   683   // Used to check if there are state machine cycles are running in sequence.
   684   DebugOnly<bool> mInRunningStateMachine;
   686   // The time that playback started from the system clock. This is used for
   687   // timing the presentation of video frames when there's no audio.
   688   // Accessed only via the state machine thread.
   689   TimeStamp mPlayStartTime;
   691   // When we start writing decoded data to a new DecodedDataStream, or we
   692   // restart writing due to PlaybackStarted(), we record where we are in the
   693   // MediaStream and what that corresponds to in the media.
   694   StreamTime mSyncPointInMediaStream;
   695   int64_t mSyncPointInDecodedStream; // microseconds
   697   // When the playbackRate changes, and there is no audio clock, it is necessary
   698   // to reset the mPlayStartTime. This is done next time the clock is queried,
   699   // when this member is true. Access protected by decoder monitor.
   700   bool mResetPlayStartTime;
   702   // The amount of time we've spent playing already the media. The current
   703   // playback position is therefore |Now() - mPlayStartTime +
   704   // mPlayDuration|, which must be adjusted by mStartTime if used with media
   705   // timestamps.  Accessed only via the state machine thread.
   706   int64_t mPlayDuration;
   708   // Time that buffering started. Used for buffering timeout and only
   709   // accessed on the state machine thread. This is null while we're not
   710   // buffering.
   711   TimeStamp mBufferingStart;
   713   // Start time of the media, in microseconds. This is the presentation
   714   // time of the first frame decoded from the media, and is used to calculate
   715   // duration and as a bounds for seeking. Accessed on state machine, decode,
   716   // and main threads. Access controlled by decoder monitor.
   717   int64_t mStartTime;
   719   // Time of the last frame in the media, in microseconds. This is the
   720   // end time of the last frame in the media. Accessed on state
   721   // machine, decode, and main threads. Access controlled by decoder monitor.
   722   int64_t mEndTime;
   724   // Position to seek to in microseconds when the seek state transition occurs.
   725   // The decoder monitor lock must be obtained before reading or writing
   726   // this value. Accessed on main and decode thread.
   727   SeekTarget mSeekTarget;
   729   // Media Fragment end time in microseconds. Access controlled by decoder monitor.
   730   int64_t mFragmentEndTime;
   732   // The audio stream resource. Used on the state machine, and audio threads.
   733   // This is created and destroyed on the audio thread, while holding the
   734   // decoder monitor, so if this is used off the audio thread, you must
   735   // first acquire the decoder monitor and check that it is non-null.
   736   RefPtr<AudioStream> mAudioStream;
   738   // The reader, don't call its methods with the decoder monitor held.
   739   // This is created in the play state machine's constructor, and destroyed
   740   // in the play state machine's destructor.
   741   nsAutoPtr<MediaDecoderReader> mReader;
   743   // Accessed only on the state machine thread.
   744   // Not an nsRevocableEventPtr since we must Revoke() it well before
   745   // this object is destroyed, anyway.
   746   // Protected by decoder monitor except during the SHUTDOWN state after the
   747   // decoder thread has been stopped.
   748   nsRevocableEventPtr<WakeDecoderRunnable> mPendingWakeDecoder;
   750   // The time of the current frame in microseconds. This is referenced from
   751   // 0 which is the initial playback position. Set by the state machine
   752   // thread, and read-only from the main thread to get the current
   753   // time value. Synchronised via decoder monitor.
   754   int64_t mCurrentFrameTime;
   756   // The presentation time of the first audio frame that was played in
   757   // microseconds. We can add this to the audio stream position to determine
   758   // the current audio time. Accessed on audio and state machine thread.
   759   // Synchronized by decoder monitor.
   760   int64_t mAudioStartTime;
   762   // The end time of the last audio frame that's been pushed onto the audio
   763   // hardware in microseconds. This will approximately be the end time of the
   764   // audio stream, unless another frame is pushed to the hardware.
   765   int64_t mAudioEndTime;
   767   // The presentation end time of the last video frame which has been displayed
   768   // in microseconds. Accessed from the state machine thread.
   769   int64_t mVideoFrameEndTime;
   771   // Volume of playback. 0.0 = muted. 1.0 = full volume. Read/Written
   772   // from the state machine and main threads. Synchronised via decoder
   773   // monitor.
   774   double mVolume;
   776   // Playback rate. 1.0 : normal speed, 0.5 : two times slower. Synchronized via
   777   // decoder monitor.
   778   double mPlaybackRate;
   780   // Pitch preservation for the playback rate. Synchronized via decoder monitor.
   781   bool mPreservesPitch;
   783   // Position at which the last playback rate change occured, used to compute
   784   // the actual position in the stream when the playback rate changes and there
   785   // is no audio to be sync-ed to. Synchronized via decoder monitor.
   786   int64_t mBasePosition;
   788   // Time at which we started decoding. Synchronised via decoder monitor.
   789   TimeStamp mDecodeStartTime;
   791   // The maximum number of second we spend buffering when we are short on
   792   // unbuffered data.
   793   uint32_t mBufferingWait;
   794   int64_t  mLowDataThresholdUsecs;
   796   // If we've got more than mAmpleVideoFrames decoded video frames waiting in
   797   // the video queue, we will not decode any more video frames until some have
   798   // been consumed by the play state machine thread.
   799   uint32_t mAmpleVideoFrames;
   801   // Low audio threshold. If we've decoded less than this much audio we
   802   // consider our audio decode "behind", and we may skip video decoding
   803   // in order to allow our audio decoding to catch up. We favour audio
   804   // decoding over video. We increase this threshold if we're slow to
   805   // decode video frames, in order to reduce the chance of audio underruns.
   806   // Note that we don't ever reset this threshold, it only ever grows as
   807   // we detect that the decode can't keep up with rendering.
   808   int64_t mLowAudioThresholdUsecs;
   810   // Our "ample" audio threshold. Once we've this much audio decoded, we
   811   // pause decoding. If we increase mLowAudioThresholdUsecs, we'll also
   812   // increase this too appropriately (we don't want mLowAudioThresholdUsecs
   813   // to be greater than ampleAudioThreshold, else we'd stop decoding!).
   814   // Note that we don't ever reset this threshold, it only ever grows as
   815   // we detect that the decode can't keep up with rendering.
   816   int64_t mAmpleAudioThresholdUsecs;
   818   // At the start of decoding we want to "preroll" the decode until we've
   819   // got a few frames decoded before we consider whether decode is falling
   820   // behind. Otherwise our "we're falling behind" logic will trigger
   821   // unneccessarily if we start playing as soon as the first sample is
   822   // decoded. These two fields store how many video frames and audio
   823   // samples we must consume before are considered to be finished prerolling.
   824   uint32_t mAudioPrerollUsecs;
   825   uint32_t mVideoPrerollFrames;
   827   // When we start decoding (either for the first time, or after a pause)
   828   // we may be low on decoded data. We don't want our "low data" logic to
   829   // kick in and decide that we're low on decoded data because the download
   830   // can't keep up with the decode, and cause us to pause playback. So we
   831   // have a "preroll" stage, where we ignore the results of our "low data"
   832   // logic during the first few frames of our decode. This occurs during
   833   // playback. The flags below are true when the corresponding stream is
   834   // being "prerolled".
   835   bool mIsAudioPrerolling;
   836   bool mIsVideoPrerolling;
   838   // True when we have an audio stream that we're decoding, and we have not
   839   // yet decoded to end of stream.
   840   bool mIsAudioDecoding;
   842   // True when we have a video stream that we're decoding, and we have not
   843   // yet decoded to end of stream.
   844   bool mIsVideoDecoding;
   846   // True when we have dispatched a task to the decode task queue to run
   847   // the audio decode.
   848   bool mDispatchedAudioDecodeTask;
   850   // True when we have dispatched a task to the decode task queue to run
   851   // the video decode.
   852   bool mDispatchedVideoDecodeTask;
   854   // True when the reader is initialized, but has been ordered "idle" by the
   855   // state machine. This happens when the MediaQueue's of decoded data are
   856   // "full" and playback is paused. The reader may choose to use the idle
   857   // notification to enter a low power state.
   858   bool mIsReaderIdle;
   860   // If the video decode is falling behind the audio, we'll start dropping the
   861   // inter-frames up until the next keyframe which is at or before the current
   862   // playback position. skipToNextKeyframe is true if we're currently
   863   // skipping up to the next keyframe.
   864   bool mSkipToNextKeyFrame;
   866   // True if we shouldn't play our audio (but still write it to any capturing
   867   // streams). When this is true, mStopAudioThread is always true and
   868   // the audio thread will never start again after it has stopped.
   869   bool mAudioCaptured;
   871   // True if the media resource can be seeked on a transport level. Accessed
   872   // from the state machine and main threads. Synchronised via decoder monitor.
   873   bool mTransportSeekable;
   875   // True if the media can be seeked. Accessed from the state machine and main
   876   // threads. Synchronised via decoder monitor.
   877   bool mMediaSeekable;
   879   // True if an event to notify about a change in the playback
   880   // position has been queued, but not yet run. It is set to false when
   881   // the event is run. This allows coalescing of these events as they can be
   882   // produced many times per second. Synchronised via decoder monitor.
   883   // Accessed on main and state machine threads.
   884   bool mPositionChangeQueued;
   886   // True if the audio playback thread has finished. It is finished
   887   // when either all the audio frames have completed playing, or we've moved
   888   // into shutdown state, and the threads are to be
   889   // destroyed. Written by the audio playback thread and read and written by
   890   // the state machine thread. Synchronised via decoder monitor.
   891   // When data is being sent to a MediaStream, this is true when all data has
   892   // been written to the MediaStream.
   893   bool mAudioCompleted;
   895   // True if mDuration has a value obtained from an HTTP header, or from
   896   // the media index/metadata. Accessed on the state machine thread.
   897   bool mGotDurationFromMetaData;
   899   // True if we've dispatched an event to the decode task queue to call
   900   // DecodeThreadRun(). We use this flag to prevent us from dispatching
   901   // unneccessary runnables, since the decode thread runs in a loop.
   902   bool mDispatchedEventToDecode;
   904   // False while audio thread should be running. Accessed state machine
   905   // and audio threads. Syncrhonised by decoder monitor.
   906   bool mStopAudioThread;
   908   // If this is true while we're in buffering mode, we can exit early,
   909   // as it's likely we may be able to playback. This happens when we enter
   910   // buffering mode soon after the decode starts, because the decode-ahead
   911   // ran fast enough to exhaust all data while the download is starting up.
   912   // Synchronised via decoder monitor.
   913   bool mQuickBuffering;
   915   // True if we should not decode/preroll unnecessary samples, unless we're
   916   // played. "Prerolling" in this context refers to when we decode and
   917   // buffer decoded samples in advance of when they're needed for playback.
   918   // This flag is set for preload=metadata media, and means we won't
   919   // decode more than the first video frame and first block of audio samples
   920   // for that media when we startup, or after a seek. When Play() is called,
   921   // we reset this flag, as we assume the user is playing the media, so
   922   // prerolling is appropriate then. This flag is used to reduce the overhead
   923   // of prerolling samples for media elements that may not play, both
   924   // memory and CPU overhead.
   925   bool mMinimizePreroll;
   927   // True if the decode thread has gone filled its buffers and is now
   928   // waiting to be awakened before it continues decoding. Synchronized
   929   // by the decoder monitor.
   930   bool mDecodeThreadWaiting;
   932   // True is we are decoding a realtime stream, like a camera stream
   933   bool mRealTime;
   935   // Stores presentation info required for playback. The decoder monitor
   936   // must be held when accessing this.
   937   MediaInfo mInfo;
   939   mozilla::MediaMetadataManager mMetadataManager;
   941   MediaDecoderOwner::NextFrameStatus mLastFrameStatus;
   943   // The id of timer tasks, used to ignore tasks that are scheduled previously.
   944   int mTimerId;
   945 };
   947 } // namespace mozilla;
   948 #endif

mercurial