| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 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_BLINK_BUFFERED_DATA_SOURCE_H_ | |
| 6 #define MEDIA_BLINK_BUFFERED_DATA_SOURCE_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <memory> | |
| 11 #include <string> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/callback.h" | |
| 15 #include "base/macros.h" | |
| 16 #include "base/memory/weak_ptr.h" | |
| 17 #include "base/synchronization/lock.h" | |
| 18 #include "media/base/data_source.h" | |
| 19 #include "media/base/ranges.h" | |
| 20 #include "media/blink/buffered_resource_loader.h" | |
| 21 #include "media/blink/media_blink_export.h" | |
| 22 #include "url/gurl.h" | |
| 23 | |
| 24 namespace base { | |
| 25 class SingleThreadTaskRunner; | |
| 26 } | |
| 27 | |
| 28 namespace media { | |
| 29 class MediaLog; | |
| 30 | |
| 31 class MEDIA_BLINK_EXPORT BufferedDataSourceHost { | |
| 32 public: | |
| 33 // Notify the host of the total size of the media file. | |
| 34 virtual void SetTotalBytes(int64_t total_bytes) = 0; | |
| 35 | |
| 36 // Notify the host that byte range [start,end] has been buffered. | |
| 37 // TODO(fischman): remove this method when demuxing is push-based instead of | |
| 38 // pull-based. http://crbug.com/131444 | |
| 39 virtual void AddBufferedByteRange(int64_t start, int64_t end) = 0; | |
| 40 | |
| 41 protected: | |
| 42 virtual ~BufferedDataSourceHost() {} | |
| 43 }; | |
| 44 | |
| 45 // This interface is temporary and will go away once MultibufferDataSource | |
| 46 // has been fully evaluated. | |
| 47 class BufferedDataSourceInterface : public DataSource { | |
| 48 public: | |
| 49 // Used to specify video preload states. They are "hints" to the browser about | |
| 50 // how aggressively the browser should load and buffer data. | |
| 51 // Please see the HTML5 spec for the descriptions of these values: | |
| 52 // http://www.w3.org/TR/html5/video.html#attr-media-preload | |
| 53 // | |
| 54 // Enum values must match the values in blink::WebMediaPlayer::Preload and | |
| 55 // there will be assertions at compile time if they do not match. | |
| 56 enum Preload { | |
| 57 NONE, | |
| 58 METADATA, | |
| 59 AUTO, | |
| 60 }; | |
| 61 | |
| 62 // Enum values must match the values in | |
| 63 // blink::WebMediaPlayer::BufferingStrategy and there will be assertions at | |
| 64 // compile time if they do not match. | |
| 65 enum BufferingStrategy { | |
| 66 BUFFERING_STRATEGY_NORMAL, | |
| 67 BUFFERING_STRATEGY_AGGRESSIVE, | |
| 68 }; | |
| 69 | |
| 70 // Executes |init_cb| with the result of initialization when it has completed. | |
| 71 // | |
| 72 // Method called on the render thread. | |
| 73 typedef base::Callback<void(bool)> InitializeCB; | |
| 74 virtual void Initialize(const InitializeCB& init_cb) = 0; | |
| 75 | |
| 76 // Adjusts the buffering algorithm based on the given preload value. | |
| 77 virtual void SetPreload(Preload preload) = 0; | |
| 78 | |
| 79 // Adjusts the buffering algorithm based on the given buffering strategy | |
| 80 // value. | |
| 81 virtual void SetBufferingStrategy(BufferingStrategy buffering_strategy) = 0; | |
| 82 | |
| 83 // Returns true if the media resource has a single origin, false otherwise. | |
| 84 // Only valid to call after Initialize() has completed. | |
| 85 // | |
| 86 // Method called on the render thread. | |
| 87 virtual bool HasSingleOrigin() = 0; | |
| 88 | |
| 89 // Returns true if the media resource passed a CORS access control check. | |
| 90 virtual bool DidPassCORSAccessCheck() const = 0; | |
| 91 | |
| 92 // Cancels initialization, any pending loaders, and any pending read calls | |
| 93 // from the demuxer. The caller is expected to release its reference to this | |
| 94 // object and never call it again. | |
| 95 // | |
| 96 // Method called on the render thread. | |
| 97 virtual void Abort() = 0; | |
| 98 | |
| 99 // Notifies changes in playback state for controlling media buffering | |
| 100 // behavior. | |
| 101 virtual void MediaPlaybackRateChanged(double playback_rate) = 0; | |
| 102 virtual void MediaIsPlaying() = 0; | |
| 103 virtual bool media_has_played() const = 0; | |
| 104 | |
| 105 // Returns true if the resource is local. | |
| 106 virtual bool assume_fully_buffered() = 0; | |
| 107 | |
| 108 // Cancels any open network connections once reaching the deferred state. If | |
| 109 // |always_cancel| is false this is done only for preload=metadata, non- | |
| 110 // streaming resources that have not started playback. If |always_cancel| is | |
| 111 // true, all resource types will have their connections canceled. If already | |
| 112 // deferred, connections will be immediately closed. | |
| 113 virtual void OnBufferingHaveEnough(bool always_cancel) = 0; | |
| 114 | |
| 115 // Returns an estimate of the number of bytes held by the data source. | |
| 116 virtual int64_t GetMemoryUsage() const = 0; | |
| 117 | |
| 118 // Returns the post-Initialize() URL after redirects have been followed; this | |
| 119 // value may change at a later time. | |
| 120 virtual GURL GetUrlAfterRedirects() const = 0; | |
| 121 }; | |
| 122 | |
| 123 // A data source capable of loading URLs and buffering the data using an | |
| 124 // in-memory sliding window. | |
| 125 // | |
| 126 // BufferedDataSource must be created and destroyed on the thread associated | |
| 127 // with the |task_runner| passed in the constructor. | |
| 128 class MEDIA_BLINK_EXPORT BufferedDataSource | |
| 129 : NON_EXPORTED_BASE(public BufferedDataSourceInterface) { | |
| 130 public: | |
| 131 // Number of cache misses or read failures we allow for a single Read() before | |
| 132 // signaling an error. | |
| 133 enum { kLoaderRetries = 30 }; | |
| 134 typedef base::Callback<void(bool)> DownloadingCB; | |
| 135 | |
| 136 // |url| and |cors_mode| are passed to the object. Buffered byte range changes | |
| 137 // will be reported to |host|. |downloading_cb| will be called whenever the | |
| 138 // downloading/paused state of the source changes. | |
| 139 BufferedDataSource( | |
| 140 const GURL& url, | |
| 141 BufferedResourceLoader::CORSMode cors_mode, | |
| 142 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
| 143 blink::WebFrame* frame, | |
| 144 MediaLog* media_log, | |
| 145 BufferedDataSourceHost* host, | |
| 146 const DownloadingCB& downloading_cb); | |
| 147 ~BufferedDataSource() override; | |
| 148 | |
| 149 // Executes |init_cb| with the result of initialization when it has completed. | |
| 150 // | |
| 151 // Method called on the render thread. | |
| 152 typedef base::Callback<void(bool)> InitializeCB; | |
| 153 void Initialize(const InitializeCB& init_cb) override; | |
| 154 | |
| 155 // Adjusts the buffering algorithm based on the given preload value. | |
| 156 void SetPreload(Preload preload) override; | |
| 157 | |
| 158 // Adjusts the buffering algorithm based on the given buffering strategy | |
| 159 // value. | |
| 160 void SetBufferingStrategy(BufferingStrategy buffering_strategy) override; | |
| 161 | |
| 162 // Returns true if the media resource has a single origin, false otherwise. | |
| 163 // Only valid to call after Initialize() has completed. | |
| 164 // | |
| 165 // Method called on the render thread. | |
| 166 bool HasSingleOrigin() override; | |
| 167 | |
| 168 // Returns true if the media resource passed a CORS access control check. | |
| 169 bool DidPassCORSAccessCheck() const override; | |
| 170 | |
| 171 // Cancels initialization, any pending loaders, and any pending read calls | |
| 172 // from the demuxer. The caller is expected to release its reference to this | |
| 173 // object and never call it again. | |
| 174 // | |
| 175 // Method called on the render thread. | |
| 176 void Abort() override; | |
| 177 | |
| 178 // Notifies changes in playback state for controlling media buffering | |
| 179 // behavior. | |
| 180 void MediaPlaybackRateChanged(double playback_rate) override; | |
| 181 void MediaIsPlaying() override; | |
| 182 bool media_has_played() const override; | |
| 183 | |
| 184 // Returns true if the resource is local. | |
| 185 bool assume_fully_buffered() override; | |
| 186 | |
| 187 // Cancels any open network connections once reaching the deferred state. If | |
| 188 // |always_cancel| is false this is done only for preload=metadata, non- | |
| 189 // streaming resources that have not started playback. If |always_cancel| is | |
| 190 // true, all resource types will have their connections canceled. If already | |
| 191 // deferred, connections will be immediately closed. | |
| 192 void OnBufferingHaveEnough(bool always_cancel) override; | |
| 193 | |
| 194 // Returns an estimate of the number of bytes held by the data source. | |
| 195 int64_t GetMemoryUsage() const override; | |
| 196 | |
| 197 GURL GetUrlAfterRedirects() const override; | |
| 198 | |
| 199 // DataSource implementation. | |
| 200 // Called from demuxer thread. | |
| 201 void Stop() override; | |
| 202 | |
| 203 void Read(int64_t position, | |
| 204 int size, | |
| 205 uint8_t* data, | |
| 206 const DataSource::ReadCB& read_cb) override; | |
| 207 bool GetSize(int64_t* size_out) override; | |
| 208 bool IsStreaming() override; | |
| 209 void SetBitrate(int bitrate) override; | |
| 210 | |
| 211 protected: | |
| 212 // A factory method to create a BufferedResourceLoader based on the read | |
| 213 // parameters. We can override this file to object a mock | |
| 214 // BufferedResourceLoader for testing. | |
| 215 virtual BufferedResourceLoader* CreateResourceLoader( | |
| 216 int64_t first_byte_position, | |
| 217 int64_t last_byte_position); | |
| 218 | |
| 219 private: | |
| 220 friend class BufferedDataSourceTest; | |
| 221 | |
| 222 // Task posted to perform actual reading on the render thread. | |
| 223 void ReadTask(); | |
| 224 | |
| 225 // Cancels oustanding callbacks and sets |stop_signal_received_|. Safe to call | |
| 226 // from any thread. | |
| 227 void StopInternal_Locked(); | |
| 228 | |
| 229 // Stops |loader_| if present. Used by Abort() and Stop(). | |
| 230 void StopLoader(); | |
| 231 | |
| 232 // Tells |loader_| the bitrate of the media. | |
| 233 void SetBitrateTask(int bitrate); | |
| 234 | |
| 235 // The method that performs actual read. This method can only be executed on | |
| 236 // the render thread. | |
| 237 void ReadInternal(); | |
| 238 | |
| 239 // BufferedResourceLoader::Start() callback for initial load. | |
| 240 void StartCallback(BufferedResourceLoader::Status status); | |
| 241 | |
| 242 // BufferedResourceLoader::Start() callback for subsequent loads (i.e., | |
| 243 // when accessing ranges that are outside initial buffered region). | |
| 244 void PartialReadStartCallback(BufferedResourceLoader::Status status); | |
| 245 | |
| 246 // Returns true if we can accept the new partial response. | |
| 247 bool CheckPartialResponseURL(const GURL& partial_response_original_url) const; | |
| 248 | |
| 249 // BufferedResourceLoader callbacks. | |
| 250 void ReadCallback(BufferedResourceLoader::Status status, int bytes_read); | |
| 251 void LoadingStateChangedCallback(BufferedResourceLoader::LoadingState state); | |
| 252 void ProgressCallback(int64_t position); | |
| 253 | |
| 254 // Update |loader_|'s deferring strategy. | |
| 255 void UpdateDeferStrategy(); | |
| 256 | |
| 257 // URL of the resource requested. | |
| 258 GURL url_; | |
| 259 // crossorigin attribute on the corresponding HTML media element, if any. | |
| 260 BufferedResourceLoader::CORSMode cors_mode_; | |
| 261 | |
| 262 // The total size of the resource. Set during StartCallback() if the size is | |
| 263 // known, otherwise it will remain kPositionNotSpecified until the size is | |
| 264 // determined by reaching EOF. | |
| 265 int64_t total_bytes_; | |
| 266 | |
| 267 // This value will be true if this data source can only support streaming. | |
| 268 // i.e. range request is not supported. | |
| 269 bool streaming_; | |
| 270 | |
| 271 // A webframe for loading. | |
| 272 blink::WebFrame* frame_; | |
| 273 | |
| 274 // A resource loader for the media resource. | |
| 275 std::unique_ptr<BufferedResourceLoader> loader_; | |
| 276 | |
| 277 // Callback method from the pipeline for initialization. | |
| 278 InitializeCB init_cb_; | |
| 279 | |
| 280 // Read parameters received from the Read() method call. Must be accessed | |
| 281 // under |lock_|. | |
| 282 class ReadOperation; | |
| 283 std::unique_ptr<ReadOperation> read_op_; | |
| 284 | |
| 285 // This buffer is intermediate, we use it for BufferedResourceLoader to write | |
| 286 // to. And when read in BufferedResourceLoader is done, we copy data from | |
| 287 // this buffer to |read_buffer_|. The reason for an additional copy is that | |
| 288 // we don't own |read_buffer_|. But since the read operation is asynchronous, | |
| 289 // |read_buffer| can be destroyed at any time, so we only copy into | |
| 290 // |read_buffer| in the final step when it is safe. | |
| 291 // Memory is allocated for this member during initialization of this object | |
| 292 // because we want buffer to be passed into BufferedResourceLoader to be | |
| 293 // always non-null. And by initializing this member with a default size we can | |
| 294 // avoid creating zero-sized buffered if the first read has zero size. | |
| 295 std::vector<uint8_t> intermediate_read_buffer_; | |
| 296 | |
| 297 // The task runner of the render thread. | |
| 298 const scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_; | |
| 299 | |
| 300 // Protects |stop_signal_received_| and |read_op_|. | |
| 301 base::Lock lock_; | |
| 302 | |
| 303 // Whether we've been told to stop via Abort() or Stop(). | |
| 304 bool stop_signal_received_; | |
| 305 | |
| 306 // This variable is true when the user has requested the video to play at | |
| 307 // least once. | |
| 308 bool media_has_played_; | |
| 309 | |
| 310 // Buffering strategy as configured by SetBufferingStrategy(). | |
| 311 BufferingStrategy buffering_strategy_; | |
| 312 | |
| 313 // This variable holds the value of the preload attribute for the video | |
| 314 // element. | |
| 315 Preload preload_; | |
| 316 | |
| 317 // Bitrate of the content, 0 if unknown. | |
| 318 int bitrate_; | |
| 319 | |
| 320 // Current playback rate. | |
| 321 double playback_rate_; | |
| 322 | |
| 323 scoped_refptr<MediaLog> media_log_; | |
| 324 | |
| 325 // Host object to report buffered byte range changes to. | |
| 326 BufferedDataSourceHost* host_; | |
| 327 | |
| 328 DownloadingCB downloading_cb_; | |
| 329 | |
| 330 // The original URL of the first response. If the request is redirected to | |
| 331 // another URL it is the URL after redirected. If the response is generated in | |
| 332 // a Service Worker this URL is empty. BufferedDataSource checks the original | |
| 333 // URL of each successive response. If the origin URL of it is different from | |
| 334 // the original URL of the first response, it is treated as an error. | |
| 335 GURL response_original_url_; | |
| 336 | |
| 337 // Disallow rebinding WeakReference ownership to a different thread by keeping | |
| 338 // a persistent reference. This avoids problems with the thread-safety of | |
| 339 // reaching into this class from multiple threads to attain a WeakPtr. | |
| 340 base::WeakPtr<BufferedDataSource> weak_ptr_; | |
| 341 base::WeakPtrFactory<BufferedDataSource> weak_factory_; | |
| 342 | |
| 343 DISALLOW_COPY_AND_ASSIGN(BufferedDataSource); | |
| 344 }; | |
| 345 | |
| 346 } // namespace media | |
| 347 | |
| 348 #endif // MEDIA_BLINK_BUFFERED_DATA_SOURCE_H_ | |
| OLD | NEW |