Home | History | Annotate | Download | only in android
      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 CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
      6 #define CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
      7 
      8 #include <jni.h>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.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/message_loop/message_loop.h"
     17 #include "base/time/time.h"
     18 #include "cc/layers/video_frame_provider.h"
     19 #include "content/common/media/media_player_messages_enums_android.h"
     20 #include "content/renderer/media/android/media_info_loader.h"
     21 #include "content/renderer/media/android/media_source_delegate.h"
     22 #include "content/renderer/media/android/stream_texture_factory_android.h"
     23 #include "content/renderer/media/crypto/proxy_decryptor.h"
     24 #include "gpu/command_buffer/common/mailbox.h"
     25 #include "media/base/android/media_player_android.h"
     26 #include "media/base/demuxer_stream.h"
     27 #include "media/base/media_keys.h"
     28 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
     29 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
     30 #include "third_party/WebKit/public/platform/WebSize.h"
     31 #include "third_party/WebKit/public/platform/WebURL.h"
     32 #include "ui/gfx/rect_f.h"
     33 
     34 namespace media {
     35 class Demuxer;
     36 class MediaLog;
     37 }
     38 
     39 namespace blink {
     40 class WebFrame;
     41 }
     42 
     43 namespace webkit {
     44 class WebLayerImpl;
     45 }
     46 
     47 namespace content {
     48 class WebMediaPlayerDelegate;
     49 class RendererMediaPlayerManager;
     50 
     51 #if defined(GOOGLE_TV)
     52 class MediaStreamAudioRenderer;
     53 class MediaStreamClient;
     54 #endif
     55 
     56 // This class implements blink::WebMediaPlayer by keeping the android
     57 // media player in the browser process. It listens to all the status changes
     58 // sent from the browser process and sends playback controls to the media
     59 // player.
     60 class WebMediaPlayerAndroid
     61     : public blink::WebMediaPlayer,
     62       public cc::VideoFrameProvider,
     63       public base::MessageLoop::DestructionObserver,
     64       public base::SupportsWeakPtr<WebMediaPlayerAndroid> {
     65  public:
     66   // Construct a WebMediaPlayerAndroid object. This class communicates
     67   // with the MediaPlayerAndroid object in the browser process through
     68   // |proxy|.
     69   // TODO(qinmin): |frame| argument is used to determine whether the current
     70   // player can enter fullscreen. This logic should probably be moved into
     71   // blink, so that enterFullscreen() will not be called if another video is
     72   // already in fullscreen.
     73   WebMediaPlayerAndroid(
     74       blink::WebFrame* frame,
     75       blink::WebMediaPlayerClient* client,
     76       base::WeakPtr<WebMediaPlayerDelegate> delegate,
     77       RendererMediaPlayerManager* manager,
     78       StreamTextureFactory* factory,
     79       const scoped_refptr<base::MessageLoopProxy>& media_loop,
     80       media::MediaLog* media_log);
     81   virtual ~WebMediaPlayerAndroid();
     82 
     83   // blink::WebMediaPlayer implementation.
     84   virtual void enterFullscreen();
     85   virtual void exitFullscreen();
     86   virtual bool canEnterFullscreen() const;
     87 
     88   // Resource loading.
     89   virtual void load(LoadType load_type,
     90                     const blink::WebURL& url,
     91                     CORSMode cors_mode) OVERRIDE;
     92 
     93   // Playback controls.
     94   virtual void play();
     95   virtual void pause();
     96   virtual void pause(bool is_media_related_action);
     97   virtual void seek(double seconds);
     98   virtual bool supportsFullscreen() const;
     99   virtual bool supportsSave() const;
    100   virtual void setRate(double rate);
    101   virtual void setVolume(double volume);
    102   virtual const blink::WebTimeRanges& buffered();
    103   virtual double maxTimeSeekable() const;
    104 
    105   // Methods for painting.
    106   virtual void paint(blink::WebCanvas* canvas,
    107                      const blink::WebRect& rect,
    108                      unsigned char alpha);
    109 
    110   virtual bool copyVideoTextureToPlatformTexture(
    111       blink::WebGraphicsContext3D* web_graphics_context,
    112       unsigned int texture,
    113       unsigned int level,
    114       unsigned int internal_format,
    115       unsigned int type,
    116       bool premultiply_alpha,
    117       bool flip_y);
    118 
    119   // True if the loaded media has a playable video/audio track.
    120   virtual bool hasVideo() const;
    121   virtual bool hasAudio() const;
    122 
    123   // Dimensions of the video.
    124   virtual blink::WebSize naturalSize() const;
    125 
    126   // Getters of playback state.
    127   virtual bool paused() const;
    128   virtual bool seeking() const;
    129   virtual double duration() const;
    130   virtual double currentTime() const;
    131 
    132   virtual bool didLoadingProgress() const;
    133 
    134   // Internal states of loading and network.
    135   virtual blink::WebMediaPlayer::NetworkState networkState() const;
    136   virtual blink::WebMediaPlayer::ReadyState readyState() const;
    137 
    138   virtual bool hasSingleSecurityOrigin() const;
    139   virtual bool didPassCORSAccessCheck() const;
    140 
    141   virtual double mediaTimeForTimeValue(double timeValue) const;
    142 
    143   // Provide statistics.
    144   virtual unsigned decodedFrameCount() const;
    145   virtual unsigned droppedFrameCount() const;
    146   virtual unsigned audioDecodedByteCount() const;
    147   virtual unsigned videoDecodedByteCount() const;
    148 
    149   // cc::VideoFrameProvider implementation. These methods are running on the
    150   // compositor thread.
    151   virtual void SetVideoFrameProviderClient(
    152       cc::VideoFrameProvider::Client* client) OVERRIDE;
    153   virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE;
    154   virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame)
    155       OVERRIDE;
    156 
    157   // Media player callback handlers.
    158   void OnMediaMetadataChanged(const base::TimeDelta& duration, int width,
    159                               int height, bool success);
    160   void OnPlaybackComplete();
    161   void OnBufferingUpdate(int percentage);
    162   void OnSeekRequest(const base::TimeDelta& time_to_seek);
    163   void OnSeekComplete(const base::TimeDelta& current_time);
    164   void OnMediaError(int error_type);
    165   void OnVideoSizeChanged(int width, int height);
    166   void OnDurationChanged(const base::TimeDelta& duration);
    167 
    168   // Called to update the current time.
    169   void OnTimeUpdate(const base::TimeDelta& current_time);
    170 
    171   // Functions called when media player status changes.
    172   void OnConnectedToRemoteDevice();
    173   void OnDisconnectedFromRemoteDevice();
    174   void OnDidEnterFullscreen();
    175   void OnDidExitFullscreen();
    176   void OnMediaPlayerPlay();
    177   void OnMediaPlayerPause();
    178   void OnRequestFullscreen();
    179 
    180   // Called when the player is released.
    181   virtual void OnPlayerReleased();
    182 
    183   // This function is called by the RendererMediaPlayerManager to pause the
    184   // video and release the media player and surface texture when we switch tabs.
    185   // However, the actual GlTexture is not released to keep the video screenshot.
    186   virtual void ReleaseMediaResources();
    187 
    188   // Method inherited from DestructionObserver.
    189   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
    190 
    191   // Detach the player from its manager.
    192   void Detach();
    193 
    194 #if defined(VIDEO_HOLE)
    195   // Retrieve geometry of the media player (i.e. location and size of the video
    196   // frame) if changed. Returns true only if the geometry has been changed since
    197   // the last call.
    198   bool RetrieveGeometryChange(gfx::RectF* rect);
    199 #endif  // defined(VIDEO_HOLE)
    200 
    201   virtual MediaKeyException generateKeyRequest(
    202       const blink::WebString& key_system,
    203       const unsigned char* init_data,
    204       unsigned init_data_length) OVERRIDE;
    205   virtual MediaKeyException addKey(
    206       const blink::WebString& key_system,
    207       const unsigned char* key,
    208       unsigned key_length,
    209       const unsigned char* init_data,
    210       unsigned init_data_length,
    211       const blink::WebString& session_id) OVERRIDE;
    212   virtual MediaKeyException cancelKeyRequest(
    213       const blink::WebString& key_system,
    214       const blink::WebString& session_id) OVERRIDE;
    215 
    216   void OnKeyAdded(const std::string& session_id);
    217   void OnKeyError(const std::string& session_id,
    218                   media::MediaKeys::KeyError error_code,
    219                   int system_code);
    220   void OnKeyMessage(const std::string& session_id,
    221                     const std::vector<uint8>& message,
    222                     const std::string& destination_url);
    223 
    224   void OnMediaSourceOpened(blink::WebMediaSource* web_media_source);
    225 
    226   void OnNeedKey(const std::string& type,
    227                  const std::vector<uint8>& init_data);
    228 
    229 #if defined(GOOGLE_TV)
    230   bool InjectMediaStream(MediaStreamClient* media_stream_client,
    231                          media::Demuxer* demuxer,
    232                          const base::Closure& destroy_demuxer_cb);
    233 #endif
    234 
    235   // Can be called on any thread.
    236   static void OnReleaseRemotePlaybackTexture(
    237       const scoped_refptr<base::MessageLoopProxy>& main_loop,
    238       const base::WeakPtr<WebMediaPlayerAndroid>& player,
    239       uint32 sync_point);
    240 
    241  protected:
    242   // Helper method to update the playing state.
    243   void UpdatePlayingState(bool is_playing_);
    244 
    245   // Helper methods for posting task for setting states and update WebKit.
    246   void UpdateNetworkState(blink::WebMediaPlayer::NetworkState state);
    247   void UpdateReadyState(blink::WebMediaPlayer::ReadyState state);
    248   void TryCreateStreamTextureProxyIfNeeded();
    249   void DoCreateStreamTexture();
    250 
    251 
    252   // Helper method to reestablish the surface texture peer for android
    253   // media player.
    254   void EstablishSurfaceTexturePeer();
    255 
    256   // Requesting whether the surface texture peer needs to be reestablished.
    257   void SetNeedsEstablishPeer(bool needs_establish_peer);
    258 
    259  private:
    260   void DrawRemotePlaybackIcon();
    261   void ReallocateVideoFrame();
    262   void SetCurrentFrameInternal(scoped_refptr<media::VideoFrame>& frame);
    263   void DidLoadMediaInfo(MediaInfoLoader::Status status);
    264   void DoReleaseRemotePlaybackTexture(uint32 sync_point);
    265 
    266   bool IsKeySystemSupported(const blink::WebString& key_system);
    267 
    268   // Actually do the work for generateKeyRequest/addKey so they can easily
    269   // report results to UMA.
    270   MediaKeyException GenerateKeyRequestInternal(
    271       const blink::WebString& key_system,
    272       const unsigned char* init_data,
    273       unsigned init_data_length);
    274   MediaKeyException AddKeyInternal(const blink::WebString& key_system,
    275                                    const unsigned char* key,
    276                                    unsigned key_length,
    277                                    const unsigned char* init_data,
    278                                    unsigned init_data_length,
    279                                    const blink::WebString& session_id);
    280   MediaKeyException CancelKeyRequestInternal(
    281       const blink::WebString& key_system,
    282       const blink::WebString& session_id);
    283 
    284   blink::WebFrame* const frame_;
    285 
    286   blink::WebMediaPlayerClient* const client_;
    287 
    288   // |delegate_| is used to notify the browser process of the player status, so
    289   // that the browser process can control screen locks.
    290   // TODO(qinmin): Currently android mediaplayer takes care of the screen
    291   // lock. So this is only used for media source. Will apply this to regular
    292   // media tag once http://crbug.com/247892 is fixed.
    293   base::WeakPtr<WebMediaPlayerDelegate> delegate_;
    294 
    295   // Save the list of buffered time ranges.
    296   blink::WebTimeRanges buffered_;
    297 
    298   // Size of the video.
    299   blink::WebSize natural_size_;
    300 
    301   // Size that has been sent to StreamTexture.
    302   blink::WebSize cached_stream_texture_size_;
    303 
    304   // The video frame object used for rendering by the compositor.
    305   scoped_refptr<media::VideoFrame> current_frame_;
    306   base::Lock current_frame_lock_;
    307 
    308   base::ThreadChecker main_thread_checker_;
    309 
    310   // Message loop for main renderer thread.
    311   const scoped_refptr<base::MessageLoopProxy> main_loop_;
    312 
    313   // Message loop for media thread.
    314   const scoped_refptr<base::MessageLoopProxy> media_loop_;
    315 
    316   // URL of the media file to be fetched.
    317   GURL url_;
    318 
    319   // Media duration.
    320   base::TimeDelta duration_;
    321 
    322   // Flag to remember if we have a trusted duration_ value provided by
    323   // MediaSourceDelegate notifying OnDurationChanged(). In this case, ignore
    324   // any subsequent duration value passed to OnMediaMetadataChange().
    325   bool ignore_metadata_duration_change_;
    326 
    327   // Seek gets pending if another seek is in progress. Only last pending seek
    328   // will have effect.
    329   bool pending_seek_;
    330   base::TimeDelta pending_seek_time_;
    331 
    332   // Internal seek state.
    333   bool seeking_;
    334   base::TimeDelta seek_time_;
    335 
    336   // Whether loading has progressed since the last call to didLoadingProgress.
    337   mutable bool did_loading_progress_;
    338 
    339   // Manager for managing this object and for delegating method calls on
    340   // Render Thread.
    341   RendererMediaPlayerManager* manager_;
    342 
    343   // Player ID assigned by the |manager_|.
    344   int player_id_;
    345 
    346   // Current player states.
    347   blink::WebMediaPlayer::NetworkState network_state_;
    348   blink::WebMediaPlayer::ReadyState ready_state_;
    349 
    350   // GL texture ID used to show the remote playback icon.
    351   unsigned int remote_playback_texture_id_;
    352 
    353   // GL texture ID allocated to the video.
    354   unsigned int texture_id_;
    355 
    356   // GL texture mailbox for texture_id_ to provide in the VideoFrame, and sync
    357   // point for when the mailbox was produced.
    358   gpu::Mailbox texture_mailbox_;
    359   unsigned int texture_mailbox_sync_point_;
    360 
    361   // Stream texture ID allocated to the video.
    362   unsigned int stream_id_;
    363 
    364   // Whether the mediaplayer is playing.
    365   bool is_playing_;
    366 
    367   // Whether the mediaplayer has already started playing.
    368   bool playing_started_;
    369 
    370   // Whether media player needs to re-establish the surface texture peer.
    371   bool needs_establish_peer_;
    372 
    373   // Whether |stream_texture_proxy_| is initialized.
    374   bool stream_texture_proxy_initialized_;
    375 
    376   // Whether the video size info is available.
    377   bool has_size_info_;
    378 
    379   // Whether the video metadata and info are available.
    380   bool has_media_metadata_;
    381   bool has_media_info_;
    382 
    383   // Object for allocating stream textures.
    384   scoped_ptr<StreamTextureFactory> stream_texture_factory_;
    385 
    386   // Object for calling back the compositor thread to repaint the video when a
    387   // frame available. It should be initialized on the compositor thread.
    388   ScopedStreamTextureProxy stream_texture_proxy_;
    389 
    390   // Whether media player needs external surface.
    391   bool needs_external_surface_;
    392 
    393   // A pointer back to the compositor to inform it about state changes. This is
    394   // not NULL while the compositor is actively using this webmediaplayer.
    395   cc::VideoFrameProvider::Client* video_frame_provider_client_;
    396 
    397   scoped_ptr<webkit::WebLayerImpl> video_weblayer_;
    398 
    399 #if defined(VIDEO_HOLE)
    400   // A rectangle represents the geometry of video frame, when computed last
    401   // time.
    402   gfx::RectF last_computed_rect_;
    403 #endif  // defined(VIDEO_HOLE)
    404 
    405 #if defined(GOOGLE_TV)
    406   // Pixel threshold for external surface usage. Negative value means that the
    407   // threshold is not defined, so that external surface is never used.
    408   int external_surface_threshold_;
    409 
    410   // Media Stream related fields.
    411   media::Demuxer* demuxer_;
    412   base::Closure destroy_demuxer_cb_;
    413   scoped_refptr<MediaStreamAudioRenderer> audio_renderer_;
    414   MediaStreamClient* media_stream_client_;
    415 #endif
    416 
    417   scoped_ptr<MediaSourceDelegate,
    418              MediaSourceDelegate::Destroyer> media_source_delegate_;
    419 
    420   // Internal pending playback state.
    421   // Store a playback request that cannot be started immediately.
    422   bool pending_playback_;
    423 
    424   MediaPlayerHostMsg_Initialize_Type player_type_;
    425 
    426   // The current playing time. Because the media player is in the browser
    427   // process, it will regularly update the |current_time_| by calling
    428   // OnTimeUpdate().
    429   double current_time_;
    430 
    431   // Whether the browser is currently connected to a remote media player.
    432   bool is_remote_;
    433 
    434   media::MediaLog* media_log_;
    435 
    436   scoped_ptr<MediaInfoLoader> info_loader_;
    437 
    438   // The currently selected key system. Empty string means that no key system
    439   // has been selected.
    440   blink::WebString current_key_system_;
    441 
    442   // Temporary for EME v0.1. In the future the init data type should be passed
    443   // through GenerateKeyRequest() directly from WebKit.
    444   std::string init_data_type_;
    445 
    446   // The decryptor that manages decryption keys and decrypts encrypted frames.
    447   scoped_ptr<ProxyDecryptor> decryptor_;
    448 
    449   base::WeakPtrFactory<WebMediaPlayerAndroid> weak_factory_;
    450 
    451   DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid);
    452 };
    453 
    454 }  // namespace content
    455 
    456 #endif  // CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
    457