| 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 |