[M120 Migration][hbbtv] Audio tracks count notification
[platform/framework/web/chromium-efl.git] / media / filters / hls_manifest_demuxer_engine.h
1 // Copyright 2023 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.
4
5 #ifndef MEDIA_FILTERS_HLS_MANIFEST_DEMUXER_ENGINE_H_
6 #define MEDIA_FILTERS_HLS_MANIFEST_DEMUXER_ENGINE_H_
7
8 #include <vector>
9
10 #include "base/memory/scoped_refptr.h"
11 #include "base/task/sequenced_task_runner.h"
12 #include "base/threading/sequence_bound.h"
13 #include "base/time/time.h"
14 #include "media/base/media_export.h"
15 #include "media/base/media_log.h"
16 #include "media/base/media_track.h"
17 #include "media/base/pipeline_status.h"
18 #include "media/filters/hls_codec_detector.h"
19 #include "media/filters/hls_data_source_provider.h"
20 #include "media/filters/hls_demuxer_status.h"
21 #include "media/filters/hls_rendition.h"
22 #include "media/filters/manifest_demuxer.h"
23 #include "media/formats/hls/media_playlist.h"
24 #include "media/formats/hls/parse_status.h"
25 #include "media/formats/hls/rendition_selector.h"
26 #include "third_party/abseil-cpp/absl/types/optional.h"
27
28 namespace media {
29
30 // A HLS-Parser/Player implementation of ManifestDemuxer's Engine interface.
31 // This will use the HLS parsers and rendition selectors to fetch and parse
32 // playlists, followed by fetching and appending media segments.
33 class MEDIA_EXPORT HlsManifestDemuxerEngine : public ManifestDemuxer::Engine,
34                                               public HlsRenditionHost {
35  public:
36   HlsManifestDemuxerEngine(base::SequenceBound<HlsDataSourceProvider> dsp,
37                            scoped_refptr<base::SequencedTaskRunner> task_runner,
38                            GURL root_playlist_uri,
39                            MediaLog* media_log);
40   ~HlsManifestDemuxerEngine() override;
41
42   // HlsRenditionHost implementation
43   std::string GetName() const override;
44   void Initialize(ManifestDemuxerEngineHost* host,
45                   PipelineStatusCallback status_cb) override;
46   void OnTimeUpdate(base::TimeDelta time,
47                     double playback_rate,
48                     ManifestDemuxer::DelayCallback cb) override;
49   void Seek(base::TimeDelta time, ManifestDemuxer::SeekCallback cb) override;
50   void StartWaitingForSeek() override;
51   void AbortPendingReads() override;
52   bool IsSeekable() const override;
53   int64_t GetMemoryUsage() const override;
54   void Stop() override;
55   void ReadFromUrl(GURL uri,
56                    bool read_chunked,
57                    absl::optional<hls::types::ByteRange> range,
58                    HlsDataSourceProvider::ReadCb cb) override;
59   void ReadStream(std::unique_ptr<HlsDataSourceStream> stream,
60                   HlsDataSourceProvider::ReadCb cb) override;
61
62   // Parses a playlist using the multivariant playlist, if it's being used.
63   hls::ParseStatus::Or<scoped_refptr<hls::MediaPlaylist>>
64   ParseMediaPlaylistFromStringSource(
65       base::StringPiece source,
66       GURL uri,
67       hls::types::DecimalInteger version) override;
68
69   // Test helpers.
70   void AddRenditionForTesting(std::unique_ptr<HlsRendition> test_rendition);
71   void InitializeWithMockCodecDetectorForTesting(
72       ManifestDemuxerEngineHost* host,
73       PipelineStatusCallback cb,
74       std::unique_ptr<HlsCodecDetector> codec_detector);
75
76  private:
77   struct PlaylistParseInfo {
78     PlaylistParseInfo(GURL uri,
79                       std::vector<std::string> codecs,
80                       std::string role,
81                       bool allow_multivariant_playlist = false);
82     PlaylistParseInfo(const PlaylistParseInfo& copy);
83     ~PlaylistParseInfo();
84
85     // The url that this media playlist came from. We might need to update it
86     // if its a live playlist, so it's vital to keep it around.
87     GURL uri;
88
89     // Any detected codecs associated with this stream.
90     std::vector<std::string> codecs;
91
92     // The name given to this stream in chunk demuxer.
93     std::string role;
94
95     // Only root playlists are allowed to be multivariant.
96     bool allow_multivariant_playlist;
97   };
98
99   // Call the `CheckState` method of each rendition recursively and
100   // asynchronously while also maintaining the correct delay time.
101   // `media_time` and `playback_rate` represent the state of the playing media
102   // `cb` allows requesting a delay time until the next CheckState call,
103   // `rendition_index` is the index into `renditions_` that should be
104   // asynchronously checked next, and `response_time` is what the previously
105   // checked renditions requested for a delay time. The ultimate response to
106   // `cb` should be the lowest of all requested delays, adjusted for the time
107   // taken to calculate later delays, e.g.:
108   // Rendition1 requests 5 seconds, takes 2 seconds
109   // Rendition2 requests 4 seconds, takes 1.5 seconds
110   // Rendition3 requests kNoTimestamp, takes 1 second
111   // First the 5 second response is carried forward, then after the second
112   // response is acquired, the lesser of (5 - 1.5) and 4 is selected, so 3.5
113   // seconds is carried forward as a delay time. Finally after the kNoTimestamp
114   // response is acquired, the duration is once again subtracted and a final
115   // delay time of 2.5 seconds is returned via cb.
116   void CheckStateAtIndex(base::TimeDelta media_time,
117                          double playback_rate,
118                          ManifestDemuxer::DelayCallback cb,
119                          size_t rendition_index,
120                          absl::optional<base::TimeDelta> response_time);
121
122   // Helper for `CheckStateAtIndex` to be bound for Rendition::CheckState
123   // method calls.
124   void OnStateChecked(
125       base::TimeTicks call_start,
126       absl::optional<base::TimeDelta> prior_delay,
127       base::OnceCallback<void(absl::optional<base::TimeDelta>)> cb,
128       base::TimeDelta delay_time);
129
130   // Helpers to call |PlayerImplDemuxer::OnDemuxerError|.
131   void Abort(HlsDemuxerStatus status);
132   void Abort(hls::ParseStatus status);
133   void Abort(HlsDataSourceProvider::ReadStatus status);
134
135   // Read the entire contents of a data source stream before calling cb.
136   void ReadUntilExhausted(HlsDataSourceProvider::ReadCb cb,
137                           HlsDataSourceProvider::ReadResult result);
138
139   void ParsePlaylist(PipelineStatusCallback parse_complete_cb,
140                      PlaylistParseInfo parse_info,
141                      HlsDataSourceProvider::ReadResult m_stream);
142
143   void OnMultivariantPlaylist(
144       PipelineStatusCallback parse_complete_cb,
145       scoped_refptr<hls::MultivariantPlaylist> playlist);
146   void SetStreams(std::vector<PlaylistParseInfo> playlists,
147                   PipelineStatusCallback cb,
148                   PipelineStatus exit_on_error);
149
150   void OnMediaPlaylist(PipelineStatusCallback parse_complete_cb,
151                        PlaylistParseInfo parse_info,
152                        scoped_refptr<hls::MediaPlaylist> playlist);
153   void DetermineStreamContainerAndCodecs(
154       hls::MediaPlaylist* playlist,
155       HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> container_cb);
156   void OnPlaylistContainerDetermined(
157       PipelineStatusCallback parse_complete_cb,
158       PlaylistParseInfo parse_info,
159       scoped_refptr<hls::MediaPlaylist> playlist,
160       HlsDemuxerStatus::Or<HlsCodecDetector::ContainerAndCodecs> maybe_info);
161   void PeekFirstSegment(
162       HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> cb,
163       HlsDataSourceProvider::ReadResult maybe_stream);
164
165   void OnChunkDemuxerParseWarning(std::string role,
166                                   SourceBufferParseWarning warning);
167   void OnChunkDemuxerTracksChanged(std::string role,
168                                    std::unique_ptr<MediaTracks> tracks);
169   void ContinueSeekInternal(base::TimeDelta time,
170                             ManifestDemuxer::SeekCallback cb);
171
172   void InitializeWithCodecDetector(
173       ManifestDemuxerEngineHost* host,
174       PipelineStatusCallback status_cb,
175       std::unique_ptr<HlsCodecDetector> codec_detector);
176
177   base::SequenceBound<HlsDataSourceProvider> data_source_provider_;
178   scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
179
180   // root playlist, either multivariant or media.
181   GURL root_playlist_uri_;
182
183   std::unique_ptr<MediaLog> media_log_;
184   raw_ptr<ManifestDemuxerEngineHost> host_
185       GUARDED_BY_CONTEXT(media_sequence_checker_) = nullptr;
186
187   // The codec detector is a reusable way for determining codecs in a media
188   // stream.
189   std::unique_ptr<HlsCodecDetector> codec_detector_
190       GUARDED_BY_CONTEXT(media_sequence_checker_);
191
192   // If the root playlist is multivariant, we need to store it for parsing the
193   // dependant media playlists.
194   scoped_refptr<hls::MultivariantPlaylist> multivariant_root_
195       GUARDED_BY_CONTEXT(media_sequence_checker_);
196   std::unique_ptr<hls::RenditionSelector> rendition_selector_
197       GUARDED_BY_CONTEXT(media_sequence_checker_);
198
199   // Multiple renditions are allowed, and have to be synchronized.
200   std::vector<std::unique_ptr<HlsRendition>> renditions_
201       GUARDED_BY_CONTEXT(media_sequence_checker_);
202
203   // When renditions are added, this ensures that they are all of the same
204   // liveness, and allows access to the liveness check later.
205   absl::optional<bool> is_seekable_ = absl::nullopt;
206
207   // Preferences for selecting optimal renditions. Storing them allows them
208   // to be changed later due to network constraints or user changes.
209   hls::RenditionSelector::VideoPlaybackPreferences video_preferences_
210       GUARDED_BY_CONTEXT(media_sequence_checker_) = {absl::nullopt,
211                                                      absl::nullopt};
212   hls::RenditionSelector::AudioPlaybackPreferences audio_preferences_
213       GUARDED_BY_CONTEXT(media_sequence_checker_) = {absl::nullopt,
214                                                      absl::nullopt};
215
216   // Ensure that safe member fields are only accessed on the media sequence.
217   SEQUENCE_CHECKER(media_sequence_checker_);
218
219   base::WeakPtrFactory<HlsManifestDemuxerEngine> weak_factory_{this};
220 };
221
222 }  // namespace media
223
224 #endif  // MEDIA_FILTERS_HLS_MANIFEST_DEMUXER_ENGINE_H_