Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / hls_data_source_provider.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_DATA_SOURCE_PROVIDER_H_
6 #define MEDIA_FILTERS_HLS_DATA_SOURCE_PROVIDER_H_
7
8 #include <cstdint>
9 #include <memory>
10
11 #include "base/functional/callback.h"
12 #include "base/strings/string_piece_forward.h"
13 #include "base/types/id_type.h"
14 #include "media/base/media_export.h"
15 #include "media/base/status.h"
16 #include "media/formats/hls/types.h"
17 #include "third_party/abseil-cpp/absl/types/optional.h"
18 #include "url/gurl.h"
19
20 namespace media {
21
22 class HlsDataSourceStream;
23
24 // Interface which can provide data sources, given a URI and an optional
25 // byterange. This interface should be used via `base::SequenceBound` to proxy
26 // requests across the media thread and the main thread.
27 class MEDIA_EXPORT HlsDataSourceProvider {
28  public:
29   virtual ~HlsDataSourceProvider() = 0;
30
31   struct ReadStatusTraits {
32     enum class Codes : StatusCodeType {
33       kError,
34       kAborted,
35     };
36     static constexpr StatusGroupType Group() {
37       return "HlsDataSourceProvider::ReadStatus";
38     }
39   };
40
41   using ReadStatus = TypedStatus<ReadStatusTraits>;
42   using ReadResult = ReadStatus::Or<std::unique_ptr<HlsDataSourceStream>>;
43   using ReadCb = base::OnceCallback<void(ReadResult)>;
44
45   // Kicks off a read from the given url and the optional constrained byterange
46   // and replies with a stream reference, which can be use to continue reading
47   // and to extract already fetched data.
48   virtual void ReadFromUrl(GURL uri,
49                            absl::optional<hls::types::ByteRange> range,
50                            ReadCb callback) = 0;
51
52   // Continues to read from an existing stream.
53   virtual void ReadFromExistingStream(
54       std::unique_ptr<HlsDataSourceStream> stream,
55       ReadCb callback) = 0;
56
57   // Aborts all pending reads and calls `callback` when finished.
58   virtual void AbortPendingReads(base::OnceClosure callback) = 0;
59 };
60
61 // A buffer-owning wrapper for an HlsDataSource which can be instructed to
62 // read an entire data source, or to retrieve it in chunks.
63 class MEDIA_EXPORT HlsDataSourceStream {
64  public:
65   // The response to a stream read includes a raw pointer back to the stream
66   // which allows accessing the data from a read as well as caching a partially
67   // read stream handle for continued downloading.
68   using StreamId = base::IdType32<HlsDataSourceStream>;
69
70   // Create a stream where `on_destructed_cb` is used to give notice that this
71   // class is being destroyed. This class isn't safe to access from anything
72   // except for an ownership-holding smart pointer, as the destruction cb may
73   // do work across threads.
74   HlsDataSourceStream(StreamId stream_id,
75                       base::OnceClosure on_destructed_cb,
76                       absl::optional<hls::types::ByteRange> range);
77   ~HlsDataSourceStream();
78
79   // Streams use an ID associated with a MultiBufferDataSource without
80   // owning it.
81   StreamId stream_id() const { return stream_id_; }
82
83   // This is the byte position in the MultiBufferDataSource where new data
84   // will be read from. This only ever goes up, because these streams are not
85   // rewindable.
86   size_t read_position() const { return read_position_; }
87
88   size_t buffer_size() const { return buffer_.size(); }
89
90   absl::optional<size_t> max_read_position() const {
91     return max_read_position_;
92   }
93
94   const uint8_t* raw_data() const { return buffer_.data(); }
95
96   // Often the network data for HLS consists of plain-text manifest files, so
97   // this supports accessing the fetched data as a string view.
98   std::string_view AsString() const;
99
100   // Has the stream read all possible data?
101   bool CanReadMore() const;
102
103   // Clears the internal buffer of data. Continual reads will refill the buffer
104   // and reading without clearing will append to the end of the buffer.
105   void Clear();
106
107   // Used by a HlsDataSourceProvider implementation to finish adding data to
108   // the internal buffer.
109   void UnlockStreamPostWrite(int read_size, bool end_of_stream);
110
111   // Used by a HlsDataSourceProvider implementation to start adding new data,
112   // which means ensuring that there is enough space for the expected write, as
113   // well as returning the correct buffer address to write into.
114   uint8_t* LockStreamForWriting(int ensure_minimum_space);
115
116  private:
117   const StreamId stream_id_;
118
119   // Active buffer data. Reading without clearing will append new data
120   // to the end of the buffer. Clearing will not reset the read-head, but will
121   // empty this buffer.
122   // TODO(crbug/1266991): Consider swapping out the vector with a more
123   // size-flexible data structure to avoid resizing.
124   std::vector<uint8_t> buffer_;
125
126   size_t read_position_ = 0;
127
128   // The write index into `buffer_`. This gets reset on flush.
129   size_t write_index_ = 0;
130
131   // If this optional value is set, then data can't be read past this maximum
132   // value.
133   absl::optional<size_t> max_read_position_;
134
135   // The data source read response indicated that the stream has ended.
136   bool reached_end_of_stream_ = false;
137
138   // The stream is unable to start a second write or clear until it is unlocked
139   // by UnlockStreamPostWrite.
140   bool stream_locked_ = false;
141
142   base::OnceClosure on_destructed_cb_;
143
144   SEQUENCE_CHECKER(sequence_checker_);
145   base::WeakPtrFactory<HlsDataSourceStream> weak_factory_{this};
146 };
147
148 }  // namespace media
149
150 #endif  // MEDIA_FILTERS_HLS_DATA_SOURCE_PROVIDER_H_