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 MEDIA_BLINK_WEBMEDIAPLAYER_IMPL_H_
6#define MEDIA_BLINK_WEBMEDIAPLAYER_IMPL_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/threading/thread.h"
17#include "media/base/audio_renderer_sink.h"
18#include "media/base/media_export.h"
19// TODO(xhwang): Remove when we remove prefixed EME implementation.
20#include "media/base/media_keys.h"
21#include "media/base/pipeline.h"
22#include "media/base/text_track.h"
23#include "media/blink/buffered_data_source.h"
24#include "media/blink/buffered_data_source_host_impl.h"
25#include "media/blink/video_frame_compositor.h"
26#include "media/filters/skcanvas_video_renderer.h"
27#include "third_party/WebKit/public/platform/WebAudioSourceProvider.h"
28#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
29#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
30#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
31#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
32#include "url/gurl.h"
33
34namespace blink {
35class WebLocalFrame;
36}
37
38namespace base {
39class SingleThreadTaskRunner;
40}
41
42namespace cc_blink {
43class WebLayerImpl;
44}
45
46namespace media {
47class AudioHardwareConfig;
48class ChunkDemuxer;
49class EncryptedMediaPlayerSupport;
50class GpuVideoAcceleratorFactories;
51class MediaLog;
52class VideoFrameCompositor;
53class WebAudioSourceProviderImpl;
54class WebMediaPlayerDelegate;
55class WebMediaPlayerParams;
56class WebTextTrackImpl;
57
58// The canonical implementation of blink::WebMediaPlayer that's backed by
59// Pipeline. Handles normal resource loading, Media Source, and
60// Encrypted Media.
61class MEDIA_EXPORT WebMediaPlayerImpl
62    : public NON_EXPORTED_BASE(blink::WebMediaPlayer),
63      public base::SupportsWeakPtr<WebMediaPlayerImpl> {
64 public:
65  // Constructs a WebMediaPlayer implementation using Chromium's media stack.
66  // |delegate| may be null.
67  WebMediaPlayerImpl(blink::WebLocalFrame* frame,
68                     blink::WebMediaPlayerClient* client,
69                     base::WeakPtr<WebMediaPlayerDelegate> delegate,
70                     const WebMediaPlayerParams& params);
71  virtual ~WebMediaPlayerImpl();
72
73  virtual void load(LoadType load_type,
74                    const blink::WebURL& url,
75                    CORSMode cors_mode);
76
77  // Playback controls.
78  virtual void play();
79  virtual void pause();
80  virtual bool supportsSave() const;
81  virtual void seek(double seconds);
82  virtual void setRate(double rate);
83  virtual void setVolume(double volume);
84  virtual void setPreload(blink::WebMediaPlayer::Preload preload);
85  virtual blink::WebTimeRanges buffered() const;
86  virtual double maxTimeSeekable() const;
87
88  // Methods for painting.
89  virtual void paint(blink::WebCanvas* canvas,
90                     const blink::WebRect& rect,
91                     unsigned char alpha,
92                     SkXfermode::Mode mode);
93  // TODO(dshwang): remove it because above method replaces. crbug.com/401027
94  virtual void paint(blink::WebCanvas* canvas,
95                     const blink::WebRect& rect,
96                     unsigned char alpha);
97
98  // True if the loaded media has a playable video/audio track.
99  virtual bool hasVideo() const;
100  virtual bool hasAudio() const;
101
102  // Dimensions of the video.
103  virtual blink::WebSize naturalSize() const;
104
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;
111
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;
117
118  virtual bool didLoadingProgress();
119
120  virtual bool hasSingleSecurityOrigin() const;
121  virtual bool didPassCORSAccessCheck() const;
122
123  virtual double mediaTimeForTimeValue(double timeValue) const;
124
125  virtual unsigned decodedFrameCount() const;
126  virtual unsigned droppedFrameCount() const;
127  virtual unsigned audioDecodedByteCount() const;
128  virtual unsigned videoDecodedByteCount() const;
129
130  virtual bool copyVideoTextureToPlatformTexture(
131      blink::WebGraphicsContext3D* web_graphics_context,
132      unsigned int texture,
133      unsigned int level,
134      unsigned int internal_format,
135      unsigned int type,
136      bool premultiply_alpha,
137      bool flip_y);
138
139  virtual blink::WebAudioSourceProvider* audioSourceProvider();
140
141  virtual MediaKeyException generateKeyRequest(
142      const blink::WebString& key_system,
143      const unsigned char* init_data,
144      unsigned init_data_length);
145
146  virtual MediaKeyException addKey(const blink::WebString& key_system,
147                                   const unsigned char* key,
148                                   unsigned key_length,
149                                   const unsigned char* init_data,
150                                   unsigned init_data_length,
151                                   const blink::WebString& session_id);
152
153  virtual MediaKeyException cancelKeyRequest(
154      const blink::WebString& key_system,
155      const blink::WebString& session_id);
156
157  // TODO(jrummell): Remove this method once Blink updated to use the other
158  // method.
159  virtual void setContentDecryptionModule(
160      blink::WebContentDecryptionModule* cdm);
161  virtual void setContentDecryptionModule(
162      blink::WebContentDecryptionModule* cdm,
163      blink::WebContentDecryptionModuleResult result);
164
165  void OnPipelineSeeked(bool time_changed, PipelineStatus status);
166  void OnPipelineEnded();
167  void OnPipelineError(PipelineStatus error);
168  void OnPipelineMetadata(PipelineMetadata metadata);
169  void OnPipelineBufferingStateChanged(BufferingState buffering_state);
170  void OnDemuxerOpened();
171  void OnAddTextTrack(const TextTrackConfig& config,
172                      const AddTextTrackDoneCB& done_cb);
173
174 private:
175  // Called after |defer_load_cb_| has decided to allow the load. If
176  // |defer_load_cb_| is null this is called immediately.
177  void DoLoad(LoadType load_type,
178              const blink::WebURL& url,
179              CORSMode cors_mode);
180
181  // Called after asynchronous initialization of a data source completed.
182  void DataSourceInitialized(bool success);
183
184  // Called when the data source is downloading or paused.
185  void NotifyDownloading(bool is_downloading);
186
187  // Creates a Renderer that will be used by the |pipeline_|.
188  scoped_ptr<Renderer> CreateRenderer();
189
190  // Finishes starting the pipeline due to a call to load().
191  void StartPipeline();
192
193  // Helpers that set the network/ready state and notifies the client if
194  // they've changed.
195  void SetNetworkState(blink::WebMediaPlayer::NetworkState state);
196  void SetReadyState(blink::WebMediaPlayer::ReadyState state);
197
198  // Gets the duration value reported by the pipeline.
199  double GetPipelineDuration() const;
200
201  // Callbacks from |pipeline_| that are forwarded to |client_|.
202  void OnDurationChanged();
203  void OnNaturalSizeChanged(gfx::Size size);
204  void OnOpacityChanged(bool opaque);
205
206  // Called by VideoRendererImpl on its internal thread with the new frame to be
207  // painted.
208  void FrameReady(const scoped_refptr<VideoFrame>& frame);
209
210  // Returns the current video frame from |compositor_|. Blocks until the
211  // compositor can return the frame.
212  scoped_refptr<VideoFrame> GetCurrentFrameFromCompositor();
213
214  blink::WebLocalFrame* frame_;
215
216  // TODO(hclam): get rid of these members and read from the pipeline directly.
217  blink::WebMediaPlayer::NetworkState network_state_;
218  blink::WebMediaPlayer::ReadyState ready_state_;
219
220  // Preload state for when |data_source_| is created after setPreload().
221  BufferedDataSource::Preload preload_;
222
223  // Task runner for posting tasks on Chrome's main thread. Also used
224  // for DCHECKs so methods calls won't execute in the wrong thread.
225  const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
226
227  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
228  scoped_refptr<MediaLog> media_log_;
229  Pipeline pipeline_;
230
231  // The LoadType passed in the |load_type| parameter of the load() call.
232  LoadType load_type_;
233
234  // Cache of metadata for answering hasAudio(), hasVideo(), and naturalSize().
235  PipelineMetadata pipeline_metadata_;
236
237  // Whether the video is known to be opaque or not.
238  bool opaque_;
239
240  // Playback state.
241  //
242  // TODO(scherkus): we have these because Pipeline favours the simplicity of a
243  // single "playback rate" over worrying about paused/stopped etc...  It forces
244  // all clients to manage the pause+playback rate externally, but is that
245  // really a bad thing?
246  //
247  // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want
248  // to hang the render thread during pause(), we record the time at the same
249  // time we pause and then return that value in currentTime().  Otherwise our
250  // clock can creep forward a little bit while the asynchronous
251  // SetPlaybackRate(0) is being executed.
252  bool paused_;
253  bool seeking_;
254  double playback_rate_;
255  base::TimeDelta paused_time_;
256
257  // TODO(scherkus): Replace with an explicit ended signal to HTMLMediaElement,
258  // see http://crbug.com/409280
259  bool ended_;
260
261  // Seek gets pending if another seek is in progress. Only last pending seek
262  // will have effect.
263  bool pending_seek_;
264  double pending_seek_seconds_;
265
266  // Tracks whether to issue time changed notifications during buffering state
267  // changes.
268  bool should_notify_time_changed_;
269
270  blink::WebMediaPlayerClient* client_;
271
272  base::WeakPtr<WebMediaPlayerDelegate> delegate_;
273
274  base::Callback<void(const base::Closure&)> defer_load_cb_;
275
276  // Factories for supporting video accelerators. May be null.
277  scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories_;
278
279  // Routes audio playback to either AudioRendererSink or WebAudio.
280  scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_;
281
282  bool supports_save_;
283
284  // These two are mutually exclusive:
285  //   |data_source_| is used for regular resource loads.
286  //   |chunk_demuxer_| is used for Media Source resource loads.
287  //
288  // |demuxer_| will contain the appropriate demuxer based on which resource
289  // load strategy we're using.
290  scoped_ptr<BufferedDataSource> data_source_;
291  scoped_ptr<Demuxer> demuxer_;
292  ChunkDemuxer* chunk_demuxer_;
293
294  BufferedDataSourceHostImpl buffered_data_source_host_;
295
296  // Video rendering members.
297  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
298  VideoFrameCompositor* compositor_;  // Deleted on |compositor_task_runner_|.
299  SkCanvasVideoRenderer skcanvas_video_renderer_;
300
301  // The compositor layer for displaying the video content when using composited
302  // playback.
303  scoped_ptr<cc_blink::WebLayerImpl> video_weblayer_;
304
305  // Text track objects get a unique index value when they're created.
306  int text_track_index_;
307
308  scoped_ptr<EncryptedMediaPlayerSupport> encrypted_media_support_;
309
310  const AudioHardwareConfig& audio_hardware_config_;
311
312  DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
313};
314
315}  // namespace media
316
317#endif  // MEDIA_BLINK_WEBMEDIAPLAYER_IMPL_H_
318