Home | History | Annotate | Download | only in media
      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 CONTENT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_
     21 #define CONTENT_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 "content/public/renderer/render_view_observer.h"
     33 #include "content/renderer/media/crypto/proxy_decryptor.h"
     34 #include "media/base/audio_renderer_sink.h"
     35 #include "media/base/decryptor.h"
     36 #include "media/base/media_keys.h"
     37 #include "media/base/pipeline.h"
     38 #include "media/base/text_track.h"
     39 #include "media/filters/skcanvas_video_renderer.h"
     40 #include "skia/ext/platform_canvas.h"
     41 #include "third_party/WebKit/public/platform/WebAudioSourceProvider.h"
     42 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
     43 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
     44 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
     45 #include "url/gurl.h"
     46 
     47 class RenderAudioSourceProvider;
     48 
     49 namespace blink {
     50 class WebFrame;
     51 }
     52 
     53 namespace base {
     54 class MessageLoopProxy;
     55 }
     56 
     57 namespace media {
     58 class ChunkDemuxer;
     59 class GpuVideoAcceleratorFactories;
     60 class MediaLog;
     61 }
     62 
     63 namespace webkit {
     64 class WebLayerImpl;
     65 }
     66 
     67 namespace content {
     68 class BufferedDataSource;
     69 class WebAudioSourceProviderImpl;
     70 class WebMediaPlayerDelegate;
     71 class WebMediaPlayerParams;
     72 class WebTextTrackImpl;
     73 
     74 class WebMediaPlayerImpl
     75     : public blink::WebMediaPlayer,
     76       public cc::VideoFrameProvider,
     77       public content::RenderViewObserver,
     78       public base::SupportsWeakPtr<WebMediaPlayerImpl> {
     79  public:
     80   // Constructs a WebMediaPlayer implementation using Chromium's media stack.
     81   // |render_view| is passed only for the purpose of registering |this| as an
     82   // observer of it.
     83   // |delegate| may be null.
     84   WebMediaPlayerImpl(
     85       content::RenderView* render_view,
     86       blink::WebFrame* frame,
     87       blink::WebMediaPlayerClient* client,
     88       base::WeakPtr<WebMediaPlayerDelegate> delegate,
     89       const WebMediaPlayerParams& params);
     90   virtual ~WebMediaPlayerImpl();
     91 
     92   virtual void load(LoadType load_type,
     93                     const blink::WebURL& url,
     94                     CORSMode cors_mode) OVERRIDE;
     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(blink::WebMediaPlayer::Preload preload);
    105   virtual const blink::WebTimeRanges& buffered();
    106   virtual double maxTimeSeekable() const;
    107 
    108   // Methods for painting.
    109   virtual void paint(blink::WebCanvas* canvas,
    110                      const blink::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 blink::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 blink::WebMediaPlayer::NetworkState networkState() const;
    130   virtual blink::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       blink::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 blink::WebAudioSourceProvider* audioSourceProvider();
    161 
    162   virtual MediaKeyException generateKeyRequest(
    163       const blink::WebString& key_system,
    164       const unsigned char* init_data,
    165       unsigned init_data_length);
    166 
    167   virtual MediaKeyException addKey(const blink::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 blink::WebString& session_id);
    173 
    174   virtual MediaKeyException cancelKeyRequest(
    175       const blink::WebString& key_system,
    176       const blink::WebString& session_id);
    177 
    178   // content::RenderViewObserver implementation.
    179   virtual void OnDestruct() OVERRIDE;
    180 
    181   void Repaint();
    182 
    183   void OnPipelineSeek(media::PipelineStatus status);
    184   void OnPipelineEnded();
    185   void OnPipelineError(media::PipelineStatus error);
    186   void OnPipelineBufferingState(
    187       media::Pipeline::BufferingState buffering_state);
    188   void OnDemuxerOpened();
    189   void OnKeyAdded(const std::string& session_id);
    190   void OnKeyError(const std::string& session_id,
    191                   media::MediaKeys::KeyError error_code,
    192                   int system_code);
    193   void OnKeyMessage(const std::string& session_id,
    194                     const std::vector<uint8>& message,
    195                     const std::string& default_url);
    196   void OnNeedKey(const std::string& type,
    197                  const std::vector<uint8>& init_data);
    198   void OnAddTextTrack(const media::TextTrackConfig& config,
    199                       const media::AddTextTrackDoneCB& done_cb);
    200   void SetOpaque(bool);
    201 
    202  private:
    203   // Called after |defer_load_cb_| has decided to allow the load. If
    204   // |defer_load_cb_| is null this is called immediately.
    205   void DoLoad(LoadType load_type,
    206               const blink::WebURL& url,
    207               CORSMode cors_mode);
    208 
    209   // Called after asynchronous initialization of a data source completed.
    210   void DataSourceInitialized(const GURL& gurl, bool success);
    211 
    212   // Called when the data source is downloading or paused.
    213   void NotifyDownloading(bool is_downloading);
    214 
    215   // Finishes starting the pipeline due to a call to load().
    216   void StartPipeline();
    217 
    218   // Helpers that set the network/ready state and notifies the client if
    219   // they've changed.
    220   void SetNetworkState(blink::WebMediaPlayer::NetworkState state);
    221   void SetReadyState(blink::WebMediaPlayer::ReadyState state);
    222 
    223   // Destroy resources held.
    224   void Destroy();
    225 
    226   // Getter method to |client_|.
    227   blink::WebMediaPlayerClient* GetClient();
    228 
    229   // Lets V8 know that player uses extra resources not managed by V8.
    230   void IncrementExternallyAllocatedMemory();
    231 
    232   // Actually do the work for generateKeyRequest/addKey so they can easily
    233   // report results to UMA.
    234   MediaKeyException GenerateKeyRequestInternal(
    235       const blink::WebString& key_system,
    236       const unsigned char* init_data,
    237       unsigned init_data_length);
    238   MediaKeyException AddKeyInternal(const blink::WebString& key_system,
    239                                    const unsigned char* key,
    240                                    unsigned key_length,
    241                                    const unsigned char* init_data,
    242                                    unsigned init_data_length,
    243                                    const blink::WebString& session_id);
    244   MediaKeyException CancelKeyRequestInternal(
    245       const blink::WebString& key_system,
    246       const blink::WebString& session_id);
    247 
    248   // Gets the duration value reported by the pipeline.
    249   double GetPipelineDuration() const;
    250 
    251   // Notifies WebKit of the duration change.
    252   void OnDurationChange();
    253 
    254   // Called by VideoRendererImpl on its internal thread with the new frame to be
    255   // painted.
    256   void FrameReady(const scoped_refptr<media::VideoFrame>& frame);
    257 
    258   // Called when a paint or a new frame arrives to indicate that we are
    259   // no longer waiting for |current_frame_| to be painted.
    260   // |painting_frame| is set to true if |current_frame_| is being painted.
    261   // False indicates |current_frame_| is being replaced with a new frame.
    262   void DoneWaitingForPaint(bool painting_frame);
    263 
    264   blink::WebFrame* frame_;
    265 
    266   // TODO(hclam): get rid of these members and read from the pipeline directly.
    267   blink::WebMediaPlayer::NetworkState network_state_;
    268   blink::WebMediaPlayer::ReadyState ready_state_;
    269 
    270   // Keep a list of buffered time ranges.
    271   blink::WebTimeRanges buffered_;
    272 
    273   // Message loops for posting tasks on Chrome's main thread. Also used
    274   // for DCHECKs so methods calls won't execute in the wrong thread.
    275   const scoped_refptr<base::MessageLoopProxy> main_loop_;
    276 
    277   scoped_ptr<media::Pipeline> pipeline_;
    278   scoped_refptr<base::MessageLoopProxy> media_loop_;
    279 
    280   // The currently selected key system. Empty string means that no key system
    281   // has been selected.
    282   blink::WebString current_key_system_;
    283 
    284   // The LoadType passed in the |load_type| parameter of the load() call.
    285   LoadType load_type_;
    286 
    287   // Playback state.
    288   //
    289   // TODO(scherkus): we have these because Pipeline favours the simplicity of a
    290   // single "playback rate" over worrying about paused/stopped etc...  It forces
    291   // all clients to manage the pause+playback rate externally, but is that
    292   // really a bad thing?
    293   //
    294   // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want
    295   // to hang the render thread during pause(), we record the time at the same
    296   // time we pause and then return that value in currentTime().  Otherwise our
    297   // clock can creep forward a little bit while the asynchronous
    298   // SetPlaybackRate(0) is being executed.
    299   bool paused_;
    300   bool seeking_;
    301   double playback_rate_;
    302   base::TimeDelta paused_time_;
    303 
    304   // Seek gets pending if another seek is in progress. Only last pending seek
    305   // will have effect.
    306   bool pending_seek_;
    307   double pending_seek_seconds_;
    308 
    309   blink::WebMediaPlayerClient* client_;
    310 
    311   base::WeakPtr<WebMediaPlayerDelegate> delegate_;
    312 
    313   base::Callback<void(const base::Closure&)> defer_load_cb_;
    314 
    315   scoped_refptr<media::MediaLog> media_log_;
    316 
    317   // Since accelerated compositing status is only known after the first layout,
    318   // we delay reporting it to UMA until that time.
    319   bool accelerated_compositing_reported_;
    320 
    321   bool incremented_externally_allocated_memory_;
    322 
    323   // Factories for supporting video accelerators. May be null.
    324   scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_;
    325 
    326   // Routes audio playback to either AudioRendererSink or WebAudio.
    327   scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_;
    328 
    329   bool is_local_source_;
    330   bool supports_save_;
    331 
    332   // The decryptor that manages decryption keys and decrypts encrypted frames.
    333   scoped_ptr<ProxyDecryptor> decryptor_;
    334 
    335   bool starting_;
    336 
    337   // These two are mutually exclusive:
    338   //   |data_source_| is used for regular resource loads.
    339   //   |chunk_demuxer_| is used for Media Source resource loads.
    340   //
    341   // |demuxer_| will contain the appropriate demuxer based on which resource
    342   // load strategy we're using.
    343   scoped_ptr<BufferedDataSource> data_source_;
    344   scoped_ptr<media::Demuxer> demuxer_;
    345   media::ChunkDemuxer* chunk_demuxer_;
    346 
    347   // Temporary for EME v0.1. In the future the init data type should be passed
    348   // through GenerateKeyRequest() directly from WebKit.
    349   std::string init_data_type_;
    350 
    351   // Video frame rendering members.
    352   //
    353   // |lock_| protects |current_frame_|, |current_frame_painted_|, and
    354   // |frames_dropped_before_paint_| since new frames arrive on the video
    355   // rendering thread, yet are accessed for rendering on either the main thread
    356   // or compositing thread depending on whether accelerated compositing is used.
    357   mutable base::Lock lock_;
    358   media::SkCanvasVideoRenderer skcanvas_video_renderer_;
    359   scoped_refptr<media::VideoFrame> current_frame_;
    360   bool current_frame_painted_;
    361   uint32 frames_dropped_before_paint_;
    362   bool pending_repaint_;
    363   bool pending_size_change_;
    364 
    365   // The compositor layer for displaying the video content when using composited
    366   // playback.
    367   scoped_ptr<webkit::WebLayerImpl> video_weblayer_;
    368 
    369   // A pointer back to the compositor to inform it about state changes. This is
    370   // not NULL while the compositor is actively using this webmediaplayer.
    371   cc::VideoFrameProvider::Client* video_frame_provider_client_;
    372 
    373   // Text track objects get a unique index value when they're created.
    374   int text_track_index_;
    375 
    376   DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
    377 };
    378 
    379 }  // namespace content
    380 
    381 #endif  // CONTENT_RENDERER_MEDIA_WEBMEDIAPLAYER_IMPL_H_
    382