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