tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ChannelMediaDecoder.h (7021B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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 #ifndef ChannelMediaDecoder_h_
      8 #define ChannelMediaDecoder_h_
      9 
     10 #include "MediaChannelStatistics.h"
     11 #include "MediaDecoder.h"
     12 #include "MediaResourceCallback.h"
     13 
     14 class nsIChannel;
     15 class nsIStreamListener;
     16 
     17 namespace mozilla {
     18 
     19 class BaseMediaResource;
     20 
     21 DDLoggedTypeDeclNameAndBase(ChannelMediaDecoder, MediaDecoder);
     22 
     23 class ChannelMediaDecoder
     24    : public MediaDecoder,
     25      public DecoderDoctorLifeLogger<ChannelMediaDecoder> {
     26  // Used to register with MediaResource to receive notifications which will
     27  // be forwarded to MediaDecoder.
     28  class ResourceCallback : public MediaResourceCallback {
     29    // Throttle calls to MediaDecoder::NotifyDataArrived()
     30    // to be at most once per 500ms.
     31    static const uint32_t sDelay = 500;
     32 
     33   public:
     34    explicit ResourceCallback(AbstractThread* aMainThread);
     35    // Start to receive notifications from ResourceCallback.
     36    void Connect(ChannelMediaDecoder* aDecoder);
     37    // Called upon shutdown to stop receiving notifications.
     38    void Disconnect();
     39 
     40   private:
     41    ~ResourceCallback();
     42 
     43    /* MediaResourceCallback functions */
     44    AbstractThread* AbstractMainThread() const override;
     45    MediaDecoderOwner* GetMediaOwner() const override;
     46    void NotifyNetworkError(const MediaResult& aError) override;
     47    void NotifyDataArrived() override;
     48    void NotifyDataEnded(nsresult aStatus) override;
     49    void NotifyPrincipalChanged() override;
     50    void NotifySuspendedStatusChanged(bool aSuspendedByCache) override;
     51 
     52    static void TimerCallback(nsITimer* aTimer, void* aClosure);
     53 
     54    // The decoder to send notifications. Main-thread only.
     55    ChannelMediaDecoder* mDecoder = nullptr;
     56    nsCOMPtr<nsITimer> mTimer;
     57    bool mTimerArmed = false;
     58    const RefPtr<AbstractThread> mAbstractMainThread;
     59  };
     60 
     61 protected:
     62  void ShutdownInternal() override;
     63  void OnPlaybackEvent(const MediaPlaybackEvent& aEvent) override;
     64  void DurationChanged() override;
     65  void MetadataLoaded(UniquePtr<MediaInfo> aInfo, UniquePtr<MetadataTags> aTags,
     66                      MediaDecoderEventVisibility aEventVisibility) override;
     67  void NotifyPrincipalChanged() override;
     68 
     69  RefPtr<ResourceCallback> mResourceCallback;
     70  RefPtr<BaseMediaResource> mResource;
     71 
     72  explicit ChannelMediaDecoder(MediaDecoderInit& aInit);
     73 
     74  void GetDebugInfo(dom::MediaDecoderDebugInfo& aInfo);
     75 
     76 public:
     77  // Create a decoder for the given aType. Returns null if we were unable
     78  // to create the decoder, for example because the requested MIME type in
     79  // the init struct was unsupported.
     80  static already_AddRefed<ChannelMediaDecoder> Create(
     81      MediaDecoderInit& aInit, DecoderDoctorDiagnostics* aDiagnostics);
     82 
     83  void Shutdown() override;
     84 
     85  bool CanClone();
     86 
     87  // Create a new decoder of the same type as this one.
     88  already_AddRefed<ChannelMediaDecoder> Clone(MediaDecoderInit& aInit);
     89 
     90  nsresult Load(nsIChannel* aChannel, bool aIsPrivateBrowsing,
     91                nsIStreamListener** aStreamListener);
     92 
     93  void AddSizeOfResources(ResourceSizes* aSizes) override;
     94  already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override;
     95  bool HadCrossOriginRedirects() override;
     96  bool IsTransportSeekable() override;
     97  void SetLoadInBackground(bool aLoadInBackground) override;
     98  void Suspend() override;
     99  void Resume() override;
    100 
    101 private:
    102  // A snapshot of the media playback and download state used to determine if
    103  // playback can proceed without interruption.
    104  struct MediaStatistics {
    105    // Estimate of the current playback rate (bytes/second).
    106    double mPlaybackByteRate;
    107    // Estimate of the current download rate (bytes/second). This
    108    // ignores time that the channel was paused by Gecko.
    109    double mDownloadByteRate;
    110    // Total length of media stream in bytes; -1 if not known
    111    int64_t mTotalBytes;
    112    // Current position of the download, in bytes. This is the offset of
    113    // the first uncached byte after the decoder position.
    114    int64_t mDownloadBytePosition;
    115    // Current position of playback, in bytes
    116    int64_t mPlaybackByteOffset;
    117    // If false, then mDownloadRate cannot be considered a reliable
    118    // estimate (probably because the download has only been running
    119    // a short time).
    120    bool mDownloadByteRateReliable;
    121    // If false, then mPlaybackRate cannot be considered a reliable
    122    // estimate (probably because playback has only been running
    123    // a short time).
    124    bool mPlaybackByteRateReliable;
    125 
    126    bool CanPlayThrough() const;
    127    nsCString ToString() const;
    128  };
    129 
    130  void DownloadProgressed();
    131 
    132  // Create a new state machine to run this decoder.
    133  MediaDecoderStateMachineBase* CreateStateMachine(
    134      bool aDisableExternalEngine) override;
    135 
    136  nsresult Load(BaseMediaResource* aOriginal);
    137 
    138  // Called by MediaResource when the download has ended.
    139  // Called on the main thread only. aStatus is the result from OnStopRequest.
    140  void NotifyDownloadEnded(nsresult aStatus);
    141 
    142  // Called by the MediaResource to keep track of the number of bytes read
    143  // from the resource. Called on the main by an event runner dispatched
    144  // by the MediaResource read functions.
    145  void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset);
    146 
    147  bool CanPlayThroughImpl() final;
    148 
    149  struct PlaybackRateInfo {
    150    uint32_t mRate;  // Estimate of the current playback rate (bytes/second).
    151    bool mReliable;  // True if mRate is a reliable estimate.
    152  };
    153 
    154  // Return a PlaybackRateInfo and update the expected byte rate per second for
    155  // playback in the media resource, which improves cache usage prediction
    156  // accuracy. This can only be run off the main thread.
    157  static PlaybackRateInfo UpdateResourceOfPlaybackByteRate(
    158      const MediaChannelStatistics& aStats, BaseMediaResource* aResource,
    159      const media::TimeUnit& aDuration);
    160 
    161  bool ShouldThrottleDownload(const MediaStatistics& aStats);
    162 
    163  // Data needed to estimate playback data rate. The timeline used for
    164  // this estimate is "decode time" (where the "current time" is the
    165  // time of the last decoded video frame).
    166  MediaChannelStatistics mPlaybackStatistics;
    167 
    168  // Current playback byte offset in the stream. This is (approximately)
    169  // where we're up to playing back the stream. This is not adjusted immediately
    170  // after seek happens, but it will be updated when playback starts or stops.
    171  int64_t mPlaybackByteOffset = 0;
    172 
    173  bool mCanPlayThrough = false;
    174 
    175  // True if we've been notified that the ChannelMediaResource has
    176  // a principal.
    177  bool mInitialChannelPrincipalKnown = false;
    178 
    179  // Set in Shutdown() when we start closing mResource, if mResource is set.
    180  // Must resolve before we unregister the shutdown blocker.
    181  RefPtr<GenericPromise> mResourceClosePromise;
    182 };
    183 
    184 }  // namespace mozilla
    185 
    186 #endif  // ChannelMediaDecoder_h_