| 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 |