1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_FILTERS_DEMUXER_MANAGER_H_
6 #define MEDIA_FILTERS_DEMUXER_MANAGER_H_
10 #include "base/functional/callback.h"
11 #include "base/memory/memory_pressure_listener.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/task/sequenced_task_runner.h"
15 #include "media/base/data_source.h"
16 #include "media/base/demuxer.h"
17 #include "media/base/eme_constants.h"
18 #include "media/base/media_export.h"
19 #include "media/base/media_log.h"
20 #include "media/base/pipeline.h"
21 #include "media/base/pipeline_status.h"
22 #include "media/filters/chunk_demuxer.h"
23 #include "third_party/abseil-cpp/absl/types/optional.h"
24 #include "url/origin.h"
26 #if BUILDFLAG(ENABLE_HLS_DEMUXER)
27 #include "base/threading/sequence_bound.h"
28 #include "media/filters/hls_data_source_provider.h"
30 #endif // BUILDFLAG(ENABLE_HLS_DEMUXER)
34 enum class HlsFallbackImplementation {
40 // This class manages both an implementation of media::Demuxer and of
41 // media::DataSource. DataSource, in particular may be null, since both MSE
42 // playback and Android's MediaPlayerRenderer do not make use of it. In the
43 // case that DataSource is present, these objects should have a similar
44 // lifetime, and both must be destroyed on the media thread, so owning them
45 // together makes sense. Additionally, the demuxer or data source can change
46 // during the lifetime of the player that owns them, so encapsulating that
47 // change logic separately lets the media player impl (WMPI) be a bit simpler,
48 // and dedicate a higher percentage of its complexity to managing playback
50 class MEDIA_EXPORT DemuxerManager {
54 virtual void OnEncryptedMediaInitData(
55 EmeInitDataType init_data_type,
56 const std::vector<uint8_t>& init_data) = 0;
58 virtual void OnChunkDemuxerOpened(ChunkDemuxer* demuxer) = 0;
60 // Called by the data source (for src=) or demuxer (for mse) when loading
62 // Can be called quite often.
63 virtual void OnProgress() = 0;
65 // Used to determine if the client is additionally a client for Android's
66 // MediaPlayerRenderer, which can inform us if we need to create a
68 virtual bool IsMediaPlayerRendererClient() = 0;
70 virtual void OnError(media::PipelineStatus status) = 0;
72 // Used for controlling the client when a demuxer swap happens.
73 virtual void StopForDemuxerReset() = 0;
74 virtual void RestartForHls() = 0;
76 virtual bool IsSecurityOriginCryptographic() const = 0;
78 #if BUILDFLAG(IS_TIZEN_TV)
79 virtual void OnAudioTracksCountChanged(unsigned count) = 0;
82 #if BUILDFLAG(ENABLE_FFMPEG)
83 virtual void AddAudioTrack(const std::string& id,
84 const std::string& label,
85 const std::string& language,
86 bool is_first_track) = 0;
87 virtual void AddVideoTrack(const std::string& id,
88 const std::string& label,
89 const std::string& language,
90 bool is_first_track) = 0;
91 #endif // BUILDFLAG(ENABLE_FFMPEG)
93 #if BUILDFLAG(ENABLE_HLS_DEMUXER)
94 virtual base::SequenceBound<HlsDataSourceProvider>
95 GetHlsDataSourceProvider() = 0;
96 #endif // BUILDFLAG(ENABLE_HLS_DEMUXER)
98 // Returns true if playback would be able to start if data is present.
99 virtual bool CouldPlayIfEnoughData() = 0;
101 // Given a demuxer, the client should construct an implementation of
102 // base::trace_event::MemoryDumpProvider for debugging purposes.
103 virtual void MakeDemuxerThreadDumper(media::Demuxer* demuxer) = 0;
105 virtual double CurrentTime() const = 0;
107 // Allows us to set a loaded url on the client, which might happen when we
108 // handle a redirect as part of a restart for switching to HLS.
109 virtual void UpdateLoadedUrl(const GURL& url) = 0;
111 // Allows a seek triggered by a demuxer (mainly used for live content)
112 virtual void DemuxerRequestsSeek(base::TimeDelta seek_time) = 0;
115 // Demuxer, StartType, IsStreaming, IsStatic
116 using DemuxerCreatedCB =
117 base::OnceCallback<PipelineStatus(Demuxer* demuxer,
118 Pipeline::StartType start_type,
119 bool /*is_streaming*/,
120 bool /*is_static*/)>;
122 DemuxerManager(Client* client,
123 scoped_refptr<base::SequencedTaskRunner> media_task_runner,
125 net::SiteForCookies site_for_cookies,
126 url::Origin top_frame_origin,
127 bool has_storage_access,
128 bool enable_instant_source_buffer_gc,
129 std::unique_ptr<Demuxer> demuxer_override);
131 void InvalidateWeakPtrs();
133 void OnPipelineError(PipelineStatus error);
134 void SetLoadedUrl(GURL url);
135 const GURL& LoadedUrl() const;
136 #if BUILDFLAG(ENABLE_HLS_DEMUXER) || BUILDFLAG(IS_ANDROID)
137 void PopulateHlsHistograms(bool cryptographic_url);
138 PipelineStatus SelectHlsFallbackMechanism(bool cryptographic_url);
139 #endif // BUILDFLAG(ENABLE_HLS_DEMUXER) || BUILDFLAG(IS_ANDROID)
140 void DisallowFallback();
142 // Methods that help manage demuxers
143 absl::optional<double> GetDemuxerDuration();
144 absl::optional<DemuxerType> GetDemuxerType() const;
145 absl::optional<container_names::MediaContainerName> GetContainerForMetrics();
146 void RespondToDemuxerMemoryUsageReport(base::OnceCallback<void(int64_t)> cb);
147 void DisableDemuxerCanChangeType();
149 // Returns a forwarded error/success from |on_demuxer_created|, or an error
150 // if a demuxer couldn't be created.
151 PipelineStatus CreateDemuxer(bool load_media_source,
152 DataSource::Preload preload,
153 bool needs_first_frame,
154 DemuxerCreatedCB on_demuxer_created);
156 #if BUILDFLAG(IS_ANDROID)
157 void SetAllowMediaPlayerRendererCredentials(bool allow);
158 #endif // BUILDFLAG(IS_ANDROID)
160 // Methods that help manage or access |data_source_|
161 const DataSource* GetDataSourceForTesting() const;
162 void SetDataSource(std::unique_ptr<DataSource> data_source);
163 void OnBufferingHaveEnough(bool enough);
164 void SetPreload(DataSource::Preload preload);
166 void StopAndResetClient(Client* client);
167 int64_t GetDataSourceMemoryUsage();
168 void OnDataSourcePlaybackRateChange(double rate, bool paused);
170 bool WouldTaintOrigin() const;
171 bool HasDataSource() const;
172 bool HasDemuxer() const;
173 bool HasDemuxerOverride() const;
174 absl::optional<GURL> GetDataSourceUrlAfterRedirects() const;
175 bool DataSourceFullyBuffered() const;
176 bool IsStreaming() const;
177 bool PassedDataSourceTimingAllowOriginCheck() const;
178 bool IsLiveContent() const;
181 // Demuxer creation and helper methods
182 std::unique_ptr<media::Demuxer> CreateChunkDemuxer();
184 #if BUILDFLAG(ENABLE_FFMPEG)
185 std::unique_ptr<media::Demuxer> CreateFFmpegDemuxer();
186 #endif // BUILDFLAG(ENABLE_FFMPEG)
188 #if BUILDFLAG(ENABLE_HLS_DEMUXER)
189 std::unique_ptr<Demuxer> CreateHlsDemuxer();
192 #if BUILDFLAG(IS_ANDROID) || defined(TIZEN_MULTIMEDIA)
193 std::unique_ptr<media::Demuxer> CreateMediaUrlDemuxer(bool hls_content);
194 #endif // BUILDFLAG(IS_ANDROID)
196 void SetDemuxer(std::unique_ptr<Demuxer> demuxer);
198 // Memory pressure listener specifically for when using ChunkDemuxer.
199 void OnMemoryPressure(
200 base::MemoryPressureListener::MemoryPressureLevel level);
202 // Trampoline methods for binding with |weak_this_| that call into |client_|.;
203 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
204 const std::vector<uint8_t>& init_data);
205 void OnChunkDemuxerOpened();
207 void RestartClientForHLS();
208 void FreeResourcesAfterMediaThreadWait(base::OnceClosure cb);
210 #if BUILDFLAG(IS_TIZEN_TV)
211 void OnAudioTracksCountChanged(unsigned count);
214 #if BUILDFLAG(ENABLE_FFMPEG)
215 void OnFFmpegMediaTracksUpdated(std::unique_ptr<MediaTracks> tracks);
216 #endif // BUILDFLAG(ENABLE_FFMPEG)
218 void DemuxerRequestsSeek(base::TimeDelta time);
220 // This is usually just the WebMediaPlayerImpl.
221 raw_ptr<Client, DanglingUntriaged> client_;
223 // The demuxers need access the the media task runner and media log.
224 const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
225 std::unique_ptr<MediaLog> media_log_;
227 // Android's MediaUrlDemuxer needs access to these.
228 net::SiteForCookies site_for_cookies_;
229 url::Origin top_frame_origin_;
230 #if BUILDFLAG(IS_ANDROID)
231 bool has_storage_access_;
232 #endif // BUILDFLAG(IS_ANDROID)
234 // When MSE memory pressure based garbage collection is enabled, the
235 // |enable_instant_source_buffer_gc| controls whether the GC is done
236 // immediately on memory pressure notification or during the next
237 // SourceBuffer append (slower, but MSE spec compliant).
238 bool enable_instant_source_buffer_gc_ = false;
240 // Used for MediaUrlDemuxer when playing HLS content, as well as
241 // FFmpegDemuxer in most cases. Also used for creating MemoryDataSource
243 // Note: this may be very large, take care when making copies.
246 // The data source for creating a demuxer. This should be null when using
248 std::unique_ptr<DataSource> data_source_;
250 // Holds whichever demuxer implementation is being used.
251 std::unique_ptr<Demuxer> demuxer_;
253 // Holds an optional demuxer that can be passed in at time of creation,
254 // which becomes the default demuxer to use.
255 std::unique_ptr<Demuxer> demuxer_override_;
257 // RAII member for notifying demuxers of memory pressure.
258 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
260 #if BUILDFLAG(IS_ANDROID)
261 // Used to determine whether to allow credentials or not for
262 // MediaPlayerRenderer.
263 bool allow_media_player_renderer_credentials_ = false;
264 #endif // BUILDFLAG(IS_ANDROID)
266 HlsFallbackImplementation hls_fallback_ = HlsFallbackImplementation::kNone;
268 // Are we allowed to switch demuxer mid-stream when fallback error codes
270 bool fallback_allowed_ = true;
272 // Weak pointer implementation.
273 base::WeakPtrFactory<DemuxerManager> weak_factory_{this};
278 #endif // MEDIA_FILTERS_DEMUXER_MANAGER_H_