Home | History | Annotate | Download | only in blink
      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 
     34 namespace blink {
     35 class WebLocalFrame;
     36 }
     37 
     38 namespace base {
     39 class SingleThreadTaskRunner;
     40 }
     41 
     42 namespace cc_blink {
     43 class WebLayerImpl;
     44 }
     45 
     46 namespace media {
     47 class AudioHardwareConfig;
     48 class ChunkDemuxer;
     49 class EncryptedMediaPlayerSupport;
     50 class GpuVideoAcceleratorFactories;
     51 class MediaLog;
     52 class VideoFrameCompositor;
     53 class WebAudioSourceProviderImpl;
     54 class WebMediaPlayerDelegate;
     55 class WebMediaPlayerParams;
     56 class 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.
     61 class 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