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