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