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 // Delegate calls from WebCore::MediaPlayerPrivate to Chrome's video player. | |
6 // It contains Pipeline which is the actual media player pipeline, it glues | |
7 // the media player pipeline, data source, audio renderer and renderer. | |
8 // Pipeline would creates multiple threads and access some public methods | |
9 // of this class, so we need to be extra careful about concurrent access of | |
10 // methods and members. | |
11 // | |
12 // Other issues: | |
13 // During tear down of the whole browser or a tab, the DOM tree may not be | |
14 // destructed nicely, and there will be some dangling media threads trying to | |
15 // the main thread, so we need this class to listen to destruction event of the | |
16 // main thread and cleanup the media threads when the even is received. Also | |
17 // at destruction of this class we will need to unhook it from destruction event | |
18 // list of the main thread. | |
19 | |
20 #ifndef WEBKIT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_ | |
21 #define WEBKIT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_ | |
22 | |
23 #include <string> | |
24 | |
25 #include "base/memory/ref_counted.h" | |
26 #include "base/memory/scoped_ptr.h" | |
27 #include "base/memory/weak_ptr.h" | |
28 #include "base/threading/thread.h" | |
29 #include "cc/layers/video_frame_provider.h" | |
30 #include "googleurl/src/gurl.h" | |
31 #include "media/base/audio_renderer_sink.h" | |
32 #include "media/base/decryptor.h" | |
33 #include "media/base/media_keys.h" | |
34 #include "media/base/pipeline.h" | |
35 #include "media/base/text_track.h" | |
36 #include "media/filters/gpu_video_decoder.h" | |
37 #include "media/filters/skcanvas_video_renderer.h" | |
38 #include "skia/ext/platform_canvas.h" | |
39 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" | |
40 #include "third_party/WebKit/public/web/WebAudioSourceProvider.h" | |
41 #include "third_party/WebKit/public/web/WebMediaPlayer.h" | |
42 #include "third_party/WebKit/public/web/WebMediaPlayerClient.h" | |
43 #include "webkit/renderer/media/crypto/proxy_decryptor.h" | |
44 | |
45 class RenderAudioSourceProvider; | |
46 | |
47 namespace WebKit { | |
48 class WebFrame; | |
49 } | |
50 | |
51 namespace base { | |
52 class MessageLoopProxy; | |
53 } | |
54 | |
55 namespace media { | |
56 class ChunkDemuxer; | |
57 class FFmpegDemuxer; | |
58 class MediaLog; | |
59 } | |
60 | |
61 namespace webkit { | |
62 class WebLayerImpl; | |
63 } | |
64 | |
65 namespace webkit_media { | |
66 | |
67 class BufferedDataSource; | |
68 class MediaStreamClient; | |
69 class WebAudioSourceProviderImpl; | |
70 class WebMediaPlayerDelegate; | |
71 class WebMediaPlayerParams; | |
72 class WebTextTrackImpl; | |
73 | |
74 class WebMediaPlayerImpl | |
75 : public WebKit::WebMediaPlayer, | |
76 public cc::VideoFrameProvider, | |
77 public base::MessageLoop::DestructionObserver, | |
78 public base::SupportsWeakPtr<WebMediaPlayerImpl> { | |
79 public: | |
80 // Constructs a WebMediaPlayer implementation using Chromium's media stack. | |
81 // | |
82 // |delegate| may be null. | |
83 WebMediaPlayerImpl( | |
84 WebKit::WebFrame* frame, | |
85 WebKit::WebMediaPlayerClient* client, | |
86 base::WeakPtr<WebMediaPlayerDelegate> delegate, | |
87 const WebMediaPlayerParams& params); | |
88 virtual ~WebMediaPlayerImpl(); | |
89 | |
90 virtual void load(const WebKit::WebURL& url, CORSMode cors_mode); | |
91 virtual void load(const WebKit::WebURL& url, | |
92 WebKit::WebMediaSource* media_source, | |
93 CORSMode cors_mode); | |
94 | |
95 // Playback controls. | |
96 virtual void play(); | |
97 virtual void pause(); | |
98 virtual bool supportsFullscreen() const; | |
99 virtual bool supportsSave() const; | |
100 virtual void seek(double seconds); | |
101 virtual void setRate(double rate); | |
102 virtual void setVolume(double volume); | |
103 virtual void setPreload(WebKit::WebMediaPlayer::Preload preload); | |
104 virtual const WebKit::WebTimeRanges& buffered(); | |
105 virtual double maxTimeSeekable() const; | |
106 | |
107 // Methods for painting. | |
108 virtual void paint(WebKit::WebCanvas* canvas, | |
109 const WebKit::WebRect& rect, | |
110 unsigned char alpha); | |
111 | |
112 // True if the loaded media has a playable video/audio track. | |
113 virtual bool hasVideo() const; | |
114 virtual bool hasAudio() const; | |
115 | |
116 // Dimensions of the video. | |
117 virtual WebKit::WebSize naturalSize() const; | |
118 | |
119 // Getters of playback state. | |
120 virtual bool paused() const; | |
121 virtual bool seeking() const; | |
122 virtual double duration() const; | |
123 virtual double currentTime() const; | |
124 | |
125 // Internal states of loading and network. | |
126 // TODO(hclam): Ask the pipeline about the state rather than having reading | |
127 // them from members which would cause race conditions. | |
128 virtual WebKit::WebMediaPlayer::NetworkState networkState() const; | |
129 virtual WebKit::WebMediaPlayer::ReadyState readyState() const; | |
130 | |
131 virtual bool didLoadingProgress() const; | |
132 | |
133 virtual bool hasSingleSecurityOrigin() const; | |
134 virtual bool didPassCORSAccessCheck() const; | |
135 | |
136 virtual double mediaTimeForTimeValue(double timeValue) const; | |
137 | |
138 virtual unsigned decodedFrameCount() const; | |
139 virtual unsigned droppedFrameCount() const; | |
140 virtual unsigned audioDecodedByteCount() const; | |
141 virtual unsigned videoDecodedByteCount() const; | |
142 | |
143 // cc::VideoFrameProvider implementation. | |
144 virtual void SetVideoFrameProviderClient( | |
145 cc::VideoFrameProvider::Client* client) OVERRIDE; | |
146 virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE; | |
147 virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) | |
148 OVERRIDE; | |
149 | |
150 virtual bool copyVideoTextureToPlatformTexture( | |
151 WebKit::WebGraphicsContext3D* web_graphics_context, | |
152 unsigned int texture, | |
153 unsigned int level, | |
154 unsigned int internal_format, | |
155 unsigned int type, | |
156 bool premultiply_alpha, | |
157 bool flip_y); | |
158 | |
159 virtual WebKit::WebAudioSourceProvider* audioSourceProvider(); | |
160 | |
161 virtual MediaKeyException generateKeyRequest( | |
162 const WebKit::WebString& key_system, | |
163 const unsigned char* init_data, | |
164 unsigned init_data_length); | |
165 | |
166 virtual MediaKeyException addKey(const WebKit::WebString& key_system, | |
167 const unsigned char* key, | |
168 unsigned key_length, | |
169 const unsigned char* init_data, | |
170 unsigned init_data_length, | |
171 const WebKit::WebString& session_id); | |
172 | |
173 virtual MediaKeyException cancelKeyRequest( | |
174 const WebKit::WebString& key_system, | |
175 const WebKit::WebString& session_id); | |
176 | |
177 // As we are closing the tab or even the browser, |main_loop_| is destroyed | |
178 // even before this object gets destructed, so we need to know when | |
179 // |main_loop_| is being destroyed and we can stop posting repaint task | |
180 // to it. | |
181 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; | |
182 | |
183 void Repaint(); | |
184 | |
185 void OnPipelineSeek(media::PipelineStatus status); | |
186 void OnPipelineEnded(); | |
187 void OnPipelineError(media::PipelineStatus error); | |
188 void OnPipelineBufferingState( | |
189 media::Pipeline::BufferingState buffering_state); | |
190 void OnDemuxerOpened(scoped_ptr<WebKit::WebMediaSource> media_source); | |
191 void OnKeyAdded(const std::string& session_id); | |
192 void OnKeyError(const std::string& session_id, | |
193 media::MediaKeys::KeyError error_code, | |
194 int system_code); | |
195 void OnKeyMessage(const std::string& session_id, | |
196 const std::string& message, | |
197 const std::string& default_url); | |
198 void OnNeedKey(const std::string& type, | |
199 const std::string& session_id, | |
200 scoped_ptr<uint8[]> init_data, | |
201 int init_data_size); | |
202 scoped_ptr<media::TextTrack> OnTextTrack(media::TextKind kind, | |
203 const std::string& label, | |
204 const std::string& language); | |
205 void SetOpaque(bool); | |
206 | |
207 private: | |
208 // Contains common logic used across the different types loading. | |
209 void LoadSetup(const WebKit::WebURL& url); | |
210 | |
211 // Called after asynchronous initialization of a data source completed. | |
212 void DataSourceInitialized(const GURL& gurl, bool success); | |
213 | |
214 // Called when the data source is downloading or paused. | |
215 void NotifyDownloading(bool is_downloading); | |
216 | |
217 // Finishes starting the pipeline due to a call to load(). | |
218 // | |
219 // A non-null |media_source| will construct a Media Source pipeline. | |
220 void StartPipeline(WebKit::WebMediaSource* media_source); | |
221 | |
222 // Helpers that set the network/ready state and notifies the client if | |
223 // they've changed. | |
224 void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state); | |
225 void SetReadyState(WebKit::WebMediaPlayer::ReadyState state); | |
226 | |
227 // Destroy resources held. | |
228 void Destroy(); | |
229 | |
230 // Getter method to |client_|. | |
231 WebKit::WebMediaPlayerClient* GetClient(); | |
232 | |
233 // Lets V8 know that player uses extra resources not managed by V8. | |
234 void IncrementExternallyAllocatedMemory(); | |
235 | |
236 // Actually do the work for generateKeyRequest/addKey so they can easily | |
237 // report results to UMA. | |
238 MediaKeyException GenerateKeyRequestInternal( | |
239 const WebKit::WebString& key_system, | |
240 const unsigned char* init_data, | |
241 unsigned init_data_length); | |
242 MediaKeyException AddKeyInternal(const WebKit::WebString& key_system, | |
243 const unsigned char* key, | |
244 unsigned key_length, | |
245 const unsigned char* init_data, | |
246 unsigned init_data_length, | |
247 const WebKit::WebString& session_id); | |
248 MediaKeyException CancelKeyRequestInternal( | |
249 const WebKit::WebString& key_system, | |
250 const WebKit::WebString& session_id); | |
251 | |
252 // Gets the duration value reported by the pipeline. | |
253 double GetPipelineDuration() const; | |
254 | |
255 // Notifies WebKit of the duration change. | |
256 void OnDurationChange(); | |
257 | |
258 // Called by VideoRendererBase on its internal thread with the new frame to be | |
259 // painted. | |
260 void FrameReady(const scoped_refptr<media::VideoFrame>& frame); | |
261 | |
262 WebKit::WebFrame* frame_; | |
263 | |
264 // TODO(hclam): get rid of these members and read from the pipeline directly. | |
265 WebKit::WebMediaPlayer::NetworkState network_state_; | |
266 WebKit::WebMediaPlayer::ReadyState ready_state_; | |
267 | |
268 // Keep a list of buffered time ranges. | |
269 WebKit::WebTimeRanges buffered_; | |
270 | |
271 // Message loops for posting tasks on Chrome's main thread. Also used | |
272 // for DCHECKs so methods calls won't execute in the wrong thread. | |
273 const scoped_refptr<base::MessageLoopProxy> main_loop_; | |
274 | |
275 scoped_ptr<media::Pipeline> pipeline_; | |
276 scoped_refptr<base::MessageLoopProxy> media_loop_; | |
277 | |
278 // The currently selected key system. Empty string means that no key system | |
279 // has been selected. | |
280 WebKit::WebString current_key_system_; | |
281 | |
282 // Playback state. | |
283 // | |
284 // TODO(scherkus): we have these because Pipeline favours the simplicity of a | |
285 // single "playback rate" over worrying about paused/stopped etc... It forces | |
286 // all clients to manage the pause+playback rate externally, but is that | |
287 // really a bad thing? | |
288 // | |
289 // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want | |
290 // to hang the render thread during pause(), we record the time at the same | |
291 // time we pause and then return that value in currentTime(). Otherwise our | |
292 // clock can creep forward a little bit while the asynchronous | |
293 // SetPlaybackRate(0) is being executed. | |
294 bool paused_; | |
295 bool seeking_; | |
296 double playback_rate_; | |
297 base::TimeDelta paused_time_; | |
298 | |
299 // Seek gets pending if another seek is in progress. Only last pending seek | |
300 // will have effect. | |
301 bool pending_seek_; | |
302 double pending_seek_seconds_; | |
303 | |
304 WebKit::WebMediaPlayerClient* client_; | |
305 | |
306 base::WeakPtr<WebMediaPlayerDelegate> delegate_; | |
307 | |
308 MediaStreamClient* media_stream_client_; | |
309 | |
310 scoped_refptr<media::MediaLog> media_log_; | |
311 | |
312 // Since accelerated compositing status is only known after the first layout, | |
313 // we delay reporting it to UMA until that time. | |
314 bool accelerated_compositing_reported_; | |
315 | |
316 bool incremented_externally_allocated_memory_; | |
317 | |
318 // Factories for supporting GpuVideoDecoder. May be null. | |
319 scoped_refptr<media::GpuVideoDecoder::Factories> gpu_factories_; | |
320 | |
321 // Routes audio playback to either AudioRendererSink or WebAudio. | |
322 scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_; | |
323 | |
324 bool is_local_source_; | |
325 bool supports_save_; | |
326 | |
327 // The decryptor that manages decryption keys and decrypts encrypted frames. | |
328 scoped_ptr<ProxyDecryptor> decryptor_; | |
329 | |
330 bool starting_; | |
331 | |
332 // These two are mutually exclusive: | |
333 // |data_source_| is used for regular resource loads. | |
334 // |chunk_demuxer_| is used for Media Source resource loads. | |
335 // | |
336 // |demuxer_| will contain the appropriate demuxer based on which resource | |
337 // load strategy we're using. | |
338 scoped_ptr<BufferedDataSource> data_source_; | |
339 scoped_ptr<media::Demuxer> demuxer_; | |
340 media::ChunkDemuxer* chunk_demuxer_; | |
341 | |
342 // Temporary for EME v0.1. In the future the init data type should be passed | |
343 // through GenerateKeyRequest() directly from WebKit. | |
344 std::string init_data_type_; | |
345 | |
346 // Video frame rendering members. | |
347 // | |
348 // |lock_| protects |current_frame_| since new frames arrive on the video | |
349 // rendering thread, yet are accessed for rendering on either the main thread | |
350 // or compositing thread depending on whether accelerated compositing is used. | |
351 base::Lock lock_; | |
352 media::SkCanvasVideoRenderer skcanvas_video_renderer_; | |
353 scoped_refptr<media::VideoFrame> current_frame_; | |
354 bool pending_repaint_; | |
355 bool pending_size_change_; | |
356 | |
357 // The compositor layer for displaying the video content when using composited | |
358 // playback. | |
359 scoped_ptr<webkit::WebLayerImpl> video_weblayer_; | |
360 | |
361 // A pointer back to the compositor to inform it about state changes. This is | |
362 // not NULL while the compositor is actively using this webmediaplayer. | |
363 cc::VideoFrameProvider::Client* video_frame_provider_client_; | |
364 | |
365 // Text track objects get a unique index value when they're created. | |
366 int text_track_index_; | |
367 | |
368 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); | |
369 }; | |
370 | |
371 } // namespace webkit_media | |
372 | |
373 #endif // WEBKIT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_ | |
OLD | NEW |