| OLD | NEW |
| (Empty) |
| 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 <stdint.h> | |
| 9 | |
| 10 #include <memory> | |
| 11 #include <string> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/macros.h" | |
| 15 #include "base/memory/ref_counted.h" | |
| 16 #include "base/memory/weak_ptr.h" | |
| 17 #include "base/threading/thread_checker.h" | |
| 18 #include "base/time/default_tick_clock.h" | |
| 19 #include "base/time/time.h" | |
| 20 #include "cc/layers/video_frame_provider.h" | |
| 21 #include "content/renderer/media/android/media_info_loader.h" | |
| 22 #include "content/renderer/media/android/renderer_media_player_manager.h" | |
| 23 #include "content/renderer/media/android/stream_texture_factory.h" | |
| 24 #include "gpu/command_buffer/common/mailbox.h" | |
| 25 #include "media/base/android/media_player_android.h" | |
| 26 #include "media/base/time_delta_interpolator.h" | |
| 27 #include "media/blink/webmediaplayer_delegate.h" | |
| 28 #include "media/blink/webmediaplayer_params.h" | |
| 29 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" | |
| 30 #include "third_party/WebKit/public/platform/WebSetSinkIdCallbacks.h" | |
| 31 #include "third_party/WebKit/public/platform/WebSize.h" | |
| 32 #include "third_party/WebKit/public/platform/WebURL.h" | |
| 33 #include "ui/gfx/geometry/rect_f.h" | |
| 34 | |
| 35 namespace base { | |
| 36 class SingleThreadTaskRunner; | |
| 37 } | |
| 38 | |
| 39 namespace blink { | |
| 40 class WebFrame; | |
| 41 class WebMediaPlayerClient; | |
| 42 class WebMediaPlayerEncryptedMediaClient; | |
| 43 class WebURL; | |
| 44 enum class WebRemotePlaybackAvailability; | |
| 45 } | |
| 46 | |
| 47 namespace cc_blink { | |
| 48 class WebLayerImpl; | |
| 49 } | |
| 50 | |
| 51 namespace gpu { | |
| 52 namespace gles2 { | |
| 53 class GLES2Interface; | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 namespace media { | |
| 58 class MediaLog; | |
| 59 } | |
| 60 | |
| 61 namespace content { | |
| 62 | |
| 63 class RendererMediaPlayerManager; | |
| 64 | |
| 65 // This class implements blink::WebMediaPlayer by keeping the android | |
| 66 // media player in the browser process. It listens to all the status changes | |
| 67 // sent from the browser process and sends playback controls to the media | |
| 68 // player. | |
| 69 class WebMediaPlayerAndroid | |
| 70 : public blink::WebMediaPlayer, | |
| 71 public cc::VideoFrameProvider, | |
| 72 public media::RendererMediaPlayerInterface, | |
| 73 public NON_EXPORTED_BASE(media::WebMediaPlayerDelegate::Observer) { | |
| 74 public: | |
| 75 // Construct a WebMediaPlayerAndroid object. This class communicates with the | |
| 76 // MediaPlayerAndroid object in the browser process through |proxy|. | |
| 77 // TODO(qinmin): |frame| argument is used to determine whether the current | |
| 78 // player can enter fullscreen. This logic should probably be moved into | |
| 79 // blink, so that enteredFullscreen() will not be called if another video is | |
| 80 // already in fullscreen. | |
| 81 WebMediaPlayerAndroid( | |
| 82 blink::WebFrame* frame, | |
| 83 blink::WebMediaPlayerClient* client, | |
| 84 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, | |
| 85 media::WebMediaPlayerDelegate* delegate, | |
| 86 RendererMediaPlayerManager* player_manager, | |
| 87 scoped_refptr<StreamTextureFactory> factory, | |
| 88 int frame_id, | |
| 89 bool enable_texture_copy, | |
| 90 const media::WebMediaPlayerParams& params); | |
| 91 ~WebMediaPlayerAndroid() override; | |
| 92 | |
| 93 // blink::WebMediaPlayer implementation. | |
| 94 bool supportsOverlayFullscreenVideo() override; | |
| 95 void enteredFullscreen() override; | |
| 96 | |
| 97 // Resource loading. | |
| 98 void load(LoadType load_type, | |
| 99 const blink::WebMediaPlayerSource& source, | |
| 100 CORSMode cors_mode) override; | |
| 101 | |
| 102 // Playback controls. | |
| 103 void play() override; | |
| 104 void pause() override; | |
| 105 void seek(double seconds) override; | |
| 106 bool supportsSave() const override; | |
| 107 void setRate(double rate) override; | |
| 108 void setVolume(double volume) override; | |
| 109 void setSinkId(const blink::WebString& sink_id, | |
| 110 const blink::WebSecurityOrigin& security_origin, | |
| 111 blink::WebSetSinkIdCallbacks* web_callback) override; | |
| 112 void requestRemotePlayback() override; | |
| 113 void requestRemotePlaybackControl() override; | |
| 114 void requestRemotePlaybackStop() override; | |
| 115 blink::WebTimeRanges buffered() const override; | |
| 116 blink::WebTimeRanges seekable() const override; | |
| 117 | |
| 118 // Poster image, as defined in the <video> element. | |
| 119 void setPoster(const blink::WebURL& poster) override; | |
| 120 | |
| 121 // Methods for painting. | |
| 122 // FIXME: This path "only works" on Android. It is a workaround for the | |
| 123 // issue that Skia could not handle Android's GL_TEXTURE_EXTERNAL_OES texture | |
| 124 // internally. It should be removed and replaced by the normal paint path. | |
| 125 // https://code.google.com/p/skia/issues/detail?id=1189 | |
| 126 void paint(blink::WebCanvas* canvas, | |
| 127 const blink::WebRect& rect, | |
| 128 cc::PaintFlags&) override; | |
| 129 | |
| 130 bool copyVideoTextureToPlatformTexture(gpu::gles2::GLES2Interface* gl, | |
| 131 unsigned int texture, | |
| 132 bool premultiply_alpha, | |
| 133 bool flip_y) override; | |
| 134 | |
| 135 // True if the loaded media has a playable video/audio track. | |
| 136 bool hasVideo() const override; | |
| 137 bool hasAudio() const override; | |
| 138 | |
| 139 bool isRemote() const override; | |
| 140 | |
| 141 // Dimensions of the video. | |
| 142 blink::WebSize naturalSize() const override; | |
| 143 | |
| 144 // Getters of playback state. | |
| 145 bool paused() const override; | |
| 146 bool seeking() const override; | |
| 147 double duration() const override; | |
| 148 virtual double timelineOffset() const; | |
| 149 double currentTime() const override; | |
| 150 | |
| 151 bool didLoadingProgress() override; | |
| 152 | |
| 153 // Internal states of loading and network. | |
| 154 blink::WebMediaPlayer::NetworkState getNetworkState() const override; | |
| 155 blink::WebMediaPlayer::ReadyState getReadyState() const override; | |
| 156 | |
| 157 blink::WebString getErrorMessage() override; | |
| 158 | |
| 159 bool hasSingleSecurityOrigin() const override; | |
| 160 bool didPassCORSAccessCheck() const override; | |
| 161 | |
| 162 double mediaTimeForTimeValue(double timeValue) const override; | |
| 163 | |
| 164 // Provide statistics. | |
| 165 unsigned decodedFrameCount() const override; | |
| 166 unsigned droppedFrameCount() const override; | |
| 167 size_t audioDecodedByteCount() const override; | |
| 168 size_t videoDecodedByteCount() const override; | |
| 169 | |
| 170 // cc::VideoFrameProvider implementation. These methods are running on the | |
| 171 // compositor thread. | |
| 172 void SetVideoFrameProviderClient( | |
| 173 cc::VideoFrameProvider::Client* client) override; | |
| 174 bool UpdateCurrentFrame(base::TimeTicks deadline_min, | |
| 175 base::TimeTicks deadline_max) override; | |
| 176 bool HasCurrentFrame() override; | |
| 177 scoped_refptr<media::VideoFrame> GetCurrentFrame() override; | |
| 178 void PutCurrentFrame() override; | |
| 179 | |
| 180 // Media player callback handlers. | |
| 181 void OnMediaMetadataChanged(base::TimeDelta duration, int width, | |
| 182 int height, bool success) override; | |
| 183 void OnPlaybackComplete() override; | |
| 184 void OnBufferingUpdate(int percentage) override; | |
| 185 void OnSeekRequest(const base::TimeDelta& time_to_seek) override; | |
| 186 void OnSeekComplete(const base::TimeDelta& current_time) override; | |
| 187 void OnMediaError(int error_type) override; | |
| 188 void OnVideoSizeChanged(int width, int height) override; | |
| 189 | |
| 190 // Called to update the current time. | |
| 191 void OnTimeUpdate(base::TimeDelta current_timestamp, | |
| 192 base::TimeTicks current_time_ticks) override; | |
| 193 | |
| 194 // Functions called when media player status changes. | |
| 195 void OnConnectedToRemoteDevice(const std::string& remote_playback_message) | |
| 196 override; | |
| 197 void OnDisconnectedFromRemoteDevice() override; | |
| 198 void OnCancelledRemotePlaybackRequest() override; | |
| 199 void OnRemotePlaybackStarted() override; | |
| 200 void OnDidExitFullscreen() override; | |
| 201 void OnMediaPlayerPlay() override; | |
| 202 void OnMediaPlayerPause() override; | |
| 203 void OnRemoteRouteAvailabilityChanged( | |
| 204 blink::WebRemotePlaybackAvailability availability) override; | |
| 205 | |
| 206 // Called when the player is released. | |
| 207 void OnPlayerReleased() override; | |
| 208 | |
| 209 // This function is called by the RendererMediaPlayerManager to pause the | |
| 210 // video and release the media player and surface texture when we switch tabs. | |
| 211 // However, the actual GlTexture is not released to keep the video screenshot. | |
| 212 void SuspendAndReleaseResources() override; | |
| 213 | |
| 214 // WebMediaPlayerDelegate::Observer implementation. | |
| 215 void OnFrameHidden() override; | |
| 216 void OnFrameClosed() override; | |
| 217 void OnFrameShown() override; | |
| 218 void OnIdleTimeout() override; | |
| 219 void OnPlay() override; | |
| 220 void OnPause() override; | |
| 221 void OnVolumeMultiplierUpdate(double multiplier) override; | |
| 222 | |
| 223 protected: | |
| 224 // Helper method to update the playing state. | |
| 225 void UpdatePlayingState(bool is_playing_); | |
| 226 | |
| 227 // Helper methods for posting task for setting states and update WebKit. | |
| 228 void UpdateNetworkState(blink::WebMediaPlayer::NetworkState state); | |
| 229 void UpdateReadyState(blink::WebMediaPlayer::ReadyState state); | |
| 230 void TryCreateStreamTextureProxyIfNeeded(); | |
| 231 | |
| 232 // Helper method to reestablish the surface texture peer for android | |
| 233 // media player. | |
| 234 void EstablishSurfaceTexturePeer(); | |
| 235 | |
| 236 // Requesting whether the surface texture peer needs to be reestablished. | |
| 237 void SetNeedsEstablishPeer(bool needs_establish_peer); | |
| 238 | |
| 239 private: | |
| 240 void InitializePlayer(const GURL& url, | |
| 241 const GURL& first_party_for_cookies, | |
| 242 bool allowed_stored_credentials); | |
| 243 void Pause(bool is_media_related_action); | |
| 244 void DrawRemotePlaybackText(const std::string& remote_playback_message); | |
| 245 void ReallocateVideoFrame(); | |
| 246 void SetCurrentFrameInternal(scoped_refptr<media::VideoFrame>& frame); | |
| 247 void DidLoadMediaInfo(MediaInfoLoader::Status status, | |
| 248 const GURL& redirected_url, | |
| 249 const GURL& first_party_for_cookies, | |
| 250 bool allow_stored_credentials); | |
| 251 bool IsLocalResource(); | |
| 252 | |
| 253 // Called whenever we create a new StreamTextureProxy and had a VFP::Client, | |
| 254 // or when we get a new VFP::Client and had a StreamTextureProxy. | |
| 255 // Sets |stream_texture_proxy_|'s OnFrameAvailable() to call |client|'s | |
| 256 // DidReceiveFrame(). | |
| 257 // Passing nullptr to this method will clear the previous callback. | |
| 258 void UpdateStreamTextureProxyCallback(cc::VideoFrameProvider::Client* client); | |
| 259 | |
| 260 bool IsHLSStream() const; | |
| 261 // Report whether the loaded url, after following redirects, points to a HLS | |
| 262 // playlist, and record the origin of the player. | |
| 263 void ReportHLSMetrics() const; | |
| 264 | |
| 265 // Called after |defer_load_cb_| has decided to allow the load. If | |
| 266 // |defer_load_cb_| is null this is called immediately. | |
| 267 void DoLoad(LoadType load_type, const blink::WebURL& url, CORSMode cors_mode); | |
| 268 | |
| 269 // Returns if this video can be resumed in the background. | |
| 270 bool IsBackgroundVideoCandidate() const; | |
| 271 | |
| 272 blink::WebFrame* const frame_; | |
| 273 | |
| 274 blink::WebMediaPlayerClient* const client_; | |
| 275 | |
| 276 // WebMediaPlayer notifies the |delegate_| of playback state changes using | |
| 277 // |delegate_id_|; an id provided after registering with the delegate. The | |
| 278 // WebMediaPlayer may also receive directives (play, pause) from the delegate | |
| 279 // via the WebMediaPlayerDelegate::Observer interface after registration. | |
| 280 // | |
| 281 // NOTE: HTMLMediaElement is a Blink::SuspendableObject, and will receive a | |
| 282 // call to contextDestroyed() when Blink::Document::shutdown() is called. | |
| 283 // Document::shutdown() is called before the frame detaches (and before the | |
| 284 // frame is destroyed). RenderFrameImpl owns |delegate_| and is guaranteed | |
| 285 // to outlive |this|; thus it is safe to store |delegate_| as a raw pointer. | |
| 286 media::WebMediaPlayerDelegate* delegate_; | |
| 287 int delegate_id_; | |
| 288 | |
| 289 // Callback responsible for determining if loading of media should be deferred | |
| 290 // for external reasons; called during load(). | |
| 291 media::WebMediaPlayerParams::DeferLoadCB defer_load_cb_; | |
| 292 | |
| 293 // Save the list of buffered time ranges. | |
| 294 blink::WebTimeRanges buffered_; | |
| 295 | |
| 296 // Size of the video. | |
| 297 blink::WebSize natural_size_; | |
| 298 | |
| 299 // Size that has been sent to gpu::StreamTexture. | |
| 300 blink::WebSize cached_stream_texture_size_; | |
| 301 | |
| 302 // The video frame object used for rendering by the compositor. | |
| 303 scoped_refptr<media::VideoFrame> current_frame_; | |
| 304 base::Lock current_frame_lock_; | |
| 305 | |
| 306 // A lazily created transparent video frame to be displayed in fullscreen. | |
| 307 scoped_refptr<media::VideoFrame> fullscreen_frame_; | |
| 308 | |
| 309 base::ThreadChecker main_thread_checker_; | |
| 310 | |
| 311 // Message loop for media thread. | |
| 312 const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; | |
| 313 | |
| 314 // URL of the media file to be fetched. | |
| 315 GURL url_; | |
| 316 | |
| 317 // URL of the media file after |media_info_loader_| resolves all the | |
| 318 // redirections. | |
| 319 GURL redirected_url_; | |
| 320 | |
| 321 // Media duration. | |
| 322 base::TimeDelta duration_; | |
| 323 | |
| 324 // Seek gets pending if another seek is in progress. Only last pending seek | |
| 325 // will have effect. | |
| 326 bool pending_seek_; | |
| 327 base::TimeDelta pending_seek_time_; | |
| 328 | |
| 329 // Internal seek state. | |
| 330 bool seeking_; | |
| 331 base::TimeDelta seek_time_; | |
| 332 | |
| 333 // Whether loading has progressed since the last call to didLoadingProgress. | |
| 334 bool did_loading_progress_; | |
| 335 | |
| 336 // Manages this object and delegates player calls to the browser process. | |
| 337 // Owned by RenderFrameImpl. | |
| 338 RendererMediaPlayerManager* const player_manager_; | |
| 339 | |
| 340 // Player ID assigned by the |player_manager_|. | |
| 341 int player_id_; | |
| 342 | |
| 343 // Current player states. | |
| 344 blink::WebMediaPlayer::NetworkState network_state_; | |
| 345 blink::WebMediaPlayer::ReadyState ready_state_; | |
| 346 | |
| 347 // GL texture ID allocated to the video. | |
| 348 unsigned int texture_id_; | |
| 349 | |
| 350 // GL texture mailbox for texture_id_ to provide in the VideoFrame, and sync | |
| 351 // point for when the mailbox was produced. | |
| 352 gpu::Mailbox texture_mailbox_; | |
| 353 | |
| 354 // Whether the media player has been initialized. | |
| 355 bool is_player_initialized_; | |
| 356 | |
| 357 // Whether the media player is playing. | |
| 358 bool is_playing_; | |
| 359 | |
| 360 // Whether the media player is pending to play. | |
| 361 bool is_play_pending_; | |
| 362 | |
| 363 // Whether media player needs to re-establish the surface texture peer. | |
| 364 bool needs_establish_peer_; | |
| 365 | |
| 366 // Whether the video size info is available. | |
| 367 bool has_size_info_; | |
| 368 | |
| 369 const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | |
| 370 | |
| 371 // Object for allocating stream textures. | |
| 372 scoped_refptr<StreamTextureFactory> stream_texture_factory_; | |
| 373 | |
| 374 // Object for calling back the compositor thread to repaint the video when a | |
| 375 // frame available. It should be initialized on the compositor thread. | |
| 376 // Accessed on main thread and on compositor thread when main thread is | |
| 377 // blocked. | |
| 378 ScopedStreamTextureProxy stream_texture_proxy_; | |
| 379 | |
| 380 // Whether the player is in fullscreen. | |
| 381 bool is_fullscreen_; | |
| 382 | |
| 383 // A pointer back to the compositor to inform it about state changes. This is | |
| 384 // not NULL while the compositor is actively using this webmediaplayer. | |
| 385 // Accessed on main thread and on compositor thread when main thread is | |
| 386 // blocked. | |
| 387 cc::VideoFrameProvider::Client* video_frame_provider_client_; | |
| 388 | |
| 389 std::unique_ptr<cc_blink::WebLayerImpl> video_weblayer_; | |
| 390 | |
| 391 MediaPlayerHostMsg_Initialize_Type player_type_; | |
| 392 | |
| 393 // Whether the browser is currently connected to a remote media player. | |
| 394 bool is_remote_; | |
| 395 | |
| 396 scoped_refptr<media::MediaLog> media_log_; | |
| 397 | |
| 398 std::unique_ptr<MediaInfoLoader> info_loader_; | |
| 399 | |
| 400 // Whether stored credentials are allowed to be passed to the server. | |
| 401 bool allow_stored_credentials_; | |
| 402 | |
| 403 // Whether the resource is local. | |
| 404 bool is_local_resource_; | |
| 405 | |
| 406 // base::TickClock used by |interpolator_|. | |
| 407 base::DefaultTickClock default_tick_clock_; | |
| 408 | |
| 409 // Tracks the most recent media time update and provides interpolated values | |
| 410 // as playback progresses. | |
| 411 media::TimeDeltaInterpolator interpolator_; | |
| 412 | |
| 413 int frame_id_; | |
| 414 | |
| 415 // Whether to require that surface textures are copied in order to support | |
| 416 // sharing between render and gpu threads in WebView. | |
| 417 bool enable_texture_copy_; | |
| 418 | |
| 419 // Whether to delete the existing texture and re-create it. | |
| 420 bool suppress_deleting_texture_; | |
| 421 | |
| 422 // Whether OnPlaybackComplete() has been called since the last playback. | |
| 423 bool playback_completed_; | |
| 424 | |
| 425 // The last volume received by setVolume() and the last volume multiplier from | |
| 426 // OnVolumeMultiplierUpdate(). The multiplier is typical 1.0, but may be less | |
| 427 // if the WebMediaPlayerDelegate has requested a volume reduction (ducking) | |
| 428 // for a transient sound. Playout volume is derived by volume * multiplier. | |
| 429 double volume_; | |
| 430 double volume_multiplier_; | |
| 431 | |
| 432 // NOTE: Weak pointers must be invalidated before all other member variables. | |
| 433 base::WeakPtrFactory<WebMediaPlayerAndroid> weak_factory_; | |
| 434 | |
| 435 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid); | |
| 436 }; | |
| 437 | |
| 438 } // namespace content | |
| 439 | |
| 440 #endif // CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_ | |
| OLD | NEW |