• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 CONTENT_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_H_
6 #define CONTENT_RENDERER_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 "content/common/content_export.h"
14 #include "content/renderer/media/buffered_resource_loader.h"
15 #include "content/renderer/media/preload.h"
16 #include "media/base/data_source.h"
17 #include "media/base/ranges.h"
18 #include "url/gurl.h"
19 
20 namespace base {
21 class MessageLoopProxy;
22 }
23 
24 namespace media {
25 class MediaLog;
26 }
27 
28 namespace content {
29 
30 // A data source capable of loading URLs and buffering the data using an
31 // in-memory sliding window.
32 //
33 // BufferedDataSource must be created and initialized on the render thread
34 // before being passed to other threads. It may be deleted on any thread.
35 class CONTENT_EXPORT BufferedDataSource : public media::DataSource {
36  public:
37   typedef base::Callback<void(bool)> DownloadingCB;
38 
39   // |downloading_cb| will be called whenever the downloading/paused state of
40   // the source changes.
41   BufferedDataSource(const scoped_refptr<base::MessageLoopProxy>& render_loop,
42                      blink::WebFrame* frame,
43                      media::MediaLog* media_log,
44                      const DownloadingCB& downloading_cb);
45   virtual ~BufferedDataSource();
46 
47   // Initialize this object using |url| and |cors_mode|, executing |init_cb|
48   // with the result of initialization when it has completed.
49   //
50   // Method called on the render thread.
51   typedef base::Callback<void(bool)> InitializeCB;
52   void Initialize(
53       const GURL& url,
54       BufferedResourceLoader::CORSMode cors_mode,
55       const InitializeCB& init_cb);
56 
57   // Adjusts the buffering algorithm based on the given preload value.
58   void SetPreload(Preload preload);
59 
60   // Returns true if the media resource has a single origin, false otherwise.
61   // Only valid to call after Initialize() has completed.
62   //
63   // Method called on the render thread.
64   bool HasSingleOrigin();
65 
66   // Returns true if the media resource passed a CORS access control check.
67   bool DidPassCORSAccessCheck() const;
68 
69   // Cancels initialization, any pending loaders, and any pending read calls
70   // from the demuxer. The caller is expected to release its reference to this
71   // object and never call it again.
72   //
73   // Method called on the render thread.
74   void Abort();
75 
76   // Notifies changes in playback state for controlling media buffering
77   // behavior.
78   void MediaPlaybackRateChanged(float playback_rate);
79   void MediaIsPlaying();
80   void MediaIsPaused();
81 
82   // media::DataSource implementation.
83   // Called from demuxer thread.
84   virtual void set_host(media::DataSourceHost* host) OVERRIDE;
85   virtual void Stop(const base::Closure& closure) OVERRIDE;
86 
87   virtual void Read(int64 position, int size, uint8* data,
88                     const media::DataSource::ReadCB& read_cb) OVERRIDE;
89   virtual bool GetSize(int64* size_out) OVERRIDE;
90   virtual bool IsStreaming() OVERRIDE;
91   virtual void SetBitrate(int bitrate) OVERRIDE;
92 
93  protected:
94   // A factory method to create a BufferedResourceLoader based on the read
95   // parameters. We can override this file to object a mock
96   // BufferedResourceLoader for testing.
97   virtual BufferedResourceLoader* CreateResourceLoader(
98       int64 first_byte_position, int64 last_byte_position);
99 
100  private:
101   friend class BufferedDataSourceTest;
102 
103   // Task posted to perform actual reading on the render thread.
104   void ReadTask();
105 
106   // Cancels oustanding callbacks and sets |stop_signal_received_|. Safe to call
107   // from any thread.
108   void StopInternal_Locked();
109 
110   // Stops |loader_| if present. Used by Abort() and Stop().
111   void StopLoader();
112 
113   // Tells |loader_| the bitrate of the media.
114   void SetBitrateTask(int bitrate);
115 
116   // The method that performs actual read. This method can only be executed on
117   // the render thread.
118   void ReadInternal();
119 
120   // BufferedResourceLoader::Start() callback for initial load.
121   void StartCallback(BufferedResourceLoader::Status status);
122 
123   // BufferedResourceLoader::Start() callback for subsequent loads (i.e.,
124   // when accessing ranges that are outside initial buffered region).
125   void PartialReadStartCallback(BufferedResourceLoader::Status status);
126 
127   // BufferedResourceLoader callbacks.
128   void ReadCallback(BufferedResourceLoader::Status status, int bytes_read);
129   void LoadingStateChangedCallback(BufferedResourceLoader::LoadingState state);
130   void ProgressCallback(int64 position);
131 
132   // Report a buffered byte range [start,end] or queue it for later
133   // reporting if set_host() hasn't been called yet.
134   void ReportOrQueueBufferedBytes(int64 start, int64 end);
135 
136   void UpdateHostState_Locked();
137 
138   // Update |loader_|'s deferring strategy in response to a play/pause, or
139   // change in playback rate.
140   void UpdateDeferStrategy(bool paused);
141 
142   base::WeakPtr<BufferedDataSource> weak_this_;
143 
144   // URL of the resource requested.
145   GURL url_;
146   // crossorigin attribute on the corresponding HTML media element, if any.
147   BufferedResourceLoader::CORSMode cors_mode_;
148 
149   // The total size of the resource. Set during StartCallback() if the size is
150   // known, otherwise it will remain kPositionNotSpecified until the size is
151   // determined by reaching EOF.
152   int64 total_bytes_;
153 
154   // Some resources are assumed to be fully buffered (i.e., file://) so we don't
155   // need to report what |loader_| has buffered.
156   bool assume_fully_buffered_;
157 
158   // This value will be true if this data source can only support streaming.
159   // i.e. range request is not supported.
160   bool streaming_;
161 
162   // A webframe for loading.
163   blink::WebFrame* frame_;
164 
165   // A resource loader for the media resource.
166   scoped_ptr<BufferedResourceLoader> loader_;
167 
168   // Callback method from the pipeline for initialization.
169   InitializeCB init_cb_;
170 
171   // Read parameters received from the Read() method call. Must be accessed
172   // under |lock_|.
173   class ReadOperation;
174   scoped_ptr<ReadOperation> read_op_;
175 
176   // This buffer is intermediate, we use it for BufferedResourceLoader to write
177   // to. And when read in BufferedResourceLoader is done, we copy data from
178   // this buffer to |read_buffer_|. The reason for an additional copy is that
179   // we don't own |read_buffer_|. But since the read operation is asynchronous,
180   // |read_buffer| can be destroyed at any time, so we only copy into
181   // |read_buffer| in the final step when it is safe.
182   // Memory is allocated for this member during initialization of this object
183   // because we want buffer to be passed into BufferedResourceLoader to be
184   // always non-null. And by initializing this member with a default size we can
185   // avoid creating zero-sized buffered if the first read has zero size.
186   scoped_ptr<uint8[]> intermediate_read_buffer_;
187   int intermediate_read_buffer_size_;
188 
189   // The message loop of the render thread.
190   const scoped_refptr<base::MessageLoopProxy> render_loop_;
191 
192   // Protects |stop_signal_received_| and |read_op_|.
193   base::Lock lock_;
194 
195   // Whether we've been told to stop via Abort() or Stop().
196   bool stop_signal_received_;
197 
198   // This variable is true when the user has requested the video to play at
199   // least once.
200   bool media_has_played_;
201 
202   // This variable holds the value of the preload attribute for the video
203   // element.
204   Preload preload_;
205 
206   // Bitrate of the content, 0 if unknown.
207   int bitrate_;
208 
209   // Current playback rate.
210   float playback_rate_;
211 
212   // Buffered byte ranges awaiting set_host() being called to report to host().
213   media::Ranges<int64> queued_buffered_byte_ranges_;
214 
215   scoped_refptr<media::MediaLog> media_log_;
216 
217   DownloadingCB downloading_cb_;
218 
219   base::WeakPtrFactory<BufferedDataSource> weak_factory_;
220 
221   DISALLOW_COPY_AND_ASSIGN(BufferedDataSource);
222 };
223 
224 }  // namespace content
225 
226 #endif  // CONTENT_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_H_
227