LCOV - code coverage report
Current view: top level - dom/media - MediaDecoder.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 78 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #if !defined(MediaDecoder_h_)
       8             : #define MediaDecoder_h_
       9             : 
      10             : #include "AbstractMediaDecoder.h"
      11             : #include "DecoderDoctorDiagnostics.h"
      12             : #include "MediaDecoderOwner.h"
      13             : #include "MediaEventSource.h"
      14             : #include "MediaMetadataManager.h"
      15             : #include "MediaResource.h"
      16             : #include "MediaStatistics.h"
      17             : #include "MediaStreamGraph.h"
      18             : #include "SeekTarget.h"
      19             : #include "TimeUnits.h"
      20             : #include "mozilla/Atomics.h"
      21             : #include "mozilla/CDMProxy.h"
      22             : #include "mozilla/MozPromise.h"
      23             : #include "mozilla/ReentrantMonitor.h"
      24             : #include "mozilla/StateMirroring.h"
      25             : #include "mozilla/StateWatching.h"
      26             : #include "mozilla/dom/AudioChannelBinding.h"
      27             : #include "necko-config.h"
      28             : #include "nsAutoPtr.h"
      29             : #include "nsCOMPtr.h"
      30             : #include "nsIObserver.h"
      31             : #include "nsISupports.h"
      32             : #include "nsITimer.h"
      33             : 
      34             : class nsIPrincipal;
      35             : 
      36             : namespace mozilla {
      37             : 
      38             : namespace dom {
      39             : class HTMLMediaElement;
      40             : }
      41             : 
      42             : class AbstractThread;
      43             : class VideoFrameContainer;
      44             : class MediaDecoderReader;
      45             : class MediaDecoderStateMachine;
      46             : 
      47             : enum class MediaEventType : int8_t;
      48             : enum class Visibility : uint8_t;
      49             : 
      50             : // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
      51             : // GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
      52             : #ifdef GetCurrentTime
      53             : #undef GetCurrentTime
      54             : #endif
      55             : 
      56           0 : struct MOZ_STACK_CLASS MediaDecoderInit
      57             : {
      58             :   MediaDecoderOwner* const mOwner;
      59             :   const dom::AudioChannel mAudioChannel;
      60             :   const double mVolume;
      61             :   const bool mPreservesPitch;
      62             :   const double mPlaybackRate;
      63             :   const bool mMinimizePreroll;
      64             :   const bool mHasSuspendTaint;
      65             :   const bool mLooping;
      66             :   const MediaContainerType mContainerType;
      67             : 
      68           0 :   MediaDecoderInit(MediaDecoderOwner* aOwner,
      69             :                    dom::AudioChannel aAudioChannel,
      70             :                    double aVolume,
      71             :                    bool aPreservesPitch,
      72             :                    double aPlaybackRate,
      73             :                    bool aMinimizePreroll,
      74             :                    bool aHasSuspendTaint,
      75             :                    bool aLooping,
      76             :                    const MediaContainerType& aContainerType)
      77           0 :     : mOwner(aOwner)
      78             :     , mAudioChannel(aAudioChannel)
      79             :     , mVolume(aVolume)
      80             :     , mPreservesPitch(aPreservesPitch)
      81             :     , mPlaybackRate(aPlaybackRate)
      82             :     , mMinimizePreroll(aMinimizePreroll)
      83             :     , mHasSuspendTaint(aHasSuspendTaint)
      84             :     , mLooping(aLooping)
      85           0 :     , mContainerType(aContainerType)
      86             :   {
      87           0 :   }
      88             : };
      89             : 
      90             : class MediaDecoder : public AbstractMediaDecoder
      91             : {
      92             : public:
      93             :   typedef MozPromise<bool /* aIgnored */, bool /* aIgnored */,
      94             :                      /* IsExclusive = */ true>
      95             :     SeekPromise;
      96             : 
      97             :   NS_DECL_THREADSAFE_ISUPPORTS
      98             : 
      99             :   // Enumeration for the valid play states (see mPlayState)
     100             :   enum PlayState
     101             :   {
     102             :     PLAY_STATE_START,
     103             :     PLAY_STATE_LOADING,
     104             :     PLAY_STATE_PAUSED,
     105             :     PLAY_STATE_PLAYING,
     106             :     PLAY_STATE_ENDED,
     107             :     PLAY_STATE_SHUTDOWN
     108             :   };
     109             : 
     110             :   // Must be called exactly once, on the main thread, during startup.
     111             :   static void InitStatics();
     112             : 
     113             :   explicit MediaDecoder(MediaDecoderInit& aInit);
     114             : 
     115             :   // Returns the container content type of the resource.
     116             :   // Safe to call from any thread.
     117           0 :   const MediaContainerType& ContainerType() const { return mContainerType; }
     118             : 
     119             :   // Create a new state machine to run this decoder.
     120             :   // Subclasses must implement this.
     121             :   virtual MediaDecoderStateMachine* CreateStateMachine() = 0;
     122             : 
     123             :   // Cleanup internal data structures. Must be called on the main
     124             :   // thread by the owning object before that object disposes of this object.
     125             :   virtual void Shutdown();
     126             : 
     127             :   // Notified by the shutdown manager that XPCOM shutdown has begun.
     128             :   // The decoder should notify its owner to drop the reference to the decoder
     129             :   // to prevent further calls into the decoder.
     130             :   void NotifyXPCOMShutdown();
     131             : 
     132             :   // Called if the media file encounters a network error.
     133             :   void NetworkError();
     134             : 
     135             :   // Get the current MediaResource being used.
     136             :   // Note: The MediaResource is refcounted, but it outlives the MediaDecoder,
     137             :   // so it's OK to use the reference returned by this function without
     138             :   // refcounting, *unless* you need to store and use the reference after the
     139             :   // MediaDecoder has been destroyed. You might need to do this if you're
     140             :   // wrapping the MediaResource in some kind of byte stream interface to be
     141             :   // passed to a platform decoder.
     142           0 :   MediaResource* GetResource() const { return mResource; }
     143             : 
     144             :   // Return the principal of the current URI being played or downloaded.
     145             :   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
     146             : 
     147             :   // Return the time position in the video stream being
     148             :   // played measured in seconds.
     149             :   virtual double GetCurrentTime();
     150             : 
     151             :   // Seek to the time position in (seconds) from the start of the video.
     152             :   // If aDoFastSeek is true, we'll seek to the sync point/keyframe preceeding
     153             :   // the seek target.
     154             :   virtual nsresult Seek(double aTime, SeekTarget::Type aSeekType);
     155             : 
     156             :   // Initialize state machine and schedule it.
     157             :   nsresult InitializeStateMachine();
     158             : 
     159             :   // Start playback of a video. 'Load' must have previously been
     160             :   // called.
     161             :   virtual nsresult Play();
     162             : 
     163             :   // Notify activity of the decoder owner is changed.
     164             :   virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible,
     165             :                                           Visibility aElementVisibility,
     166             :                                           bool aIsElementInTree);
     167             : 
     168             :   // Pause video playback.
     169             :   virtual void Pause();
     170             :   // Adjust the speed of the playback, optionally with pitch correction,
     171             :   void SetVolume(double aVolume);
     172             : 
     173             :   void SetPlaybackRate(double aPlaybackRate);
     174             :   void SetPreservesPitch(bool aPreservesPitch);
     175             :   void SetLooping(bool aLooping);
     176             : 
     177           0 :   bool GetMinimizePreroll() const { return mMinimizePreroll; }
     178             : 
     179             :   // All MediaStream-related data is protected by mReentrantMonitor.
     180             :   // We have at most one DecodedStreamData per MediaDecoder. Its stream
     181             :   // is used as the input for each ProcessedMediaStream created by calls to
     182             :   // captureStream(UntilEnded). Seeking creates a new source stream, as does
     183             :   // replaying after the input as ended. In the latter case, the new source is
     184             :   // not connected to streams created by captureStreamUntilEnded.
     185             : 
     186             :   // Add an output stream. All decoder output will be sent to the stream.
     187             :   // The stream is initially blocked. The decoder is responsible for unblocking
     188             :   // it while it is playing back.
     189             :   virtual void AddOutputStream(ProcessedMediaStream* aStream,
     190             :                                bool aFinishWhenEnded);
     191             :   // Remove an output stream added with AddOutputStream.
     192             :   virtual void RemoveOutputStream(MediaStream* aStream);
     193             : 
     194             :   // Return the duration of the video in seconds.
     195             :   virtual double GetDuration();
     196             : 
     197             :   // Return true if the stream is infinite (see SetInfinite).
     198             :   bool IsInfinite() const;
     199             : 
     200             :   // Called as data arrives on the stream and is read into the cache.  Called
     201             :   // on the main thread only.
     202             :   void NotifyDataArrived();
     203             : 
     204             :   // Return true if we are currently seeking in the media resource.
     205             :   // Call on the main thread only.
     206             :   bool IsSeeking() const;
     207             : 
     208             :   // Return true if the decoder has reached the end of playback.
     209             :   bool IsEnded() const;
     210             : 
     211             :   // True if we are playing a MediaSource object.
     212           0 :   virtual bool IsMSE() const { return false; }
     213             : 
     214             :   // Return true if the MediaDecoderOwner's error attribute is not null.
     215             :   // Must be called before Shutdown().
     216             :   bool OwnerHasError() const;
     217             : 
     218             :   already_AddRefed<GMPCrashHelper> GetCrashHelper() override;
     219             : 
     220             : public:
     221             :   // Returns true if this media supports random seeking. False for example with
     222             :   // chained ogg files.
     223             :   bool IsMediaSeekable();
     224             :   // Returns true if seeking is supported on a transport level (e.g. the server
     225             :   // supports range requests, we are playing a file, etc.).
     226             :   bool IsTransportSeekable();
     227             : 
     228             :   // Return the time ranges that can be seeked into.
     229             :   virtual media::TimeIntervals GetSeekable();
     230             : 
     231             :   // Set the end time of the media resource. When playback reaches
     232             :   // this point the media pauses. aTime is in seconds.
     233             :   virtual void SetFragmentEndTime(double aTime);
     234             : 
     235             :   // Invalidate the frame.
     236             :   void Invalidate();
     237             :   void InvalidateWithFlags(uint32_t aFlags);
     238             : 
     239             :   // Suspend any media downloads that are in progress. Called by the
     240             :   // media element when it is sent to the bfcache, or when we need
     241             :   // to throttle the download. Call on the main thread only. This can
     242             :   // be called multiple times, there's an internal "suspend count".
     243             :   virtual void Suspend();
     244             : 
     245             :   // Resume any media downloads that have been suspended. Called by the
     246             :   // media element when it is restored from the bfcache, or when we need
     247             :   // to stop throttling the download. Call on the main thread only.
     248             :   // The download will only actually resume once as many Resume calls
     249             :   // have been made as Suspend calls.
     250             :   virtual void Resume();
     251             : 
     252             :   // Moves any existing channel loads into or out of background. Background
     253             :   // loads don't block the load event. This is called when we stop or restart
     254             :   // delaying the load event. This also determines whether any new loads
     255             :   // initiated (for example to seek) will be in the background.  This calls
     256             :   // SetLoadInBackground() on mResource.
     257             :   void SetLoadInBackground(bool aLoadInBackground);
     258             : 
     259             :   MediaDecoderStateMachine* GetStateMachine() const;
     260             :   void SetStateMachine(MediaDecoderStateMachine* aStateMachine);
     261             : 
     262             :   // Constructs the time ranges representing what segments of the media
     263             :   // are buffered and playable.
     264             :   virtual media::TimeIntervals GetBuffered();
     265             : 
     266             :   // Returns the size, in bytes, of the heap memory used by the currently
     267             :   // queued decoded video and audio data.
     268             :   size_t SizeOfVideoQueue();
     269             :   size_t SizeOfAudioQueue();
     270             : 
     271             :   // Helper struct for accumulating resource sizes that need to be measured
     272             :   // asynchronously. Once all references are dropped the callback will be
     273             :   // invoked.
     274             :   struct ResourceSizes
     275             :   {
     276             :     typedef MozPromise<size_t, size_t, true> SizeOfPromise;
     277           0 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResourceSizes)
     278           0 :     explicit ResourceSizes(MallocSizeOf aMallocSizeOf)
     279           0 :       : mMallocSizeOf(aMallocSizeOf)
     280             :       , mByteSize(0)
     281           0 :       , mCallback()
     282             :     {
     283           0 :     }
     284             : 
     285             :     mozilla::MallocSizeOf mMallocSizeOf;
     286             :     mozilla::Atomic<size_t> mByteSize;
     287             : 
     288           0 :     RefPtr<SizeOfPromise> Promise()
     289             :     {
     290           0 :       return mCallback.Ensure(__func__);
     291             :     }
     292             : 
     293             : private:
     294           0 :     ~ResourceSizes()
     295           0 :     {
     296           0 :       mCallback.ResolveIfExists(mByteSize, __func__);
     297           0 :     }
     298             : 
     299             :     MozPromiseHolder<SizeOfPromise> mCallback;
     300             :   };
     301             : 
     302             :   virtual void AddSizeOfResources(ResourceSizes* aSizes);
     303             : 
     304           0 :   VideoFrameContainer* GetVideoFrameContainer() final override
     305             :   {
     306           0 :     return mVideoFrameContainer;
     307             :   }
     308             :   layers::ImageContainer* GetImageContainer() override;
     309             : 
     310             :   // Fire timeupdate events if needed according to the time constraints
     311             :   // outlined in the specification.
     312             :   void FireTimeUpdate();
     313             : 
     314             :   // Something has changed that could affect the computed playback rate,
     315             :   // so recompute it. The monitor must be held.
     316             :   virtual void UpdatePlaybackRate();
     317             : 
     318             :   // The actual playback rate computation. The monitor must be held.
     319             :   void ComputePlaybackRate();
     320             : 
     321             :   // Returns true if we can play the entire media through without stopping
     322             :   // to buffer, given the current download and playback rates.
     323             :   virtual bool CanPlayThrough();
     324             : 
     325           0 :   dom::AudioChannel GetAudioChannel() { return mAudioChannel; }
     326             : 
     327             :   // Called from HTMLMediaElement when owner document activity changes
     328             :   virtual void SetElementVisibility(bool aIsDocumentVisible,
     329             :                                     Visibility aElementVisibility,
     330             :                                     bool aIsElementInTree);
     331             : 
     332             :   // Force override the visible state to hidden.
     333             :   // Called from HTMLMediaElement when testing of video decode suspend from mochitests.
     334             :   void SetForcedHidden(bool aForcedHidden);
     335             : 
     336             :   // Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
     337             :   void SetSuspendTaint(bool aTaint);
     338             : 
     339             :   // Returns true if the decoder can't participate in suspend-video-decoder.
     340             :   bool HasSuspendTaint() const;
     341             : 
     342             :   void UpdateVideoDecodeMode();
     343             : 
     344             :   /******
     345             :    * The following methods must only be called on the main
     346             :    * thread.
     347             :    ******/
     348             : 
     349             :   // Change to a new play state. This updates the mState variable and
     350             :   // notifies any thread blocking on this object's monitor of the
     351             :   // change. Call on the main thread only.
     352             :   virtual void ChangeState(PlayState aState);
     353             : 
     354             :   // Called when the video has completed playing.
     355             :   // Call on the main thread only.
     356             :   void PlaybackEnded();
     357             : 
     358             :   void OnSeekRejected();
     359             :   void OnSeekResolved();
     360             : 
     361           0 :   void SeekingChanged()
     362             :   {
     363             :     // Stop updating the bytes downloaded for progress notifications when
     364             :     // seeking to prevent wild changes to the progress notification.
     365           0 :     MOZ_ASSERT(NS_IsMainThread());
     366           0 :     mIgnoreProgressData = mLogicallySeeking;
     367           0 :   }
     368             : 
     369             :   // Seeking has started. Inform the element on the main thread.
     370             :   void SeekingStarted();
     371             : 
     372             :   void UpdateLogicalPositionInternal();
     373           0 :   void UpdateLogicalPosition()
     374             :   {
     375           0 :     MOZ_ASSERT(NS_IsMainThread());
     376           0 :     MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
     377             :     // Per spec, offical position remains stable during pause and seek.
     378           0 :     if (mPlayState == PLAY_STATE_PAUSED || IsSeeking()) {
     379           0 :       return;
     380             :     }
     381           0 :     UpdateLogicalPositionInternal();
     382             :   }
     383             : 
     384             :   // Find the end of the cached data starting at the current decoder
     385             :   // position.
     386             :   int64_t GetDownloadPosition();
     387             : 
     388             :   // Notifies the element that decoding has failed.
     389             :   void DecodeError(const MediaResult& aError);
     390             : 
     391             :   // Indicate whether the media is same-origin with the element.
     392             :   void UpdateSameOriginStatus(bool aSameOrigin);
     393             : 
     394             :   MediaDecoderOwner* GetOwner() const override;
     395             : 
     396           0 :   AbstractThread* AbstractMainThread() const final override
     397             :   {
     398           0 :     return mAbstractMainThread;
     399             :   }
     400             : 
     401             :   typedef MozPromise<RefPtr<CDMProxy>, bool /* aIgnored */,
     402             :                      /* IsExclusive = */ true>
     403             :     CDMProxyPromise;
     404             : 
     405             :   // Resolved when a CDMProxy is available and the capabilities are known or
     406             :   // rejected when this decoder is about to shut down.
     407             :   RefPtr<CDMProxyPromise> RequestCDMProxy() const;
     408             : 
     409             :   void SetCDMProxy(CDMProxy* aProxy);
     410             : 
     411             :   void EnsureTelemetryReported();
     412             : 
     413             :   static bool IsOggEnabled();
     414             :   static bool IsOpusEnabled();
     415             :   static bool IsWaveEnabled();
     416             :   static bool IsWebMEnabled();
     417             : 
     418             : #ifdef MOZ_ANDROID_OMX
     419             :   static bool IsAndroidMediaPluginEnabled();
     420             : #endif
     421             : 
     422             : #ifdef MOZ_WMF
     423             :   static bool IsWMFEnabled();
     424             : #endif
     425             : 
     426             :   // Return statistics. This is used for progress events and other things.
     427             :   // This can be called from any thread. It's only a snapshot of the
     428             :   // current state, since other threads might be changing the state
     429             :   // at any time.
     430             :   MediaStatistics GetStatistics();
     431             : 
     432             :   // Return the frame decode/paint related statistics.
     433           0 :   FrameStatistics& GetFrameStatistics() { return *mFrameStats; }
     434             : 
     435             :   // Increments the parsed and decoded frame counters by the passed in counts.
     436             :   // Can be called on any thread.
     437           0 :   virtual void NotifyDecodedFrames(const FrameStatisticsData& aStats) override
     438             :   {
     439           0 :     GetFrameStatistics().NotifyDecodedFrames(aStats);
     440           0 :   }
     441             : 
     442           0 :   void UpdateReadyState()
     443             :   {
     444           0 :     MOZ_ASSERT(NS_IsMainThread());
     445           0 :     MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
     446           0 :     GetOwner()->UpdateReadyState();
     447           0 :   }
     448             : 
     449           0 :   virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus()
     450             :   {
     451           0 :     return mNextFrameStatus;
     452             :   }
     453             :   virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus();
     454             : 
     455             :   // Returns a string describing the state of the media player internal
     456             :   // data. Used for debugging purposes.
     457           0 :   virtual void GetMozDebugReaderData(nsACString& aString) { }
     458             : 
     459             :   virtual void DumpDebugInfo();
     460             : 
     461             :   using DebugInfoPromise = MozPromise<nsCString, bool, true>;
     462             :   RefPtr<DebugInfoPromise> RequestDebugInfo();
     463             : 
     464             : protected:
     465             :   virtual ~MediaDecoder();
     466             : 
     467             :   // Called when the first audio and/or video from the media file has been loaded
     468             :   // by the state machine. Call on the main thread only.
     469             :   virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
     470             :                                 MediaDecoderEventVisibility aEventVisibility);
     471             : 
     472             :   void SetStateMachineParameters();
     473             : 
     474             :   bool IsShutdown() const;
     475             : 
     476             :   // Called by the state machine to notify the decoder that the duration
     477             :   // has changed.
     478             :   void DurationChanged();
     479             : 
     480             :   // State-watching manager.
     481             :   WatchManager<MediaDecoder> mWatchManager;
     482             : 
     483           0 :   double ExplicitDuration() { return mExplicitDuration.Ref().ref(); }
     484             : 
     485           0 :   void SetExplicitDuration(double aValue)
     486             :   {
     487           0 :     MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
     488           0 :     mExplicitDuration.Set(Some(aValue));
     489             : 
     490             :     // We Invoke DurationChanged explicitly, rather than using a watcher, so
     491             :     // that it takes effect immediately, rather than at the end of the current task.
     492           0 :     DurationChanged();
     493           0 :   }
     494             : 
     495             :   /******
     496             :    * The following members should be accessed with the decoder lock held.
     497             :    ******/
     498             : 
     499             :   // The logical playback position of the media resource in units of
     500             :   // seconds. This corresponds to the "official position" in HTML5. Note that
     501             :   // we need to store this as a double, rather than an int64_t (like
     502             :   // mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo|
     503             :   // returns true without being affected by rounding errors.
     504             :   double mLogicalPosition;
     505             : 
     506             :   // The current playback position of the underlying playback infrastructure.
     507             :   // This corresponds to the "current position" in HTML5.
     508             :   // We allow omx subclasses to substitute an alternative current position for
     509             :   // usage with the audio offload player.
     510           0 :   virtual media::TimeUnit CurrentPosition()
     511             :   {
     512           0 :     return mCurrentPosition.Ref();
     513             :   }
     514             : 
     515             :   // Official duration of the media resource as observed by script.
     516             :   double mDuration;
     517             : 
     518             :   /******
     519             :    * The following member variables can be accessed from any thread.
     520             :    ******/
     521             : 
     522             :   // Media data resource.
     523             :   RefPtr<MediaResource> mResource;
     524             : 
     525             :   RefPtr<MediaDecoderReader> mReader;
     526             : 
     527             :   // Amount of buffered data ahead of current time required to consider that
     528             :   // the next frame is available.
     529             :   // An arbitrary value of 250ms is used.
     530             :   static constexpr auto DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED =
     531             :     media::TimeUnit::FromMicroseconds(250000);
     532             : 
     533             : private:
     534             :   nsCString GetDebugInfo();
     535             : 
     536             :   // Called when the metadata from the media file has been loaded by the
     537             :   // state machine. Call on the main thread only.
     538             :   void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
     539             :                       UniquePtr<MetadataTags> aTags,
     540             :                       MediaDecoderEventVisibility aEventVisibility);
     541             : 
     542             :   // Called when the owner's activity changed.
     543             :   void NotifyCompositor();
     544             : 
     545             :   MediaEventSource<RefPtr<layers::KnowsCompositor>>*
     546           0 :   CompositorUpdatedEvent() override { return &mCompositorUpdatedEvent; }
     547             : 
     548             :   void OnPlaybackEvent(MediaEventType aEvent);
     549             :   void OnPlaybackErrorEvent(const MediaResult& aError);
     550             : 
     551             :   void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent);
     552             : 
     553           0 :   void OnMediaNotSeekable()
     554             :   {
     555           0 :     mMediaSeekable = false;
     556           0 :   }
     557             : 
     558             :   void FinishShutdown();
     559             : 
     560             :   void ConnectMirrors(MediaDecoderStateMachine* aObject);
     561             :   void DisconnectMirrors();
     562             : 
     563             :   MediaEventProducer<RefPtr<layers::KnowsCompositor>> mCompositorUpdatedEvent;
     564             : 
     565             :   // The state machine object for handling the decoding. It is safe to
     566             :   // call methods of this object from other threads. Its internal data
     567             :   // is synchronised on a monitor. The lifetime of this object is
     568             :   // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
     569             :   // is safe to access it during this period.
     570             :   //
     571             :   // Explicitly prievate to force access via accessors.
     572             :   RefPtr<MediaDecoderStateMachine> mDecoderStateMachine;
     573             : 
     574             :   MozPromiseHolder<CDMProxyPromise> mCDMProxyPromiseHolder;
     575             :   RefPtr<CDMProxyPromise> mCDMProxyPromise;
     576             : 
     577             : protected:
     578             :   void NotifyDataArrivedInternal();
     579             :   void DiscardOngoingSeekIfExists();
     580             :   virtual void CallSeek(const SeekTarget& aTarget);
     581             : 
     582             :   // Called to recompute playback rate and notify 'progress' event.
     583             :   // Call on the main thread only.
     584             :   void DownloadProgressed();
     585             : 
     586             :   // A media stream is assumed to be infinite if the metadata doesn't
     587             :   // contain the duration, and range requests are not supported, and
     588             :   // no headers give a hint of a possible duration (Content-Length,
     589             :   // Content-Duration, and variants), and we cannot seek in the media
     590             :   // stream to determine the duration.
     591             :   //
     592             :   // When the media stream ends, we can know the duration, thus the stream is
     593             :   // no longer considered to be infinite.
     594             :   void SetInfinite(bool aInfinite);
     595             : 
     596             :   // Called by MediaResource when the "cache suspended" status changes.
     597             :   // If MediaResource::IsSuspendedByCache returns true, then the decoder
     598             :   // should stop buffering or otherwise waiting for download progress and
     599             :   // start consuming data, if possible, because the cache is full.
     600             :   void NotifySuspendedStatusChanged();
     601             : 
     602             :   // Called by MediaResource when the principal of the resource has
     603             :   // changed. Called on main thread only.
     604             :   void NotifyPrincipalChanged();
     605             : 
     606             :   // Called by the MediaResource to keep track of the number of bytes read
     607             :   // from the resource. Called on the main by an event runner dispatched
     608             :   // by the MediaResource read functions.
     609             :   void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset);
     610             : 
     611             :   // Called by nsChannelToPipeListener or MediaResource when the
     612             :   // download has ended. Called on the main thread only. aStatus is
     613             :   // the result from OnStopRequest.
     614             :   void NotifyDownloadEnded(nsresult aStatus);
     615             : 
     616             :   MozPromiseRequestHolder<SeekPromise> mSeekRequest;
     617             : 
     618             :   // True when seeking or otherwise moving the play position around in
     619             :   // such a manner that progress event data is inaccurate. This is set
     620             :   // during seek and duration operations to prevent the progress indicator
     621             :   // from jumping around. Read/Write on the main thread only.
     622             :   bool mIgnoreProgressData;
     623             : 
     624             :   // True if the stream is infinite (e.g. a webradio).
     625             :   bool mInfiniteStream;
     626             : 
     627             :   // Ensures our media stream has been pinned.
     628             :   void PinForSeek();
     629             : 
     630             :   // Ensures our media stream has been unpinned.
     631             :   void UnpinForSeek();
     632             : 
     633             :   const char* PlayStateStr();
     634             : 
     635             :   void OnMetadataUpdate(TimedMetadata&& aMetadata);
     636             : 
     637             :   bool ShouldThrottleDownload();
     638             : 
     639             :   // This should only ever be accessed from the main thread.
     640             :   // It is set in the constructor and cleared in Shutdown when the element goes
     641             :   // away. The decoder does not add a reference the element.
     642             :   MediaDecoderOwner* mOwner;
     643             : 
     644             :   // The AbstractThread from mOwner.
     645             :   const RefPtr<AbstractThread> mAbstractMainThread;
     646             : 
     647             :   // Counters related to decode and presentation of frames.
     648             :   const RefPtr<FrameStatistics> mFrameStats;
     649             : 
     650             :   RefPtr<VideoFrameContainer> mVideoFrameContainer;
     651             : 
     652             :   // Data needed to estimate playback data rate. The timeline used for
     653             :   // this estimate is "decode time" (where the "current time" is the
     654             :   // time of the last decoded video frame).
     655             :   MediaChannelStatistics mPlaybackStatistics;
     656             : 
     657             :   // True when our media stream has been pinned. We pin the stream
     658             :   // while seeking.
     659             :   bool mPinnedForSeek;
     660             : 
     661             :   // Be assigned from media element during the initialization and pass to
     662             :   // AudioStream Class.
     663             :   const dom::AudioChannel mAudioChannel;
     664             : 
     665             :   // True if the decoder has been directed to minimize its preroll before
     666             :   // playback starts. After the first time playback starts, we don't attempt
     667             :   // to minimize preroll, as we assume the user is likely to keep playing,
     668             :   // or play the media again.
     669             :   const bool mMinimizePreroll;
     670             : 
     671             :   // True if we've already fired metadataloaded.
     672             :   bool mFiredMetadataLoaded;
     673             : 
     674             :   // True if the media is seekable (i.e. supports random access).
     675             :   bool mMediaSeekable = true;
     676             : 
     677             :   // True if the media is only seekable within its buffered ranges
     678             :   // like WebMs with no cues.
     679             :   bool mMediaSeekableOnlyInBufferedRanges = false;
     680             : 
     681             :   // Stores media info, including info of audio tracks and video tracks, should
     682             :   // only be accessed from main thread.
     683             :   nsAutoPtr<MediaInfo> mInfo;
     684             : 
     685             :   // Tracks the visibility status of owner element's document.
     686             :   bool mIsDocumentVisible;
     687             : 
     688             :   // Tracks the visibility status of owner element.
     689             :   Visibility mElementVisibility;
     690             : 
     691             :   // Tracks the owner is in-tree or not.
     692             :   bool mIsElementInTree;
     693             : 
     694             :   // If true, forces the decoder to be considered hidden.
     695             :   bool mForcedHidden;
     696             : 
     697             :   // True if the decoder has a suspend taint - meaning suspend-video-decoder is
     698             :   // disabled.
     699             :   bool mHasSuspendTaint;
     700             : 
     701             :   // A listener to receive metadata updates from MDSM.
     702             :   MediaEventListener mTimedMetadataListener;
     703             : 
     704             :   MediaEventListener mMetadataLoadedListener;
     705             :   MediaEventListener mFirstFrameLoadedListener;
     706             : 
     707             :   MediaEventListener mOnPlaybackEvent;
     708             :   MediaEventListener mOnPlaybackErrorEvent;
     709             :   MediaEventListener mOnDecoderDoctorEvent;
     710             :   MediaEventListener mOnMediaNotSeekable;
     711             : 
     712             : protected:
     713             :   // PlaybackRate and pitch preservation status we should start at.
     714             :   double mPlaybackRate;
     715             : 
     716             :   // Buffered range, mirrored from the reader.
     717             :   Mirror<media::TimeIntervals> mBuffered;
     718             : 
     719             :   // NextFrameStatus, mirrored from the state machine.
     720             :   Mirror<MediaDecoderOwner::NextFrameStatus> mNextFrameStatus;
     721             : 
     722             :   // NB: Don't use mCurrentPosition directly, but rather CurrentPosition().
     723             :   Mirror<media::TimeUnit> mCurrentPosition;
     724             : 
     725             :   // Duration of the media resource according to the state machine.
     726             :   Mirror<media::NullableTimeUnit> mStateMachineDuration;
     727             : 
     728             :   // Current playback position in the stream. This is (approximately)
     729             :   // where we're up to playing back the stream. This is not adjusted
     730             :   // during decoder seek operations, but it's updated at the end when we
     731             :   // start playing back again.
     732             :   Mirror<int64_t> mPlaybackPosition;
     733             : 
     734             :   // Used to distinguish whether the audio is producing sound.
     735             :   Mirror<bool> mIsAudioDataAudible;
     736             : 
     737             :   // Volume of playback.  0.0 = muted. 1.0 = full volume.
     738             :   Canonical<double> mVolume;
     739             : 
     740             :   Canonical<bool> mPreservesPitch;
     741             : 
     742             :   Canonical<bool> mLooping;
     743             : 
     744             :   // Media duration set explicitly by JS. At present, this is only ever present
     745             :   // for MSE.
     746             :   Canonical<Maybe<double>> mExplicitDuration;
     747             : 
     748             :   // Set to one of the valid play states.
     749             :   // This can only be changed on the main thread while holding the decoder
     750             :   // monitor. Thus, it can be safely read while holding the decoder monitor
     751             :   // OR on the main thread.
     752             :   Canonical<PlayState> mPlayState;
     753             : 
     754             :   // This can only be changed on the main thread while holding the decoder
     755             :   // monitor. Thus, it can be safely read while holding the decoder monitor
     756             :   // OR on the main thread.
     757             :   Canonical<PlayState> mNextState;
     758             : 
     759             :   // True if the decoder is seeking.
     760             :   Canonical<bool> mLogicallySeeking;
     761             : 
     762             :   // True if the media is same-origin with the element. Data can only be
     763             :   // passed to MediaStreams when this is true.
     764             :   Canonical<bool> mSameOriginMedia;
     765             : 
     766             :   // An identifier for the principal of the media. Used to track when
     767             :   // main-thread induced principal changes get reflected on MSG thread.
     768             :   Canonical<PrincipalHandle> mMediaPrincipalHandle;
     769             : 
     770             :   // Estimate of the current playback rate (bytes/second).
     771             :   Canonical<double> mPlaybackBytesPerSecond;
     772             : 
     773             :   // True if mPlaybackBytesPerSecond is a reliable estimate.
     774             :   Canonical<bool> mPlaybackRateReliable;
     775             : 
     776             :   // Current decoding position in the stream. This is where the decoder
     777             :   // is up to consuming the stream. This is not adjusted during decoder
     778             :   // seek operations, but it's updated at the end when we start playing
     779             :   // back again.
     780             :   Canonical<int64_t> mDecoderPosition;
     781             : 
     782             : public:
     783           0 :   AbstractCanonical<double>* CanonicalVolume() { return &mVolume; }
     784           0 :   AbstractCanonical<bool>* CanonicalPreservesPitch()
     785             :   {
     786           0 :     return &mPreservesPitch;
     787             :   }
     788           0 :   AbstractCanonical<bool>* CanonicalLooping()
     789             :   {
     790           0 :     return &mLooping;
     791             :   }
     792           0 :   AbstractCanonical<Maybe<double>>* CanonicalExplicitDuration()
     793             :   {
     794           0 :     return &mExplicitDuration;
     795             :   }
     796           0 :   AbstractCanonical<PlayState>* CanonicalPlayState() { return &mPlayState; }
     797           0 :   AbstractCanonical<PlayState>* CanonicalNextPlayState() { return &mNextState; }
     798             :   AbstractCanonical<bool>* CanonicalLogicallySeeking()
     799             :   {
     800             :     return &mLogicallySeeking;
     801             :   }
     802           0 :   AbstractCanonical<bool>* CanonicalSameOriginMedia()
     803             :   {
     804           0 :     return &mSameOriginMedia;
     805             :   }
     806           0 :   AbstractCanonical<PrincipalHandle>* CanonicalMediaPrincipalHandle()
     807             :   {
     808           0 :     return &mMediaPrincipalHandle;
     809             :   }
     810           0 :   AbstractCanonical<double>* CanonicalPlaybackBytesPerSecond()
     811             :   {
     812           0 :     return &mPlaybackBytesPerSecond;
     813             :   }
     814           0 :   AbstractCanonical<bool>* CanonicalPlaybackRateReliable()
     815             :   {
     816           0 :     return &mPlaybackRateReliable;
     817             :   }
     818           0 :   AbstractCanonical<int64_t>* CanonicalDecoderPosition()
     819             :   {
     820           0 :     return &mDecoderPosition;
     821             :   }
     822             : 
     823             : private:
     824             :   // Notify owner when the audible state changed
     825             :   void NotifyAudibleStateChanged();
     826             : 
     827             :   bool mTelemetryReported;
     828             : 
     829             :   // Used to debug how mOwner becomes a dangling pointer in bug 1326294.
     830             :   bool mIsMediaElement;
     831             :   WeakPtr<dom::HTMLMediaElement> mElement;
     832             :   const MediaContainerType mContainerType;
     833             : };
     834             : 
     835             : } // namespace mozilla
     836             : 
     837             : #endif

Generated by: LCOV version 1.13