Update V8 to version 4.7.56.
[chromium-blink-merge.git] / media / blink / buffered_resource_loader.h
blob6e466a37b0c80cea6b5c8802ab51e65d285c5f7a
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.
5 #ifndef MEDIA_BLINK_BUFFERED_RESOURCE_LOADER_H_
6 #define MEDIA_BLINK_BUFFERED_RESOURCE_LOADER_H_
8 #include <string>
10 #include "base/callback.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "media/base/media_export.h"
13 #include "media/base/seekable_buffer.h"
14 #include "media/blink/active_loader.h"
15 #include "third_party/WebKit/public/platform/WebURLLoader.h"
16 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
17 #include "third_party/WebKit/public/platform/WebURLRequest.h"
18 #include "third_party/WebKit/public/web/WebFrame.h"
19 #include "url/gurl.h"
21 namespace media {
22 class MediaLog;
23 class SeekableBuffer;
25 const int64 kPositionNotSpecified = -1;
27 // BufferedResourceLoader is single threaded and must be accessed on the
28 // render thread. It wraps a WebURLLoader and does in-memory buffering,
29 // pausing resource loading when the in-memory buffer is full and resuming
30 // resource loading when there is available capacity.
31 class MEDIA_EXPORT BufferedResourceLoader
32 : NON_EXPORTED_BASE(public blink::WebURLLoaderClient) {
33 public:
34 // kNeverDefer - Aggresively buffer; never defer loading while paused.
35 // kReadThenDefer - Request only enough data to fulfill read requests.
36 // kCapacityDefer - Try to keep amount of buffered data at capacity.
37 enum DeferStrategy {
38 kNeverDefer,
39 kReadThenDefer,
40 kCapacityDefer,
43 // Status codes for start/read operations on BufferedResourceLoader.
44 enum Status {
45 // Everything went as planned.
46 kOk,
48 // The operation failed, which may have been due to:
49 // - Page navigation
50 // - Server replied 4xx/5xx
51 // - The response was invalid
52 // - Connection was terminated
54 // At this point you should delete the loader.
55 kFailed,
57 // The loader will never be able to satisfy the read request. Please stop,
58 // delete, create a new loader, and try again.
59 kCacheMiss,
62 // Keep in sync with WebMediaPlayer::CORSMode.
63 enum CORSMode { kUnspecified, kAnonymous, kUseCredentials };
65 enum LoadingState {
66 kLoading, // Actively attempting to download data.
67 kLoadingDeferred, // Loading intentionally deferred.
68 kLoadingFinished, // Loading finished normally; no more data will arrive.
69 kLoadingFailed, // Loading finished abnormally; no more data will arrive.
72 // |url| - URL for the resource to be loaded.
73 // |cors_mode| - HTML media element's crossorigin attribute.
74 // |first_byte_position| - First byte to start loading from,
75 // |kPositionNotSpecified| for not specified.
76 // |last_byte_position| - Last byte to be loaded,
77 // |kPositionNotSpecified| for not specified.
78 // |strategy| is the initial loading strategy to use.
79 // |bitrate| is the bitrate of the media, 0 if unknown.
80 // |playback_rate| is the current playback rate of the media.
81 BufferedResourceLoader(
82 const GURL& url,
83 CORSMode cors_mode,
84 int64 first_byte_position,
85 int64 last_byte_position,
86 DeferStrategy strategy,
87 int bitrate,
88 double playback_rate,
89 MediaLog* media_log);
90 virtual ~BufferedResourceLoader();
92 // Start the resource loading with the specified URL and range.
94 // |loading_cb| is executed when the loading state has changed.
95 // |progress_cb| is executed when additional data has arrived.
96 typedef base::Callback<void(Status)> StartCB;
97 typedef base::Callback<void(LoadingState)> LoadingStateChangedCB;
98 typedef base::Callback<void(int64)> ProgressCB;
99 void Start(const StartCB& start_cb,
100 const LoadingStateChangedCB& loading_cb,
101 const ProgressCB& progress_cb,
102 blink::WebFrame* frame);
104 // Stops everything associated with this loader, including active URL loads
105 // and pending callbacks.
107 // It is safe to delete a BufferedResourceLoader after calling Stop().
108 void Stop();
110 // Copies |read_size| bytes from |position| into |buffer|, executing |read_cb|
111 // when the operation has completed.
113 // The callback will contain the number of bytes read iff the status is kOk,
114 // zero otherwise.
116 // If necessary will temporarily increase forward capacity of buffer to
117 // accomodate an unusually large read.
118 typedef base::Callback<void(Status, int)> ReadCB;
119 void Read(int64 position, int read_size,
120 uint8* buffer, const ReadCB& read_cb);
122 // Gets the content length in bytes of the instance after this loader has been
123 // started. If this value is |kPositionNotSpecified|, then content length is
124 // unknown.
125 int64 content_length();
127 // Gets the original size of the file requested. If this value is
128 // |kPositionNotSpecified|, then the size is unknown.
129 int64 instance_size();
131 // Returns true if the server supports byte range requests.
132 bool range_supported();
134 // blink::WebURLLoaderClient implementation.
135 virtual void willSendRequest(
136 blink::WebURLLoader* loader,
137 blink::WebURLRequest& newRequest,
138 const blink::WebURLResponse& redirectResponse);
139 virtual void didSendData(
140 blink::WebURLLoader* loader,
141 unsigned long long bytesSent,
142 unsigned long long totalBytesToBeSent);
143 virtual void didReceiveResponse(
144 blink::WebURLLoader* loader,
145 const blink::WebURLResponse& response);
146 virtual void didDownloadData(
147 blink::WebURLLoader* loader,
148 int data_length,
149 int encoded_data_length);
150 virtual void didReceiveData(
151 blink::WebURLLoader* loader,
152 const char* data,
153 int data_length,
154 int encoded_data_length);
155 virtual void didReceiveCachedMetadata(
156 blink::WebURLLoader* loader,
157 const char* data, int dataLength);
158 virtual void didFinishLoading(
159 blink::WebURLLoader* loader,
160 double finishTime,
161 int64_t total_encoded_data_length);
162 virtual void didFail(
163 blink::WebURLLoader* loader,
164 const blink::WebURLError&);
166 // Returns true if the media resource has a single origin, false otherwise.
167 // Only valid to call after Start() has completed.
168 bool HasSingleOrigin() const;
170 // Returns true if the media resource passed a CORS access control check.
171 // Only valid to call after Start() has completed.
172 bool DidPassCORSAccessCheck() const;
174 // Sets the defer strategy to the given value unless it seems unwise.
175 // Specifically downgrade kNeverDefer to kCapacityDefer if we know the
176 // current response will not be used to satisfy future requests (the cache
177 // won't help us).
178 void UpdateDeferStrategy(DeferStrategy strategy);
180 // Sets the playback rate to the given value and updates buffer window
181 // accordingly.
182 void SetPlaybackRate(double playback_rate);
184 // Sets the bitrate to the given value and updates buffer window
185 // accordingly.
186 void SetBitrate(int bitrate);
188 // Return the |first_byte_position| passed into the ctor.
189 int64 first_byte_position() const;
191 // Parse a Content-Range header into its component pieces and return true if
192 // each of the expected elements was found & parsed correctly.
193 // |*instance_size| may be set to kPositionNotSpecified if the range ends in
194 // "/*".
195 // NOTE: only public for testing! This is an implementation detail of
196 // VerifyPartialResponse (a private method).
197 static bool ParseContentRange(
198 const std::string& content_range_str, int64* first_byte_position,
199 int64* last_byte_position, int64* instance_size);
201 // Cancels and closes any outstanding deferred ActiveLoader instances. Does
202 // not report a failed state, so subsequent read calls to cache may still
203 // complete okay. If the ActiveLoader is not deferred it will be canceled once
204 // it is unless playback starts before then (as determined by the reported
205 // playback rate).
206 void CancelUponDeferral();
208 // Returns the original URL of the response. If the request is redirected to
209 // another URL it is the URL after redirected. If the response is generated in
210 // a Service Worker it is empty.
211 const GURL response_original_url() const { return response_original_url_; }
213 private:
214 friend class BufferedDataSourceTest;
215 friend class BufferedResourceLoaderTest;
216 friend class MockBufferedDataSource;
218 // Updates the |buffer_|'s forward and backward capacities.
219 void UpdateBufferWindow();
221 // Updates deferring behavior based on current buffering scheme.
222 void UpdateDeferBehavior();
224 // Sets |active_loader_|'s defer state and fires |loading_cb_| if the state
225 // changed.
226 void SetDeferred(bool deferred);
228 // Returns true if we should defer resource loading based on the current
229 // buffering scheme.
230 bool ShouldDefer() const;
232 // Returns true if the current read request can be fulfilled by what is in
233 // the buffer.
234 bool CanFulfillRead() const;
236 // Returns true if the current read request will be fulfilled in the future.
237 bool WillFulfillRead() const;
239 // Method that does the actual read and calls the |read_cb_|, assuming the
240 // request range is in |buffer_|.
241 void ReadInternal();
243 // If we have made a range request, verify the response from the server.
244 bool VerifyPartialResponse(const blink::WebURLResponse& response);
246 // Done with read. Invokes the read callback and reset parameters for the
247 // read request.
248 void DoneRead(Status status, int bytes_read);
250 // Done with start. Invokes the start callback and reset it.
251 void DoneStart(Status status);
253 bool HasPendingRead() { return !read_cb_.is_null(); }
255 // Helper function that returns true if a range request was specified.
256 bool IsRangeRequest() const;
258 // Log everything interesting to |media_log_|.
259 void Log();
261 // A sliding window of buffer.
262 SeekableBuffer buffer_;
264 // Keeps track of an active WebURLLoader and associated state.
265 scoped_ptr<ActiveLoader> active_loader_;
267 // Tracks if |active_loader_| failed. If so, then all calls to Read() will
268 // fail.
269 bool loader_failed_;
271 // Current buffering algorithm in place for resource loading.
272 DeferStrategy defer_strategy_;
274 // True if the currently-reading response might be used to satisfy a future
275 // request from the cache.
276 bool might_be_reused_from_cache_in_future_;
278 // True if Range header is supported.
279 bool range_supported_;
281 // Forward capacity to reset to after an extension.
282 int saved_forward_capacity_;
284 GURL url_;
285 CORSMode cors_mode_;
286 const int64 first_byte_position_;
287 const int64 last_byte_position_;
288 bool single_origin_;
290 // Executed whenever the state of resource loading has changed.
291 LoadingStateChangedCB loading_cb_;
293 // Executed whenever additional data has been downloaded and reports the
294 // zero-indexed file offset of the furthest buffered byte.
295 ProgressCB progress_cb_;
297 // Members used during request start.
298 StartCB start_cb_;
299 int64 offset_;
300 int64 content_length_;
301 int64 instance_size_;
303 // Members used during a read operation. They should be reset after each
304 // read has completed or failed.
305 ReadCB read_cb_;
306 int64 read_position_;
307 int read_size_;
308 uint8* read_buffer_;
310 // Offsets of the requested first byte and last byte in |buffer_|. They are
311 // written by Read().
312 int first_offset_;
313 int last_offset_;
315 // Injected WebURLLoader instance for testing purposes.
316 scoped_ptr<blink::WebURLLoader> test_loader_;
318 // Bitrate of the media. Set to 0 if unknown.
319 int bitrate_;
321 // Playback rate of the media.
322 double playback_rate_;
324 GURL response_original_url_;
326 scoped_refptr<MediaLog> media_log_;
328 bool cancel_upon_deferral_;
330 DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader);
333 } // namespace media
335 #endif // MEDIA_BLINK_BUFFERED_RESOURCE_LOADER_H_