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_