| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/android/webmediaplayer_android.h" | 5 #include "content/renderer/media/android/webmediaplayer_android.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 #if defined(GOOGLE_TV) | 132 #if defined(GOOGLE_TV) |
| 133 if (CommandLine::ForCurrentProcess()->HasSwitch( | 133 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 134 switches::kUseExternalVideoSurfaceThresholdInPixels)) { | 134 switches::kUseExternalVideoSurfaceThresholdInPixels)) { |
| 135 if (!base::StringToInt( | 135 if (!base::StringToInt( |
| 136 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 136 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 137 switches::kUseExternalVideoSurfaceThresholdInPixels), | 137 switches::kUseExternalVideoSurfaceThresholdInPixels), |
| 138 &external_surface_threshold_)) { | 138 &external_surface_threshold_)) { |
| 139 external_surface_threshold_ = -1; | 139 external_surface_threshold_ = -1; |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 #endif // defined(GOOGLE_TV) |
| 142 | 143 |
| 144 #if defined(VIDEO_HOLE) |
| 143 // Defer stream texture creation until we are sure it's necessary. | 145 // Defer stream texture creation until we are sure it's necessary. |
| 144 stream_id_ = 0; | |
| 145 needs_establish_peer_ = false; | 146 needs_establish_peer_ = false; |
| 146 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1)); | 147 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1)); |
| 147 #endif | 148 #endif // defined(VIDEO_HOLE) |
| 148 TryCreateStreamTextureProxyIfNeeded(); | 149 TryCreateStreamTextureProxyIfNeeded(); |
| 149 | 150 |
| 150 if (blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled()) { | 151 if (blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled()) { |
| 151 // TODO(xhwang): Report an error when there is encrypted stream but EME is | 152 // TODO(xhwang): Report an error when there is encrypted stream but EME is |
| 152 // not enabled. Currently the player just doesn't start and waits for ever. | 153 // not enabled. Currently the player just doesn't start and waits for ever. |
| 153 decryptor_.reset(new ProxyDecryptor( | 154 decryptor_.reset(new ProxyDecryptor( |
| 154 #if defined(ENABLE_PEPPER_CDMS) | 155 #if defined(ENABLE_PEPPER_CDMS) |
| 155 client, | 156 client, |
| 156 frame, | 157 frame, |
| 157 #else | 158 #else |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 318 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
| 318 } | 319 } |
| 319 // Android doesn't start fetching resources until an implementation-defined | 320 // Android doesn't start fetching resources until an implementation-defined |
| 320 // event (e.g. playback request) occurs. Sets the network state to IDLE | 321 // event (e.g. playback request) occurs. Sets the network state to IDLE |
| 321 // if play is not requested yet. | 322 // if play is not requested yet. |
| 322 if (!playing_started_) | 323 if (!playing_started_) |
| 323 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); | 324 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); |
| 324 } | 325 } |
| 325 | 326 |
| 326 void WebMediaPlayerAndroid::play() { | 327 void WebMediaPlayerAndroid::play() { |
| 327 #if defined(GOOGLE_TV) | 328 #if defined(VIDEO_HOLE) |
| 328 if (hasVideo() && needs_external_surface_ && | 329 if (hasVideo() && needs_external_surface_ && |
| 329 !manager_->IsInFullscreen(frame_)) { | 330 !manager_->IsInFullscreen(frame_)) { |
| 330 DCHECK(!needs_establish_peer_); | 331 DCHECK(!needs_establish_peer_); |
| 331 manager_->RequestExternalSurface(player_id_, last_computed_rect_); | 332 manager_->RequestExternalSurface(player_id_, last_computed_rect_); |
| 332 } | 333 } |
| 334 #endif // defined(VIDEO_HOLE) |
| 335 #if defined(GOOGLE_TV) |
| 333 if (audio_renderer_ && paused()) | 336 if (audio_renderer_ && paused()) |
| 334 audio_renderer_->Play(); | 337 audio_renderer_->Play(); |
| 335 #endif | 338 #endif // defined(GOOGLE_TV) |
| 336 | 339 |
| 337 TryCreateStreamTextureProxyIfNeeded(); | 340 TryCreateStreamTextureProxyIfNeeded(); |
| 338 if (hasVideo() && needs_establish_peer_) | 341 if (hasVideo() && needs_establish_peer_) |
| 339 EstablishSurfaceTexturePeer(); | 342 EstablishSurfaceTexturePeer(); |
| 340 | 343 |
| 341 if (paused()) | 344 if (paused()) |
| 342 manager_->Start(player_id_); | 345 manager_->Start(player_id_); |
| 343 UpdatePlayingState(true); | 346 UpdatePlayingState(true); |
| 344 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); | 347 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 345 playing_started_ = true; | 348 playing_started_ = true; |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 break; | 722 break; |
| 720 } | 723 } |
| 721 client_->repaint(); | 724 client_->repaint(); |
| 722 } | 725 } |
| 723 | 726 |
| 724 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { | 727 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { |
| 725 has_size_info_ = true; | 728 has_size_info_ = true; |
| 726 if (natural_size_.width == width && natural_size_.height == height) | 729 if (natural_size_.width == width && natural_size_.height == height) |
| 727 return; | 730 return; |
| 728 | 731 |
| 732 #if defined(VIDEO_HOLE) |
| 733 bool has_surface_size_restriction = false; |
| 729 #if defined(GOOGLE_TV) | 734 #if defined(GOOGLE_TV) |
| 730 if ((external_surface_threshold_ >= 0 && | 735 has_surface_size_restriction = external_surface_threshold_ >= 0 && |
| 731 external_surface_threshold_ <= width * height) || | 736 external_surface_threshold_ <= width * height; |
| 732 // Use H/W surface for MSE as the content is protected. | 737 #endif // defined(GOOGLE_TV) |
| 733 media_source_delegate_) { | 738 // Use H/W surface for MSE as the content might be protected. |
| 739 // TODO(qinmin): Change this so that only EME needs the H/W surface |
| 740 if (media_source_delegate_ || has_surface_size_restriction) { |
| 734 needs_external_surface_ = true; | 741 needs_external_surface_ = true; |
| 735 if (!paused() && !manager_->IsInFullscreen(frame_)) | 742 if (!paused() && !manager_->IsInFullscreen(frame_)) |
| 736 manager_->RequestExternalSurface(player_id_, last_computed_rect_); | 743 manager_->RequestExternalSurface(player_id_, last_computed_rect_); |
| 737 } else if (stream_texture_factory_ && !stream_id_) { | 744 } else if (stream_texture_factory_ && !stream_id_) { |
| 738 // Do deferred stream texture creation finally. | 745 // Do deferred stream texture creation finally. |
| 739 DoCreateStreamTexture(); | 746 DoCreateStreamTexture(); |
| 740 if (paused()) { | 747 if (paused()) { |
| 741 SetNeedsEstablishPeer(true); | 748 SetNeedsEstablishPeer(true); |
| 742 } else { | 749 } else { |
| 743 EstablishSurfaceTexturePeer(); | 750 EstablishSurfaceTexturePeer(); |
| 744 } | 751 } |
| 745 } | 752 } |
| 746 #endif | 753 #endif // defined(VIDEO_HOLE) |
| 747 | 754 |
| 748 natural_size_.width = width; | 755 natural_size_.width = width; |
| 749 natural_size_.height = height; | 756 natural_size_.height = height; |
| 750 ReallocateVideoFrame(); | 757 ReallocateVideoFrame(); |
| 751 } | 758 } |
| 752 | 759 |
| 753 void WebMediaPlayerAndroid::OnTimeUpdate(const base::TimeDelta& current_time) { | 760 void WebMediaPlayerAndroid::OnTimeUpdate(const base::TimeDelta& current_time) { |
| 754 DCHECK(main_loop_->BelongsToCurrentThread()); | 761 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 755 current_time_ = current_time.InSecondsF(); | 762 current_time_ = current_time.InSecondsF(); |
| 756 } | 763 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 783 | 790 |
| 784 void WebMediaPlayerAndroid::OnDidExitFullscreen() { | 791 void WebMediaPlayerAndroid::OnDidExitFullscreen() { |
| 785 // |needs_external_surface_| is always false on non-TV devices. | 792 // |needs_external_surface_| is always false on non-TV devices. |
| 786 if (!needs_external_surface_) | 793 if (!needs_external_surface_) |
| 787 SetNeedsEstablishPeer(true); | 794 SetNeedsEstablishPeer(true); |
| 788 // We had the fullscreen surface connected to Android MediaPlayer, | 795 // We had the fullscreen surface connected to Android MediaPlayer, |
| 789 // so reconnect our surface texture for embedded playback. | 796 // so reconnect our surface texture for embedded playback. |
| 790 if (!paused() && needs_establish_peer_) | 797 if (!paused() && needs_establish_peer_) |
| 791 EstablishSurfaceTexturePeer(); | 798 EstablishSurfaceTexturePeer(); |
| 792 | 799 |
| 793 #if defined(GOOGLE_TV) | 800 #if defined(VIDEO_HOLE) |
| 794 if (!paused() && needs_external_surface_) | 801 if (!paused() && needs_external_surface_) |
| 795 manager_->RequestExternalSurface(player_id_, last_computed_rect_); | 802 manager_->RequestExternalSurface(player_id_, last_computed_rect_); |
| 796 #endif | 803 #endif // defined(VIDEO_HOLE) |
| 797 | 804 |
| 798 frame_->view()->willExitFullScreen(); | 805 frame_->view()->willExitFullScreen(); |
| 799 frame_->view()->didExitFullScreen(); | 806 frame_->view()->didExitFullScreen(); |
| 800 manager_->DidExitFullscreen(); | 807 manager_->DidExitFullscreen(); |
| 801 client_->repaint(); | 808 client_->repaint(); |
| 802 } | 809 } |
| 803 | 810 |
| 804 void WebMediaPlayerAndroid::OnMediaPlayerPlay() { | 811 void WebMediaPlayerAndroid::OnMediaPlayerPlay() { |
| 805 UpdatePlayingState(true); | 812 UpdatePlayingState(true); |
| 806 client_->playbackStateChanged(); | 813 client_->playbackStateChanged(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 WebMediaPlayer::ReadyState state) { | 859 WebMediaPlayer::ReadyState state) { |
| 853 ready_state_ = state; | 860 ready_state_ = state; |
| 854 client_->readyStateChanged(); | 861 client_->readyStateChanged(); |
| 855 } | 862 } |
| 856 | 863 |
| 857 void WebMediaPlayerAndroid::OnPlayerReleased() { | 864 void WebMediaPlayerAndroid::OnPlayerReleased() { |
| 858 // |needs_external_surface_| is always false on non-TV devices. | 865 // |needs_external_surface_| is always false on non-TV devices. |
| 859 if (!needs_external_surface_) | 866 if (!needs_external_surface_) |
| 860 needs_establish_peer_ = true; | 867 needs_establish_peer_ = true; |
| 861 | 868 |
| 862 #if defined(GOOGLE_TV) | 869 #if defined(VIDEO_HOLE) |
| 863 last_computed_rect_ = gfx::RectF(); | 870 last_computed_rect_ = gfx::RectF(); |
| 864 #endif | 871 #endif // defined(VIDEO_HOLE) |
| 865 } | 872 } |
| 866 | 873 |
| 867 void WebMediaPlayerAndroid::ReleaseMediaResources() { | 874 void WebMediaPlayerAndroid::ReleaseMediaResources() { |
| 868 switch (network_state_) { | 875 switch (network_state_) { |
| 869 // Pause the media player and inform WebKit if the player is in a good | 876 // Pause the media player and inform WebKit if the player is in a good |
| 870 // shape. | 877 // shape. |
| 871 case WebMediaPlayer::NetworkStateIdle: | 878 case WebMediaPlayer::NetworkStateIdle: |
| 872 case WebMediaPlayer::NetworkStateLoading: | 879 case WebMediaPlayer::NetworkStateLoading: |
| 873 case WebMediaPlayer::NetworkStateLoaded: | 880 case WebMediaPlayer::NetworkStateLoaded: |
| 874 pause(false); | 881 pause(false); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 gfx::Rect(canvas_size) /* visible_rect */, | 1008 gfx::Rect(canvas_size) /* visible_rect */, |
| 1002 canvas_size /* natural_size */, | 1009 canvas_size /* natural_size */, |
| 1003 base::TimeDelta() /* timestamp */, | 1010 base::TimeDelta() /* timestamp */, |
| 1004 VideoFrame::ReadPixelsCB(), | 1011 VideoFrame::ReadPixelsCB(), |
| 1005 base::Closure() /* no_longer_needed_cb */); | 1012 base::Closure() /* no_longer_needed_cb */); |
| 1006 SetCurrentFrameInternal(new_frame); | 1013 SetCurrentFrameInternal(new_frame); |
| 1007 } | 1014 } |
| 1008 | 1015 |
| 1009 void WebMediaPlayerAndroid::ReallocateVideoFrame() { | 1016 void WebMediaPlayerAndroid::ReallocateVideoFrame() { |
| 1010 if (needs_external_surface_) { | 1017 if (needs_external_surface_) { |
| 1011 // VideoFrame::CreateHoleFrame is only defined under GOOGLE_TV. | 1018 // VideoFrame::CreateHoleFrame is only defined under VIDEO_HOLE. |
| 1012 #if defined(GOOGLE_TV) | 1019 #if defined(VIDEO_HOLE) |
| 1013 if (!natural_size_.isEmpty()) { | 1020 if (!natural_size_.isEmpty()) { |
| 1014 scoped_refptr<VideoFrame> new_frame = | 1021 scoped_refptr<VideoFrame> new_frame = |
| 1015 VideoFrame::CreateHoleFrame(natural_size_); | 1022 VideoFrame::CreateHoleFrame(natural_size_); |
| 1016 SetCurrentFrameInternal(new_frame); | 1023 SetCurrentFrameInternal(new_frame); |
| 1017 // Force the client to grab the hole frame. | 1024 // Force the client to grab the hole frame. |
| 1018 client_->repaint(); | 1025 client_->repaint(); |
| 1019 } | 1026 } |
| 1020 #else | 1027 #else |
| 1021 NOTIMPLEMENTED() << "Hole punching not supported outside of Google TV"; | 1028 NOTIMPLEMENTED() << "Hole punching not supported without VIDEO_HOLE flag"; |
| 1022 #endif | 1029 #endif // defined(VIDEO_HOLE) |
| 1023 } else if (!is_remote_ && texture_id_) { | 1030 } else if (!is_remote_ && texture_id_) { |
| 1024 scoped_refptr<VideoFrame> new_frame = VideoFrame::WrapNativeTexture( | 1031 scoped_refptr<VideoFrame> new_frame = VideoFrame::WrapNativeTexture( |
| 1025 make_scoped_ptr(new VideoFrame::MailboxHolder( | 1032 make_scoped_ptr(new VideoFrame::MailboxHolder( |
| 1026 texture_mailbox_, | 1033 texture_mailbox_, |
| 1027 texture_mailbox_sync_point_, | 1034 texture_mailbox_sync_point_, |
| 1028 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())), | 1035 VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())), |
| 1029 kGLTextureExternalOES, | 1036 kGLTextureExternalOES, |
| 1030 natural_size_, | 1037 natural_size_, |
| 1031 gfx::Rect(natural_size_), | 1038 gfx::Rect(natural_size_), |
| 1032 natural_size_, | 1039 natural_size_, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) { | 1145 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) { |
| 1139 is_playing_ = is_playing; | 1146 is_playing_ = is_playing; |
| 1140 if (!delegate_) | 1147 if (!delegate_) |
| 1141 return; | 1148 return; |
| 1142 if (is_playing) | 1149 if (is_playing) |
| 1143 delegate_->DidPlay(this); | 1150 delegate_->DidPlay(this); |
| 1144 else | 1151 else |
| 1145 delegate_->DidPause(this); | 1152 delegate_->DidPause(this); |
| 1146 } | 1153 } |
| 1147 | 1154 |
| 1148 #if defined(GOOGLE_TV) | 1155 #if defined(VIDEO_HOLE) |
| 1149 bool WebMediaPlayerAndroid::RetrieveGeometryChange(gfx::RectF* rect) { | 1156 bool WebMediaPlayerAndroid::RetrieveGeometryChange(gfx::RectF* rect) { |
| 1150 if (!video_weblayer_) | 1157 if (!video_weblayer_) |
| 1151 return false; | 1158 return false; |
| 1152 | 1159 |
| 1153 // Compute the geometry of video frame layer. | 1160 // Compute the geometry of video frame layer. |
| 1154 cc::Layer* layer = video_weblayer_->layer(); | 1161 cc::Layer* layer = video_weblayer_->layer(); |
| 1155 rect->set_size(layer->bounds()); | 1162 rect->set_size(layer->bounds()); |
| 1156 while (layer) { | 1163 while (layer) { |
| 1157 rect->Offset(layer->position().OffsetFromOrigin()); | 1164 rect->Offset(layer->position().OffsetFromOrigin()); |
| 1158 layer = layer->parent(); | 1165 layer = layer->parent(); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 | 1452 |
| 1446 void WebMediaPlayerAndroid::exitFullscreen() { | 1453 void WebMediaPlayerAndroid::exitFullscreen() { |
| 1447 manager_->ExitFullscreen(player_id_); | 1454 manager_->ExitFullscreen(player_id_); |
| 1448 } | 1455 } |
| 1449 | 1456 |
| 1450 bool WebMediaPlayerAndroid::canEnterFullscreen() const { | 1457 bool WebMediaPlayerAndroid::canEnterFullscreen() const { |
| 1451 return manager_->CanEnterFullscreen(frame_); | 1458 return manager_->CanEnterFullscreen(frame_); |
| 1452 } | 1459 } |
| 1453 | 1460 |
| 1454 } // namespace content | 1461 } // namespace content |
| OLD | NEW |