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 CONTENT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_
6 #define CONTENT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_
11 #include "base/basictypes.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/threading/thread.h"
16 #include "content/renderer/media/buffered_data_source_host_impl.h"
17 #include "content/renderer/media/crypto/proxy_decryptor.h"
18 #include "content/renderer/media/video_frame_compositor.h"
19 #include "media/base/audio_renderer_sink.h"
20 #include "media/base/decryptor.h"
21 // TODO(xhwang): Remove when we remove prefixed EME implementation.
22 #include "media/base/media_keys.h"
23 #include "media/base/pipeline.h"
24 #include "media/base/text_track.h"
25 #include "media/filters/skcanvas_video_renderer.h"
26 #include "skia/ext/platform_canvas.h"
27 #include "third_party/WebKit/public/platform/WebAudioSourceProvider.h"
28 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
29 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
30 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
33 class RenderAudioSourceProvider;
36 class WebContentDecryptionModule;
41 class MessageLoopProxy;
46 class GpuVideoAcceleratorFactories;
55 class BufferedDataSource;
56 class VideoFrameCompositor;
57 class WebAudioSourceProviderImpl;
58 class WebContentDecryptionModuleImpl;
59 class WebMediaPlayerDelegate;
60 class WebMediaPlayerParams;
61 class WebTextTrackImpl;
63 // The canonical implementation of blink::WebMediaPlayer that's backed by
64 // media::Pipeline. Handles normal resource loading, Media Source, and
66 class WebMediaPlayerImpl
67 : public blink::WebMediaPlayer,
68 public base::SupportsWeakPtr<WebMediaPlayerImpl> {
70 // Constructs a WebMediaPlayer implementation using Chromium's media stack.
71 // |delegate| may be null.
72 WebMediaPlayerImpl(blink::WebLocalFrame* frame,
73 blink::WebMediaPlayerClient* client,
74 base::WeakPtr<WebMediaPlayerDelegate> delegate,
75 const WebMediaPlayerParams& params);
76 virtual ~WebMediaPlayerImpl();
78 virtual void load(LoadType load_type,
79 const blink::WebURL& url,
85 virtual bool supportsSave() const;
86 virtual void seek(double seconds);
87 virtual void setRate(double rate);
88 virtual void setVolume(double volume);
89 virtual void setPreload(blink::WebMediaPlayer::Preload preload);
90 virtual const blink::WebTimeRanges& buffered();
91 virtual double maxTimeSeekable() const;
93 // Methods for painting.
94 virtual void paint(blink::WebCanvas* canvas,
95 const blink::WebRect& rect,
98 // True if the loaded media has a playable video/audio track.
99 virtual bool hasVideo() const;
100 virtual bool hasAudio() const;
102 // Dimensions of the video.
103 virtual blink::WebSize naturalSize() const;
105 // Getters of playback state.
106 virtual bool paused() const;
107 virtual bool seeking() const;
108 virtual double duration() const;
109 virtual double timelineOffset() const;
110 virtual double currentTime() const;
112 // Internal states of loading and network.
113 // TODO(hclam): Ask the pipeline about the state rather than having reading
114 // them from members which would cause race conditions.
115 virtual blink::WebMediaPlayer::NetworkState networkState() const;
116 virtual blink::WebMediaPlayer::ReadyState readyState() const;
118 // TODO(sandersd): Change this to non-const in blink::WebMediaPlayer.
119 // http://crbug.com/360251
120 virtual bool didLoadingProgress() const;
122 virtual bool hasSingleSecurityOrigin() const;
123 virtual bool didPassCORSAccessCheck() const;
125 virtual double mediaTimeForTimeValue(double timeValue) const;
127 virtual unsigned decodedFrameCount() const;
128 virtual unsigned droppedFrameCount() const;
129 virtual unsigned audioDecodedByteCount() const;
130 virtual unsigned videoDecodedByteCount() const;
132 virtual bool copyVideoTextureToPlatformTexture(
133 blink::WebGraphicsContext3D* web_graphics_context,
134 unsigned int texture,
136 unsigned int internal_format,
138 bool premultiply_alpha,
141 virtual blink::WebAudioSourceProvider* audioSourceProvider();
143 virtual MediaKeyException generateKeyRequest(
144 const blink::WebString& key_system,
145 const unsigned char* init_data,
146 unsigned init_data_length);
148 virtual MediaKeyException addKey(const blink::WebString& key_system,
149 const unsigned char* key,
151 const unsigned char* init_data,
152 unsigned init_data_length,
153 const blink::WebString& session_id);
155 virtual MediaKeyException cancelKeyRequest(
156 const blink::WebString& key_system,
157 const blink::WebString& session_id);
159 virtual void setContentDecryptionModule(
160 blink::WebContentDecryptionModule* cdm);
162 // Notifies blink that the entire media element region has been invalidated.
163 // This path is slower than notifying the compositor directly as it performs
164 // more work and can trigger layouts. It should only be used in two cases:
165 // 1) Major state changes (e.g., first frame available, run time error
167 // 2) Compositing not available
168 void InvalidateOnMainThread();
170 void OnPipelineSeek(media::PipelineStatus status);
171 void OnPipelineEnded();
172 void OnPipelineError(media::PipelineStatus error);
173 void OnPipelineMetadata(media::PipelineMetadata metadata);
174 void OnPipelinePrerollCompleted();
175 void OnDemuxerOpened();
176 void OnKeyAdded(const std::string& session_id);
177 void OnKeyError(const std::string& session_id,
178 media::MediaKeys::KeyError error_code,
180 void OnKeyMessage(const std::string& session_id,
181 const std::vector<uint8>& message,
182 const std::string& default_url);
183 void OnNeedKey(const std::string& type,
184 const std::vector<uint8>& init_data);
185 void OnAddTextTrack(const media::TextTrackConfig& config,
186 const media::AddTextTrackDoneCB& done_cb);
189 // Called after |defer_load_cb_| has decided to allow the load. If
190 // |defer_load_cb_| is null this is called immediately.
191 void DoLoad(LoadType load_type,
192 const blink::WebURL& url,
195 // Called after asynchronous initialization of a data source completed.
196 void DataSourceInitialized(const GURL& gurl, bool success);
198 // Called when the data source is downloading or paused.
199 void NotifyDownloading(bool is_downloading);
201 // Finishes starting the pipeline due to a call to load().
202 void StartPipeline();
204 // Helpers that set the network/ready state and notifies the client if
206 void SetNetworkState(blink::WebMediaPlayer::NetworkState state);
207 void SetReadyState(blink::WebMediaPlayer::ReadyState state);
209 // Lets V8 know that player uses extra resources not managed by V8.
210 void IncrementExternallyAllocatedMemory();
212 // Actually do the work for generateKeyRequest/addKey so they can easily
213 // report results to UMA.
214 MediaKeyException GenerateKeyRequestInternal(const std::string& key_system,
215 const unsigned char* init_data,
216 unsigned init_data_length);
217 MediaKeyException AddKeyInternal(const std::string& key_system,
218 const unsigned char* key,
220 const unsigned char* init_data,
221 unsigned init_data_length,
222 const std::string& session_id);
223 MediaKeyException CancelKeyRequestInternal(const std::string& key_system,
224 const std::string& session_id);
226 // Gets the duration value reported by the pipeline.
227 double GetPipelineDuration() const;
229 // Callbacks from |pipeline_| that are forwarded to |client_|.
230 void OnDurationChanged();
231 void OnNaturalSizeChanged(gfx::Size size);
232 void OnOpacityChanged(bool opaque);
234 // Called by VideoRendererImpl on its internal thread with the new frame to be
236 void FrameReady(const scoped_refptr<media::VideoFrame>& frame);
238 // Requests that this object notifies when a decryptor is ready through the
239 // |decryptor_ready_cb| provided.
240 // If |decryptor_ready_cb| is null, the existing callback will be fired with
241 // NULL immediately and reset.
242 void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
244 // Returns the current video frame from |compositor_|. Blocks until the
245 // compositor can return the frame.
246 scoped_refptr<media::VideoFrame> GetCurrentFrameFromCompositor();
248 blink::WebLocalFrame* frame_;
250 // TODO(hclam): get rid of these members and read from the pipeline directly.
251 blink::WebMediaPlayer::NetworkState network_state_;
252 blink::WebMediaPlayer::ReadyState ready_state_;
254 // Message loops for posting tasks on Chrome's main thread. Also used
255 // for DCHECKs so methods calls won't execute in the wrong thread.
256 const scoped_refptr<base::MessageLoopProxy> main_loop_;
258 scoped_refptr<base::MessageLoopProxy> media_loop_;
259 scoped_refptr<media::MediaLog> media_log_;
260 media::Pipeline pipeline_;
262 // The currently selected key system. Empty string means that no key system
263 // has been selected.
264 std::string current_key_system_;
266 // The LoadType passed in the |load_type| parameter of the load() call.
269 // Cache of metadata for answering hasAudio(), hasVideo(), and naturalSize().
270 media::PipelineMetadata pipeline_metadata_;
272 // Whether the video is known to be opaque or not.
277 // TODO(scherkus): we have these because Pipeline favours the simplicity of a
278 // single "playback rate" over worrying about paused/stopped etc... It forces
279 // all clients to manage the pause+playback rate externally, but is that
280 // really a bad thing?
282 // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want
283 // to hang the render thread during pause(), we record the time at the same
284 // time we pause and then return that value in currentTime(). Otherwise our
285 // clock can creep forward a little bit while the asynchronous
286 // SetPlaybackRate(0) is being executed.
289 double playback_rate_;
290 base::TimeDelta paused_time_;
292 // Seek gets pending if another seek is in progress. Only last pending seek
295 double pending_seek_seconds_;
297 blink::WebMediaPlayerClient* client_;
299 base::WeakPtr<WebMediaPlayerDelegate> delegate_;
301 base::Callback<void(const base::Closure&)> defer_load_cb_;
303 // Since accelerated compositing status is only known after the first layout,
304 // we delay reporting it to UMA until that time.
305 bool accelerated_compositing_reported_;
307 bool incremented_externally_allocated_memory_;
309 // Factories for supporting video accelerators. May be null.
310 scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_;
312 // Routes audio playback to either AudioRendererSink or WebAudio.
313 scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_;
315 bool is_local_source_;
320 // These two are mutually exclusive:
321 // |data_source_| is used for regular resource loads.
322 // |chunk_demuxer_| is used for Media Source resource loads.
324 // |demuxer_| will contain the appropriate demuxer based on which resource
325 // load strategy we're using.
326 scoped_ptr<BufferedDataSource> data_source_;
327 scoped_ptr<media::Demuxer> demuxer_;
328 media::ChunkDemuxer* chunk_demuxer_;
330 BufferedDataSourceHostImpl buffered_data_source_host_;
331 // TODO(sandersd): Remove this cache. http://crbug.com/360254
332 blink::WebTimeRanges buffered_web_time_ranges_;
334 // Temporary for EME v0.1. In the future the init data type should be passed
335 // through GenerateKeyRequest() directly from WebKit.
336 std::string init_data_type_;
338 // Video rendering members.
339 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
340 VideoFrameCompositor* compositor_; // Deleted on |compositor_task_runner_|.
341 media::SkCanvasVideoRenderer skcanvas_video_renderer_;
343 // The compositor layer for displaying the video content when using composited
345 scoped_ptr<webkit::WebLayerImpl> video_weblayer_;
347 // Text track objects get a unique index value when they're created.
348 int text_track_index_;
350 // Manages decryption keys and decrypts encrypted frames.
351 scoped_ptr<ProxyDecryptor> proxy_decryptor_;
353 // Non-owned pointer to the CDM. Updated via calls to
354 // setContentDecryptionModule().
355 WebContentDecryptionModuleImpl* web_cdm_;
357 media::DecryptorReadyCB decryptor_ready_cb_;
359 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
362 } // namespace content
364 #endif // CONTENT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_