OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 WEBKIT_GLUE_MEDIA_BUFFERED_DATA_SOURCE_H_ | |
6 #define WEBKIT_GLUE_MEDIA_BUFFERED_DATA_SOURCE_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/callback.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/synchronization/lock.h" | |
13 #include "media/base/filter_factories.h" | |
14 #include "media/base/filters.h" | |
15 #include "webkit/glue/media/buffered_resource_loader.h" | |
16 | |
17 namespace media { | |
18 class MediaLog; | |
19 } | |
20 | |
21 namespace webkit_glue { | |
22 | |
23 // This class may be created on any thread, and is callable from the render | |
24 // thread as well as media-specific threads. | |
25 class BufferedDataSource : public WebDataSource { | |
26 public: | |
27 // Creates a DataSourceFactory for building BufferedDataSource objects. | |
28 static media::DataSourceFactory* CreateFactory( | |
29 MessageLoop* render_loop, | |
30 WebKit::WebFrame* frame, | |
31 media::MediaLog* media_log, | |
32 const WebDataSourceBuildObserverHack& build_observer); | |
33 | |
34 BufferedDataSource(MessageLoop* render_loop, | |
35 WebKit::WebFrame* frame, | |
36 media::MediaLog* media_log); | |
37 | |
38 virtual ~BufferedDataSource(); | |
39 | |
40 // media::Filter implementation. | |
41 virtual void set_host(media::FilterHost* host); | |
42 virtual void Stop(const base::Closure& callback); | |
43 virtual void SetPlaybackRate(float playback_rate); | |
44 | |
45 // media::DataSource implementation. | |
46 // Called from demuxer thread. | |
47 virtual void Read(int64 position, size_t size, | |
48 uint8* data, | |
49 const media::DataSource::ReadCallback& read_callback); | |
50 virtual bool GetSize(int64* size_out); | |
51 virtual bool IsStreaming(); | |
52 virtual void SetPreload(media::Preload preload); | |
53 virtual void SetBitrate(int bitrate); | |
54 | |
55 // webkit_glue::WebDataSource implementation. | |
56 virtual void Initialize(const std::string& url, | |
57 const media::PipelineStatusCB& callback); | |
58 virtual void CancelInitialize(); | |
59 virtual bool HasSingleOrigin(); | |
60 virtual void Abort(); | |
61 | |
62 protected: | |
63 // A factory method to create a BufferedResourceLoader based on the read | |
64 // parameters. We can override this file to object a mock | |
65 // BufferedResourceLoader for testing. | |
66 virtual BufferedResourceLoader* CreateResourceLoader( | |
67 int64 first_byte_position, int64 last_byte_position); | |
68 | |
69 private: | |
70 friend class BufferedDataSourceTest2; | |
71 | |
72 // Posted to perform initialization on render thread and start resource | |
73 // loading. | |
74 void InitializeTask(); | |
75 | |
76 // Task posted to perform actual reading on the render thread. | |
77 void ReadTask(int64 position, int read_size, uint8* read_buffer); | |
78 | |
79 // Task posted when Stop() is called. Stops |watch_dog_timer_| and | |
80 // |loader_|, reset Read() variables, and set |stopped_on_render_loop_| | |
81 // to signal any remaining tasks to stop. | |
82 void CleanupTask(); | |
83 | |
84 // Restart resource loading on render thread. | |
85 void RestartLoadingTask(); | |
86 | |
87 // This task uses the current playback rate with the previous playback rate | |
88 // to determine whether we are going from pause to play and play to pause, | |
89 // and signals the buffered resource loader accordingly. | |
90 void SetPlaybackRateTask(float playback_rate); | |
91 | |
92 // This task saves the preload value for the media. | |
93 void SetPreloadTask(media::Preload preload); | |
94 | |
95 // Tells |loader_| the bitrate of the media. | |
96 void SetBitrateTask(int bitrate); | |
97 | |
98 // Decides which DeferStrategy to used based on the current state of the | |
99 // BufferedDataSource. | |
100 BufferedResourceLoader::DeferStrategy ChooseDeferStrategy(); | |
101 | |
102 // The method that performs actual read. This method can only be executed on | |
103 // the render thread. | |
104 void ReadInternal(); | |
105 | |
106 // Calls |read_callback_| and reset all read parameters. | |
107 void DoneRead_Locked(int error); | |
108 | |
109 // Calls |initialize_cb_| and reset it. | |
110 void DoneInitialization_Locked(media::PipelineStatus status); | |
111 | |
112 // Callback method for |loader_| if URL for the resource requested is using | |
113 // HTTP protocol. This method is called when response for initial request is | |
114 // received. | |
115 void HttpInitialStartCallback(int error); | |
116 | |
117 // Callback method for |loader_| if URL for the resource requested is using | |
118 // a non-HTTP protocol, e.g. local files. This method is called when response | |
119 // for initial request is received. | |
120 void NonHttpInitialStartCallback(int error); | |
121 | |
122 // Callback method to be passed to BufferedResourceLoader during range | |
123 // request. Once a resource request has started, this method will be called | |
124 // with the error code. This method will be executed on the thread | |
125 // BufferedResourceLoader lives, i.e. render thread. | |
126 void PartialReadStartCallback(int error); | |
127 | |
128 // Callback method for making a read request to BufferedResourceLoader. | |
129 // If data arrives or the request has failed, this method is called with | |
130 // the error code or the number of bytes read. | |
131 void ReadCallback(int error); | |
132 | |
133 // Callback method when a network event is received. | |
134 void NetworkEventCallback(); | |
135 | |
136 void UpdateHostState_Locked(); | |
137 | |
138 // URL of the resource requested. | |
139 GURL url_; | |
140 | |
141 // Members for total bytes of the requested object. It is written once on | |
142 // render thread but may be read from any thread. However reading of this | |
143 // member is guaranteed to happen after it is first written, so we don't | |
144 // need to protect it. | |
145 int64 total_bytes_; | |
146 int64 buffered_bytes_; | |
147 | |
148 // True if this data source is considered loaded. | |
149 bool loaded_; | |
150 | |
151 // This value will be true if this data source can only support streaming. | |
152 // i.e. range request is not supported. | |
153 bool streaming_; | |
154 | |
155 // A webframe for loading. | |
156 WebKit::WebFrame* frame_; | |
157 | |
158 // A resource loader for the media resource. | |
159 scoped_refptr<BufferedResourceLoader> loader_; | |
160 | |
161 // True if |loader| is downloading data. | |
162 bool is_downloading_data_; | |
163 | |
164 // Callback method from the pipeline for initialization. | |
165 media::PipelineStatusCB initialize_cb_; | |
166 | |
167 // Read parameters received from the Read() method call. | |
168 media::DataSource::ReadCallback read_callback_; | |
169 int64 read_position_; | |
170 int read_size_; | |
171 uint8* read_buffer_; | |
172 | |
173 // This buffer is intermediate, we use it for BufferedResourceLoader to write | |
174 // to. And when read in BufferedResourceLoader is done, we copy data from | |
175 // this buffer to |read_buffer_|. The reason for an additional copy is that | |
176 // we don't own |read_buffer_|. But since the read operation is asynchronous, | |
177 // |read_buffer| can be destroyed at any time, so we only copy into | |
178 // |read_buffer| in the final step when it is safe. | |
179 // Memory is allocated for this member during initialization of this object | |
180 // because we want buffer to be passed into BufferedResourceLoader to be | |
181 // always non-null. And by initializing this member with a default size we can | |
182 // avoid creating zero-sized buffered if the first read has zero size. | |
183 scoped_array<uint8> intermediate_read_buffer_; | |
184 int intermediate_read_buffer_size_; | |
185 | |
186 // The message loop of the render thread. | |
187 MessageLoop* render_loop_; | |
188 | |
189 // Protects |stop_signal_received_|, |stopped_on_render_loop_| and | |
190 // |initialize_cb_|. | |
191 base::Lock lock_; | |
192 | |
193 // Stop signal to suppressing activities. This variable is set on the pipeline | |
194 // thread and read from the render thread. | |
195 bool stop_signal_received_; | |
196 | |
197 // This variable is set by CleanupTask() that indicates this object is stopped | |
198 // on the render thread and work should no longer progress. | |
199 bool stopped_on_render_loop_; | |
200 | |
201 // This variable is true when we are in a paused state and false when we | |
202 // are in a playing state. | |
203 bool media_is_paused_; | |
204 | |
205 // This variable is true when the user has requested the video to play at | |
206 // least once. | |
207 bool media_has_played_; | |
208 | |
209 // This variable holds the value of the preload attribute for the video | |
210 // element. | |
211 media::Preload preload_; | |
212 | |
213 // Keeps track of whether we used a Range header in the initialization | |
214 // request. | |
215 bool using_range_request_; | |
216 | |
217 // Number of cache miss retries left. | |
218 int cache_miss_retries_left_; | |
219 | |
220 // Bitrate of the content, 0 if unknown. | |
221 int bitrate_; | |
222 | |
223 // Current playback rate. | |
224 float playback_rate_; | |
225 | |
226 scoped_refptr<media::MediaLog> media_log_; | |
227 | |
228 DISALLOW_COPY_AND_ASSIGN(BufferedDataSource); | |
229 }; | |
230 | |
231 } // namespace webkit_glue | |
232 | |
233 #endif // WEBKIT_GLUE_MEDIA_BUFFERED_DATA_SOURCE_H_ | |
OLD | NEW |