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.
5 #ifndef MEDIA_FILTERS_HLS_LIVE_RENDITION_H_
6 #define MEDIA_FILTERS_HLS_LIVE_RENDITION_H_
10 #include "base/containers/queue.h"
11 #include "base/moving_window.h"
12 #include "media/filters/hls_rendition.h"
16 // Represents the playback logic for livestreams.
17 class MEDIA_EXPORT HlsLiveRendition : public HlsRendition {
19 ~HlsLiveRendition() override;
20 HlsLiveRendition(ManifestDemuxerEngineHost* engine_host,
21 HlsRenditionHost* rendition_host,
23 scoped_refptr<hls::MediaPlaylist> playlist,
24 GURL media_playlist_uri);
26 // `HlsRendition` implementation
27 absl::optional<base::TimeDelta> GetDuration() override;
28 void CheckState(base::TimeDelta media_time,
30 ManifestDemuxer::DelayCallback time_remaining_cb) override;
31 ManifestDemuxer::SeekResponse Seek(base::TimeDelta seek_time) override;
32 void StartWaitingForSeek() override;
36 base::TimeDelta GetForwardBufferSize() const;
38 // Segment fetching and appending.
39 void LoadSegment(const hls::MediaSegment& segment, base::OnceClosure cb);
40 void FetchMoreDataFromPendingStream(base::OnceClosure cb);
41 void OnSegmentData(base::OnceClosure cb,
42 base::TimeTicks net_req_start,
43 HlsDataSourceProvider::ReadResult result);
46 void AppendSegments(hls::MediaPlaylist* playlist);
47 void MaybeFetchManifestUpdates(base::TimeDelta delay,
48 ManifestDemuxer::DelayCallback cb);
49 void FetchManifestUpdates(base::TimeDelta delay,
50 ManifestDemuxer::DelayCallback cb);
51 void OnManifestUpdates(base::TimeTicks download_start_time,
52 base::TimeDelta delay_time,
53 ManifestDemuxer::DelayCallback cb,
54 HlsDataSourceProvider::ReadResult result);
55 void ClearOldData(base::TimeDelta time);
57 void ContinuePartialFetching(base::OnceClosure cb);
59 // `ManifestDemuxerEngineHost` owns the `HlsRenditionHost` which in
60 // turn owns |this|, so it's safe to keep these as raw ptrs. |host_| is needed
61 // to access the chunk demuxer, and |engine_| is needed to make network
63 raw_ptr<ManifestDemuxerEngineHost> engine_host_;
64 raw_ptr<HlsRenditionHost> rendition_host_;
66 // The chunk demuxer role for this rendition.
69 // The current playlist. Needs to be updated periodically.
70 GURL media_playlist_uri_;
72 // A queue of segments.
73 base::queue<scoped_refptr<hls::MediaSegment>> segments_;
75 // The parser offset timestamp for this stream.
76 base::TimeDelta parse_offset_;
77 base::TimeDelta parse_end_ = base::Seconds(0);
79 // Keep state for reloading playlists.
80 base::TimeTicks last_download_time_;
81 hls::types::DecimalInteger last_sequence_number_ = 0;
82 hls::types::DecimalInteger first_sequence_number_ = 0;
84 // Manifests should declare an upper limit on the length of segments.
85 base::TimeDelta segment_duration_upper_limit_;
87 // If this is set, then use it to get more data. Otherwise, fetch another
89 std::unique_ptr<HlsDataSourceStream> partial_stream_;
91 // Record the time it takes to download content.
92 base::MovingAverage<base::TimeDelta, base::TimeDelta> fetch_time_{32};
94 bool has_ever_played_ = false;
95 bool require_seek_after_unpause_ = false;
96 bool is_stopped_for_shutdown_ = false;
98 SEQUENCE_CHECKER(sequence_checker_);
100 base::WeakPtrFactory<HlsLiveRendition> weak_factory_{this};
105 #endif // MEDIA_FILTERS_HLS_LIVE_RENDITION_H_