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/. */
7 #ifndef ChannelMediaDecoder_h_
8 #define ChannelMediaDecoder_h_
10 #include "MediaDecoder.h"
11 #include "MediaResourceCallback.h"
12 #include "MediaChannelStatistics.h"
15 class nsIStreamListener
;
19 class BaseMediaResource
;
21 DDLoggedTypeDeclNameAndBase(ChannelMediaDecoder
, MediaDecoder
);
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;
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.
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
;
52 static void TimerCallback(nsITimer
* aTimer
, void* aClosure
);
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
;
62 void ShutdownInternal() override
;
63 void OnPlaybackEvent(MediaPlaybackEvent
&& aEvent
) override
;
64 void DurationChanged() override
;
65 void MetadataLoaded(UniquePtr
<MediaInfo
> aInfo
, UniquePtr
<MetadataTags
> aTags
,
66 MediaDecoderEventVisibility aEventVisibility
) override
;
67 void NotifyPrincipalChanged() override
;
69 RefPtr
<ResourceCallback
> mResourceCallback
;
70 RefPtr
<BaseMediaResource
> mResource
;
72 explicit ChannelMediaDecoder(MediaDecoderInit
& aInit
);
74 void GetDebugInfo(dom::MediaDecoderDebugInfo
& aInfo
);
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
);
83 void Shutdown() override
;
87 // Create a new decoder of the same type as this one.
88 already_AddRefed
<ChannelMediaDecoder
> Clone(MediaDecoderInit
& aInit
);
90 nsresult
Load(nsIChannel
* aChannel
, bool aIsPrivateBrowsing
,
91 nsIStreamListener
** aStreamListener
);
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
;
102 void DownloadProgressed();
104 // Create a new state machine to run this decoder.
105 MediaDecoderStateMachineBase
* CreateStateMachine(
106 bool aDisableExternalEngine
) override
;
108 nsresult
Load(BaseMediaResource
* aOriginal
);
110 // Called by MediaResource when the download has ended.
111 // Called on the main thread only. aStatus is the result from OnStopRequest.
112 void NotifyDownloadEnded(nsresult aStatus
);
114 // Called by the MediaResource to keep track of the number of bytes read
115 // from the resource. Called on the main by an event runner dispatched
116 // by the MediaResource read functions.
117 void NotifyBytesConsumed(int64_t aBytes
, int64_t aOffset
);
119 bool CanPlayThroughImpl() final
;
121 struct PlaybackRateInfo
{
122 uint32_t mRate
; // Estimate of the current playback rate (bytes/second).
123 bool mReliable
; // True if mRate is a reliable estimate.
125 // The actual playback rate computation.
126 static PlaybackRateInfo
ComputePlaybackRate(
127 const MediaChannelStatistics
& aStats
, BaseMediaResource
* aResource
,
128 const media::TimeUnit
& aDuration
);
130 // Something has changed that could affect the computed playback rate,
132 static void UpdatePlaybackRate(const PlaybackRateInfo
& aInfo
,
133 BaseMediaResource
* aResource
);
135 // Return statistics. This is used for progress events and other things.
136 // This can be called from any thread. It's only a snapshot of the
137 // current state, since other threads might be changing the state
139 static MediaStatistics
GetStatistics(const PlaybackRateInfo
& aInfo
,
140 BaseMediaResource
* aRes
,
141 int64_t aPlaybackPosition
);
143 bool ShouldThrottleDownload(const MediaStatistics
& aStats
);
145 // Data needed to estimate playback data rate. The timeline used for
146 // this estimate is "decode time" (where the "current time" is the
147 // time of the last decoded video frame).
148 MediaChannelStatistics mPlaybackStatistics
;
150 // Current playback position in the stream. This is (approximately)
151 // where we're up to playing back the stream. This is not adjusted
152 // during decoder seek operations, but it's updated at the end when we
153 // start playing back again.
154 int64_t mPlaybackPosition
= 0;
156 bool mCanPlayThrough
= false;
158 // True if we've been notified that the ChannelMediaResource has
160 bool mInitialChannelPrincipalKnown
= false;
162 // Set in Shutdown() when we start closing mResource, if mResource is set.
163 // Must resolve before we unregister the shutdown blocker.
164 RefPtr
<GenericPromise
> mResourceClosePromise
;
167 } // namespace mozilla
169 #endif // ChannelMediaDecoder_h_