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 OnPlaybackEvent(MediaPlaybackEvent
&& aEvent
) override
;
63 void DurationChanged() override
;
64 void MetadataLoaded(UniquePtr
<MediaInfo
> aInfo
, UniquePtr
<MetadataTags
> aTags
,
65 MediaDecoderEventVisibility aEventVisibility
) override
;
66 void NotifyPrincipalChanged() override
;
68 RefPtr
<ResourceCallback
> mResourceCallback
;
69 RefPtr
<BaseMediaResource
> mResource
;
71 explicit ChannelMediaDecoder(MediaDecoderInit
& aInit
);
73 void GetDebugInfo(dom::MediaDecoderDebugInfo
& aInfo
);
76 // Create a decoder for the given aType. Returns null if we were unable
77 // to create the decoder, for example because the requested MIME type in
78 // the init struct was unsupported.
79 static already_AddRefed
<ChannelMediaDecoder
> Create(
80 MediaDecoderInit
& aInit
, DecoderDoctorDiagnostics
* aDiagnostics
);
82 void Shutdown() override
;
86 // Create a new decoder of the same type as this one.
87 already_AddRefed
<ChannelMediaDecoder
> Clone(MediaDecoderInit
& aInit
);
89 nsresult
Load(nsIChannel
* aChannel
, bool aIsPrivateBrowsing
,
90 nsIStreamListener
** aStreamListener
);
92 void AddSizeOfResources(ResourceSizes
* aSizes
) override
;
93 already_AddRefed
<nsIPrincipal
> GetCurrentPrincipal() override
;
94 bool HadCrossOriginRedirects() override
;
95 bool IsTransportSeekable() override
;
96 void SetLoadInBackground(bool aLoadInBackground
) override
;
97 void Suspend() override
;
98 void Resume() override
;
101 void DownloadProgressed();
103 // Create a new state machine to run this decoder.
104 MediaDecoderStateMachine
* CreateStateMachine();
106 nsresult
Load(BaseMediaResource
* aOriginal
);
108 // Called by MediaResource when the download has ended.
109 // Called on the main thread only. aStatus is the result from OnStopRequest.
110 void NotifyDownloadEnded(nsresult aStatus
);
112 // Called by the MediaResource to keep track of the number of bytes read
113 // from the resource. Called on the main by an event runner dispatched
114 // by the MediaResource read functions.
115 void NotifyBytesConsumed(int64_t aBytes
, int64_t aOffset
);
117 bool CanPlayThroughImpl() final
;
119 struct PlaybackRateInfo
{
120 uint32_t mRate
; // Estimate of the current playback rate (bytes/second).
121 bool mReliable
; // True if mRate is a reliable estimate.
123 // The actual playback rate computation.
124 static PlaybackRateInfo
ComputePlaybackRate(
125 const MediaChannelStatistics
& aStats
, BaseMediaResource
* aResource
,
128 // Something has changed that could affect the computed playback rate,
130 static void UpdatePlaybackRate(const PlaybackRateInfo
& aInfo
,
131 BaseMediaResource
* aResource
);
133 // Return statistics. This is used for progress events and other things.
134 // This can be called from any thread. It's only a snapshot of the
135 // current state, since other threads might be changing the state
137 static MediaStatistics
GetStatistics(const PlaybackRateInfo
& aInfo
,
138 BaseMediaResource
* aRes
,
139 int64_t aPlaybackPosition
);
141 bool ShouldThrottleDownload(const MediaStatistics
& aStats
);
143 // Data needed to estimate playback data rate. The timeline used for
144 // this estimate is "decode time" (where the "current time" is the
145 // time of the last decoded video frame).
146 MediaChannelStatistics mPlaybackStatistics
;
148 // Current playback position in the stream. This is (approximately)
149 // where we're up to playing back the stream. This is not adjusted
150 // during decoder seek operations, but it's updated at the end when we
151 // start playing back again.
152 int64_t mPlaybackPosition
= 0;
154 bool mCanPlayThrough
= false;
156 // True if we've been notified that the ChannelMediaResource has
158 bool mInitialChannelPrincipalKnown
= false;
161 } // namespace mozilla
163 #endif // ChannelMediaDecoder_h_