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/threading/thread_checker.h" 17 #include "base/time/default_tick_clock.h" 18 #include "base/time/time.h" 19 #include "cc/layers/video_frame_provider.h" 20 #include "content/common/media/media_player_messages_enums_android.h" 21 #include "content/public/renderer/render_frame_observer.h" 22 #include "content/renderer/media/android/media_info_loader.h" 23 #include "content/renderer/media/android/media_source_delegate.h" 24 #include "content/renderer/media/android/stream_texture_factory.h" 25 #include "content/renderer/media/crypto/proxy_decryptor.h" 26 #include "gpu/command_buffer/common/mailbox.h" 27 #include "media/base/android/media_player_android.h" 28 #include "media/base/demuxer_stream.h" 29 #include "media/base/media_keys.h" 30 #include "media/base/time_delta_interpolator.h" 31 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 32 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" 33 #include "third_party/WebKit/public/platform/WebSize.h" 34 #include "third_party/WebKit/public/platform/WebURL.h" 35 #include "third_party/skia/include/core/SkBitmap.h" 36 #include "third_party/skia/include/gpu/GrContext.h" 37 #include "third_party/skia/include/gpu/SkGrPixelRef.h" 38 #include "ui/gfx/rect_f.h" 39 40 namespace base { 41 class SingleThreadTaskRunner; 42 } 43 44 namespace blink { 45 class WebContentDecryptionModule; 46 class WebContentDecryptionModuleResult; 47 class WebFrame; 48 class WebURL; 49 } 50 51 namespace cc_blink { 52 class WebLayerImpl; 53 } 54 55 namespace gpu { 56 struct MailboxHolder; 57 } 58 59 namespace media { 60 class MediaLog; 61 class WebMediaPlayerDelegate; 62 } 63 64 namespace content { 65 class RendererCdmManager; 66 class RendererMediaPlayerManager; 67 class WebContentDecryptionModuleImpl; 68 69 // This class implements blink::WebMediaPlayer by keeping the android 70 // media player in the browser process. It listens to all the status changes 71 // sent from the browser process and sends playback controls to the media 72 // player. 73 class WebMediaPlayerAndroid : public blink::WebMediaPlayer, 74 public cc::VideoFrameProvider, 75 public RenderFrameObserver, 76 public StreamTextureFactoryContextObserver { 77 public: 78 // Construct a WebMediaPlayerAndroid object. This class communicates with the 79 // MediaPlayerAndroid object in the browser process through |proxy|. 80 // TODO(qinmin): |frame| argument is used to determine whether the current 81 // player can enter fullscreen. This logic should probably be moved into 82 // blink, so that enterFullscreen() will not be called if another video is 83 // already in fullscreen. 84 WebMediaPlayerAndroid( 85 blink::WebFrame* frame, 86 blink::WebMediaPlayerClient* client, 87 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, 88 RendererMediaPlayerManager* player_manager, 89 RendererCdmManager* cdm_manager, 90 blink::WebContentDecryptionModule* initial_cdm, 91 scoped_refptr<StreamTextureFactory> factory, 92 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 93 media::MediaLog* media_log); 94 virtual ~WebMediaPlayerAndroid(); 95 96 // blink::WebMediaPlayer implementation. 97 virtual void enterFullscreen(); 98 virtual bool canEnterFullscreen() const; 99 100 // Resource loading. 101 virtual void load(LoadType load_type, 102 const blink::WebURL& url, 103 CORSMode cors_mode); 104 105 // Playback controls. 106 virtual void play(); 107 virtual void pause(); 108 virtual void seek(double seconds); 109 virtual bool supportsSave() const; 110 virtual void setRate(double rate); 111 virtual void setVolume(double volume); 112 virtual void requestRemotePlayback(); 113 virtual void requestRemotePlaybackControl(); 114 virtual blink::WebTimeRanges buffered() const; 115 virtual double maxTimeSeekable() const; 116 117 // Poster image, as defined in the <video> element. 118 virtual void setPoster(const blink::WebURL& poster) OVERRIDE; 119 120 // Methods for painting. 121 // FIXME: This path "only works" on Android. It is a workaround for the 122 // issue that Skia could not handle Android's GL_TEXTURE_EXTERNAL_OES texture 123 // internally. It should be removed and replaced by the normal paint path. 124 // https://code.google.com/p/skia/issues/detail?id=1189 125 virtual void paint(blink::WebCanvas* canvas, 126 const blink::WebRect& rect, 127 unsigned char alpha, 128 SkXfermode::Mode mode); 129 // TODO(dshwang): remove it because above method replaces. crbug.com/401027 130 virtual void paint(blink::WebCanvas* canvas, 131 const blink::WebRect& rect, 132 unsigned char alpha); 133 134 virtual bool copyVideoTextureToPlatformTexture( 135 blink::WebGraphicsContext3D* web_graphics_context, 136 unsigned int texture, 137 unsigned int level, 138 unsigned int internal_format, 139 unsigned int type, 140 bool premultiply_alpha, 141 bool flip_y); 142 143 // True if the loaded media has a playable video/audio track. 144 virtual bool hasVideo() const; 145 virtual bool hasAudio() const; 146 147 virtual bool isRemote() const; 148 149 // Dimensions of the video. 150 virtual blink::WebSize naturalSize() const; 151 152 // Getters of playback state. 153 virtual bool paused() const; 154 virtual bool seeking() const; 155 virtual double duration() const; 156 virtual double timelineOffset() const; 157 virtual double currentTime() const; 158 159 virtual bool didLoadingProgress(); 160 161 // Internal states of loading and network. 162 virtual blink::WebMediaPlayer::NetworkState networkState() const; 163 virtual blink::WebMediaPlayer::ReadyState readyState() const; 164 165 virtual bool hasSingleSecurityOrigin() const; 166 virtual bool didPassCORSAccessCheck() const; 167 168 virtual double mediaTimeForTimeValue(double timeValue) const; 169 170 // Provide statistics. 171 virtual unsigned decodedFrameCount() const; 172 virtual unsigned droppedFrameCount() const; 173 virtual unsigned audioDecodedByteCount() const; 174 virtual unsigned videoDecodedByteCount() const; 175 176 // cc::VideoFrameProvider implementation. These methods are running on the 177 // compositor thread. 178 virtual void SetVideoFrameProviderClient( 179 cc::VideoFrameProvider::Client* client) OVERRIDE; 180 virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE; 181 virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) 182 OVERRIDE; 183 184 // Media player callback handlers. 185 void OnMediaMetadataChanged(const base::TimeDelta& duration, int width, 186 int height, bool success); 187 void OnPlaybackComplete(); 188 void OnBufferingUpdate(int percentage); 189 void OnSeekRequest(const base::TimeDelta& time_to_seek); 190 void OnSeekComplete(const base::TimeDelta& current_time); 191 void OnMediaError(int error_type); 192 void OnVideoSizeChanged(int width, int height); 193 void OnDurationChanged(const base::TimeDelta& duration); 194 195 // Called to update the current time. 196 void OnTimeUpdate(base::TimeDelta current_timestamp, 197 base::TimeTicks current_time_ticks); 198 199 // Functions called when media player status changes. 200 void OnConnectedToRemoteDevice(const std::string& remote_playback_message); 201 void OnDisconnectedFromRemoteDevice(); 202 void OnDidEnterFullscreen(); 203 void OnDidExitFullscreen(); 204 void OnMediaPlayerPlay(); 205 void OnMediaPlayerPause(); 206 void OnRequestFullscreen(); 207 void OnRemoteRouteAvailabilityChanged(bool routes_available); 208 209 // StreamTextureFactoryContextObserver implementation. 210 virtual void ResetStreamTextureProxy() OVERRIDE; 211 212 // Called when the player is released. 213 virtual void OnPlayerReleased(); 214 215 // This function is called by the RendererMediaPlayerManager to pause the 216 // video and release the media player and surface texture when we switch tabs. 217 // However, the actual GlTexture is not released to keep the video screenshot. 218 virtual void ReleaseMediaResources(); 219 220 // RenderFrameObserver implementation. 221 virtual void OnDestruct() OVERRIDE; 222 223 #if defined(VIDEO_HOLE) 224 // Calculate the boundary rectangle of the media player (i.e. location and 225 // size of the video frame). 226 // Returns true if the geometry has been changed since the last call. 227 bool UpdateBoundaryRectangle(); 228 229 const gfx::RectF GetBoundaryRectangle(); 230 #endif // defined(VIDEO_HOLE) 231 232 virtual MediaKeyException generateKeyRequest( 233 const blink::WebString& key_system, 234 const unsigned char* init_data, 235 unsigned init_data_length); 236 virtual MediaKeyException addKey( 237 const blink::WebString& key_system, 238 const unsigned char* key, 239 unsigned key_length, 240 const unsigned char* init_data, 241 unsigned init_data_length, 242 const blink::WebString& session_id); 243 virtual MediaKeyException cancelKeyRequest( 244 const blink::WebString& key_system, 245 const blink::WebString& session_id); 246 // TODO(jrummell): Remove this method once Blink updated to use the other 247 // two methods. 248 virtual void setContentDecryptionModule( 249 blink::WebContentDecryptionModule* cdm); 250 virtual void setContentDecryptionModule( 251 blink::WebContentDecryptionModule* cdm, 252 blink::WebContentDecryptionModuleResult result); 253 254 void OnKeyAdded(const std::string& session_id); 255 void OnKeyError(const std::string& session_id, 256 media::MediaKeys::KeyError error_code, 257 uint32 system_code); 258 void OnKeyMessage(const std::string& session_id, 259 const std::vector<uint8>& message, 260 const GURL& destination_url); 261 262 void OnMediaSourceOpened(blink::WebMediaSource* web_media_source); 263 264 void OnNeedKey(const std::string& type, 265 const std::vector<uint8>& init_data); 266 267 // TODO(xhwang): Implement WebMediaPlayer::setContentDecryptionModule(). 268 // See: http://crbug.com/224786 269 270 protected: 271 // Helper method to update the playing state. 272 void UpdatePlayingState(bool is_playing_); 273 274 // Helper methods for posting task for setting states and update WebKit. 275 void UpdateNetworkState(blink::WebMediaPlayer::NetworkState state); 276 void UpdateReadyState(blink::WebMediaPlayer::ReadyState state); 277 void TryCreateStreamTextureProxyIfNeeded(); 278 void DoCreateStreamTexture(); 279 280 // Helper method to reestablish the surface texture peer for android 281 // media player. 282 void EstablishSurfaceTexturePeer(); 283 284 // Requesting whether the surface texture peer needs to be reestablished. 285 void SetNeedsEstablishPeer(bool needs_establish_peer); 286 287 private: 288 void InitializePlayer(const GURL& url, 289 const GURL& first_party_for_cookies, 290 bool allowed_stored_credentials, 291 int demuxer_client_id); 292 void Pause(bool is_media_related_action); 293 void DrawRemotePlaybackText(const std::string& remote_playback_message); 294 void ReallocateVideoFrame(); 295 void SetCurrentFrameInternal(scoped_refptr<media::VideoFrame>& frame); 296 void DidLoadMediaInfo(MediaInfoLoader::Status status, 297 const GURL& redirected_url, 298 const GURL& first_party_for_cookies, 299 bool allow_stored_credentials); 300 bool IsKeySystemSupported(const std::string& key_system); 301 bool IsLocalResource(); 302 303 // Actually do the work for generateKeyRequest/addKey so they can easily 304 // report results to UMA. 305 MediaKeyException GenerateKeyRequestInternal(const std::string& key_system, 306 const unsigned char* init_data, 307 unsigned init_data_length); 308 MediaKeyException AddKeyInternal(const std::string& key_system, 309 const unsigned char* key, 310 unsigned key_length, 311 const unsigned char* init_data, 312 unsigned init_data_length, 313 const std::string& session_id); 314 MediaKeyException CancelKeyRequestInternal(const std::string& key_system, 315 const std::string& session_id); 316 317 // Requests that this object notifies when a decryptor is ready through the 318 // |decryptor_ready_cb| provided. 319 // If |decryptor_ready_cb| is null, the existing callback will be fired with 320 // NULL immediately and reset. 321 void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb); 322 323 // Called when the ContentDecryptionModule has been attached to the 324 // pipeline/decoders. 325 void ContentDecryptionModuleAttached( 326 blink::WebContentDecryptionModuleResult result, 327 bool success); 328 329 bool EnsureTextureBackedSkBitmap(GrContext* gr, SkBitmap& bitmap, 330 const blink::WebSize& size, 331 GrSurfaceOrigin origin, 332 GrPixelConfig config); 333 334 bool IsHLSStream() const; 335 336 blink::WebFrame* const frame_; 337 338 blink::WebMediaPlayerClient* const client_; 339 340 // |delegate_| is used to notify the browser process of the player status, so 341 // that the browser process can control screen locks. 342 // TODO(qinmin): Currently android mediaplayer takes care of the screen 343 // lock. So this is only used for media source. Will apply this to regular 344 // media tag once http://crbug.com/247892 is fixed. 345 base::WeakPtr<media::WebMediaPlayerDelegate> delegate_; 346 347 // Save the list of buffered time ranges. 348 blink::WebTimeRanges buffered_; 349 350 // Size of the video. 351 blink::WebSize natural_size_; 352 353 // Size that has been sent to StreamTexture. 354 blink::WebSize cached_stream_texture_size_; 355 356 // The video frame object used for rendering by the compositor. 357 scoped_refptr<media::VideoFrame> current_frame_; 358 base::Lock current_frame_lock_; 359 360 base::ThreadChecker main_thread_checker_; 361 362 // Message loop for media thread. 363 const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; 364 365 // URL of the media file to be fetched. 366 GURL url_; 367 368 // URL of the media file after |media_info_loader_| resolves all the 369 // redirections. 370 GURL redirected_url_; 371 372 // Media duration. 373 base::TimeDelta duration_; 374 375 // Flag to remember if we have a trusted duration_ value provided by 376 // MediaSourceDelegate notifying OnDurationChanged(). In this case, ignore 377 // any subsequent duration value passed to OnMediaMetadataChange(). 378 bool ignore_metadata_duration_change_; 379 380 // Seek gets pending if another seek is in progress. Only last pending seek 381 // will have effect. 382 bool pending_seek_; 383 base::TimeDelta pending_seek_time_; 384 385 // Internal seek state. 386 bool seeking_; 387 base::TimeDelta seek_time_; 388 389 // Whether loading has progressed since the last call to didLoadingProgress. 390 bool did_loading_progress_; 391 392 // Manages this object and delegates player calls to the browser process. 393 // Owned by RenderFrameImpl. 394 RendererMediaPlayerManager* player_manager_; 395 396 // Delegates EME calls to the browser process. Owned by RenderFrameImpl. 397 // TODO(xhwang): Remove |cdm_manager_| when prefixed EME is deprecated. See 398 // http://crbug.com/249976 399 RendererCdmManager* cdm_manager_; 400 401 // Player ID assigned by the |player_manager_|. 402 int player_id_; 403 404 // Current player states. 405 blink::WebMediaPlayer::NetworkState network_state_; 406 blink::WebMediaPlayer::ReadyState ready_state_; 407 408 // GL texture ID allocated to the video. 409 unsigned int texture_id_; 410 411 // GL texture mailbox for texture_id_ to provide in the VideoFrame, and sync 412 // point for when the mailbox was produced. 413 gpu::Mailbox texture_mailbox_; 414 415 // Stream texture ID allocated to the video. 416 unsigned int stream_id_; 417 418 // Whether the mediaplayer is playing. 419 bool is_playing_; 420 421 // Whether media player needs to re-establish the surface texture peer. 422 bool needs_establish_peer_; 423 424 // Whether the video size info is available. 425 bool has_size_info_; 426 427 const scoped_refptr<base::MessageLoopProxy> compositor_loop_; 428 429 // Object for allocating stream textures. 430 scoped_refptr<StreamTextureFactory> stream_texture_factory_; 431 432 // Object for calling back the compositor thread to repaint the video when a 433 // frame available. It should be initialized on the compositor thread. 434 // Accessed on main thread and on compositor thread when main thread is 435 // blocked. 436 ScopedStreamTextureProxy stream_texture_proxy_; 437 438 // Whether media player needs external surface. 439 // Only used for the VIDEO_HOLE logic. 440 bool needs_external_surface_; 441 442 // A pointer back to the compositor to inform it about state changes. This is 443 // not NULL while the compositor is actively using this webmediaplayer. 444 // Accessed on main thread and on compositor thread when main thread is 445 // blocked. 446 cc::VideoFrameProvider::Client* video_frame_provider_client_; 447 448 scoped_ptr<cc_blink::WebLayerImpl> video_weblayer_; 449 450 #if defined(VIDEO_HOLE) 451 // A rectangle represents the geometry of video frame, when computed last 452 // time. 453 gfx::RectF last_computed_rect_; 454 455 // Whether to use the video overlay for all embedded video. 456 // True only for testing. 457 bool force_use_overlay_embedded_video_; 458 #endif // defined(VIDEO_HOLE) 459 460 MediaPlayerHostMsg_Initialize_Type player_type_; 461 462 // Whether the browser is currently connected to a remote media player. 463 bool is_remote_; 464 465 scoped_refptr<media::MediaLog> media_log_; 466 467 scoped_ptr<MediaInfoLoader> info_loader_; 468 469 // The currently selected key system. Empty string means that no key system 470 // has been selected. 471 std::string current_key_system_; 472 473 // Temporary for EME v0.1. In the future the init data type should be passed 474 // through GenerateKeyRequest() directly from WebKit. 475 std::string init_data_type_; 476 477 // Manages decryption keys and decrypts encrypted frames. 478 scoped_ptr<ProxyDecryptor> proxy_decryptor_; 479 480 // Non-owned pointer to the CDM. Updated via calls to 481 // setContentDecryptionModule(). 482 WebContentDecryptionModuleImpl* web_cdm_; 483 484 // This is only Used by Clear Key key system implementation, where a renderer 485 // side CDM will be used. This is similar to WebMediaPlayerImpl. For other key 486 // systems, a browser side CDM will be used and we set CDM by calling 487 // player_manager_->SetCdm() directly. 488 media::DecryptorReadyCB decryptor_ready_cb_; 489 490 SkBitmap bitmap_; 491 492 // Whether stored credentials are allowed to be passed to the server. 493 bool allow_stored_credentials_; 494 495 // Whether the resource is local. 496 bool is_local_resource_; 497 498 // base::TickClock used by |interpolator_|. 499 base::DefaultTickClock default_tick_clock_; 500 501 // Tracks the most recent media time update and provides interpolated values 502 // as playback progresses. 503 media::TimeDeltaInterpolator interpolator_; 504 505 scoped_ptr<MediaSourceDelegate> media_source_delegate_; 506 507 // NOTE: Weak pointers must be invalidated before all other member variables. 508 base::WeakPtrFactory<WebMediaPlayerAndroid> weak_factory_; 509 510 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid); 511 }; 512 513 } // namespace content 514 515 #endif // CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_ 516