Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(899)

Side by Side Diff: content/renderer/media/android/webmediaplayer_android.cc

Issue 545993002: Provide fine grained media playback time thru interpolation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase again Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 13 matching lines...) Expand all
24 #include "content/renderer/media/android/renderer_demuxer_android.h" 24 #include "content/renderer/media/android/renderer_demuxer_android.h"
25 #include "content/renderer/media/android/renderer_media_player_manager.h" 25 #include "content/renderer/media/android/renderer_media_player_manager.h"
26 #include "content/renderer/media/crypto/key_systems.h" 26 #include "content/renderer/media/crypto/key_systems.h"
27 #include "content/renderer/media/crypto/renderer_cdm_manager.h" 27 #include "content/renderer/media/crypto/renderer_cdm_manager.h"
28 #include "content/renderer/media/webcontentdecryptionmodule_impl.h" 28 #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
29 #include "content/renderer/render_frame_impl.h" 29 #include "content/renderer/render_frame_impl.h"
30 #include "content/renderer/render_thread_impl.h" 30 #include "content/renderer/render_thread_impl.h"
31 #include "gpu/GLES2/gl2extchromium.h" 31 #include "gpu/GLES2/gl2extchromium.h"
32 #include "gpu/command_buffer/client/gles2_interface.h" 32 #include "gpu/command_buffer/client/gles2_interface.h"
33 #include "gpu/command_buffer/common/mailbox_holder.h" 33 #include "gpu/command_buffer/common/mailbox_holder.h"
34 #include "media/base/android/media_common_android.h"
34 #include "media/base/android/media_player_android.h" 35 #include "media/base/android/media_player_android.h"
35 #include "media/base/bind_to_current_loop.h" 36 #include "media/base/bind_to_current_loop.h"
36 // TODO(xhwang): Remove when we remove prefixed EME implementation. 37 // TODO(xhwang): Remove when we remove prefixed EME implementation.
37 #include "media/base/media_keys.h" 38 #include "media/base/media_keys.h"
38 #include "media/base/media_log.h" 39 #include "media/base/media_log.h"
39 #include "media/base/media_switches.h" 40 #include "media/base/media_switches.h"
40 #include "media/base/video_frame.h" 41 #include "media/base/video_frame.h"
41 #include "media/blink/webmediaplayer_delegate.h" 42 #include "media/blink/webmediaplayer_delegate.h"
42 #include "media/blink/webmediaplayer_util.h" 43 #include "media/blink/webmediaplayer_util.h"
43 #include "net/base/mime_util.h" 44 #include "net/base/mime_util.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 is_playing_(false), 137 is_playing_(false),
137 needs_establish_peer_(true), 138 needs_establish_peer_(true),
138 stream_texture_proxy_initialized_(false), 139 stream_texture_proxy_initialized_(false),
139 has_size_info_(false), 140 has_size_info_(false),
140 stream_texture_factory_(factory), 141 stream_texture_factory_(factory),
141 needs_external_surface_(false), 142 needs_external_surface_(false),
142 has_valid_metadata_(false), 143 has_valid_metadata_(false),
143 video_frame_provider_client_(NULL), 144 video_frame_provider_client_(NULL),
144 pending_playback_(false), 145 pending_playback_(false),
145 player_type_(MEDIA_PLAYER_TYPE_URL), 146 player_type_(MEDIA_PLAYER_TYPE_URL),
146 current_time_(0),
147 is_remote_(false), 147 is_remote_(false),
148 media_log_(media_log), 148 media_log_(media_log),
149 web_cdm_(NULL), 149 web_cdm_(NULL),
150 allow_stored_credentials_(false), 150 allow_stored_credentials_(false),
151 is_local_resource_(false), 151 is_local_resource_(false),
152 interpolator_(&default_tick_clock_),
152 weak_factory_(this) { 153 weak_factory_(this) {
153 DCHECK(player_manager_); 154 DCHECK(player_manager_);
154 DCHECK(cdm_manager_); 155 DCHECK(cdm_manager_);
155 156
156 DCHECK(main_thread_checker_.CalledOnValidThread()); 157 DCHECK(main_thread_checker_.CalledOnValidThread());
157 158
158 player_id_ = player_manager_->RegisterMediaPlayer(this); 159 player_id_ = player_manager_->RegisterMediaPlayer(this);
159 160
160 #if defined(VIDEO_HOLE) 161 #if defined(VIDEO_HOLE)
161 force_use_overlay_embedded_video_ = CommandLine::ForCurrentProcess()-> 162 force_use_overlay_embedded_video_ = CommandLine::ForCurrentProcess()->
162 HasSwitch(switches::kForceUseOverlayEmbeddedVideo); 163 HasSwitch(switches::kForceUseOverlayEmbeddedVideo);
163 if (force_use_overlay_embedded_video_ || 164 if (force_use_overlay_embedded_video_ ||
164 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) { 165 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) {
165 // Defer stream texture creation until we are sure it's necessary. 166 // Defer stream texture creation until we are sure it's necessary.
166 needs_establish_peer_ = false; 167 needs_establish_peer_ = false;
167 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1)); 168 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
168 } 169 }
169 #endif // defined(VIDEO_HOLE) 170 #endif // defined(VIDEO_HOLE)
170 TryCreateStreamTextureProxyIfNeeded(); 171 TryCreateStreamTextureProxyIfNeeded();
172 interpolator_.SetUpperBound(base::TimeDelta());
171 } 173 }
172 174
173 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 175 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
174 DCHECK(main_thread_checker_.CalledOnValidThread()); 176 DCHECK(main_thread_checker_.CalledOnValidThread());
175 SetVideoFrameProviderClient(NULL); 177 SetVideoFrameProviderClient(NULL);
176 client_->setWebLayer(NULL); 178 client_->setWebLayer(NULL);
177 179
178 if (player_manager_) { 180 if (player_manager_) {
179 player_manager_->DestroyPlayer(player_id_); 181 player_manager_->DestroyPlayer(player_id_);
180 player_manager_->UnregisterMediaPlayer(player_id_); 182 player_manager_->UnregisterMediaPlayer(player_id_);
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 460
459 double WebMediaPlayerAndroid::currentTime() const { 461 double WebMediaPlayerAndroid::currentTime() const {
460 DCHECK(main_thread_checker_.CalledOnValidThread()); 462 DCHECK(main_thread_checker_.CalledOnValidThread());
461 // If the player is processing a seek, return the seek time. 463 // If the player is processing a seek, return the seek time.
462 // Blink may still query us if updatePlaybackState() occurs while seeking. 464 // Blink may still query us if updatePlaybackState() occurs while seeking.
463 if (seeking()) { 465 if (seeking()) {
464 return pending_seek_ ? 466 return pending_seek_ ?
465 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF(); 467 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF();
466 } 468 }
467 469
468 return current_time_; 470 return std::min(
471 (const_cast<media::TimeDeltaInterpolator*>(
472 &interpolator_))->GetInterpolatedTime(), duration_).InSecondsF();
469 } 473 }
470 474
471 WebSize WebMediaPlayerAndroid::naturalSize() const { 475 WebSize WebMediaPlayerAndroid::naturalSize() const {
472 return natural_size_; 476 return natural_size_;
473 } 477 }
474 478
475 WebMediaPlayer::NetworkState WebMediaPlayerAndroid::networkState() const { 479 WebMediaPlayer::NetworkState WebMediaPlayerAndroid::networkState() const {
476 return network_state_; 480 return network_state_;
477 } 481 }
478 482
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 DCHECK(main_thread_checker_.CalledOnValidThread()); 715 DCHECK(main_thread_checker_.CalledOnValidThread());
712 bool need_to_signal_duration_changed = false; 716 bool need_to_signal_duration_changed = false;
713 717
714 if (is_local_resource_) 718 if (is_local_resource_)
715 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); 719 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
716 720
717 // Update duration, if necessary, prior to ready state updates that may 721 // Update duration, if necessary, prior to ready state updates that may
718 // cause duration() query. 722 // cause duration() query.
719 if (!ignore_metadata_duration_change_ && duration_ != duration) { 723 if (!ignore_metadata_duration_change_ && duration_ != duration) {
720 duration_ = duration; 724 duration_ = duration;
721 725 if (is_local_resource_)
726 buffered_[0].end = duration_.InSecondsF();
722 // Client readyState transition from HAVE_NOTHING to HAVE_METADATA 727 // Client readyState transition from HAVE_NOTHING to HAVE_METADATA
723 // already triggers a durationchanged event. If this is a different 728 // already triggers a durationchanged event. If this is a different
724 // transition, remember to signal durationchanged. 729 // transition, remember to signal durationchanged.
725 // Do not ever signal durationchanged on metadata change in MSE case 730 // Do not ever signal durationchanged on metadata change in MSE case
726 // because OnDurationChanged() handles this. 731 // because OnDurationChanged() handles this.
727 if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing && 732 if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing &&
728 player_type_ != MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { 733 player_type_ != MEDIA_PLAYER_TYPE_MEDIA_SOURCE) {
729 need_to_signal_duration_changed = true; 734 need_to_signal_duration_changed = true;
730 } 735 }
731 } 736 }
(...skipping 12 matching lines...) Expand all
744 749
745 if (need_to_signal_duration_changed) 750 if (need_to_signal_duration_changed)
746 client_->durationChanged(); 751 client_->durationChanged();
747 } 752 }
748 753
749 void WebMediaPlayerAndroid::OnPlaybackComplete() { 754 void WebMediaPlayerAndroid::OnPlaybackComplete() {
750 // When playback is about to finish, android media player often stops 755 // When playback is about to finish, android media player often stops
751 // at a time which is smaller than the duration. This makes webkit never 756 // at a time which is smaller than the duration. This makes webkit never
752 // know that the playback has finished. To solve this, we set the 757 // know that the playback has finished. To solve this, we set the
753 // current time to media duration when OnPlaybackComplete() get called. 758 // current time to media duration when OnPlaybackComplete() get called.
754 OnTimeUpdate(duration_); 759 interpolator_.SetBounds(duration_, duration_);
755 client_->timeChanged(); 760 client_->timeChanged();
756 761
757 // if the loop attribute is set, timeChanged() will update the current time 762 // if the loop attribute is set, timeChanged() will update the current time
758 // to 0. It will perform a seek to 0. As the requests to the renderer 763 // to 0. It will perform a seek to 0. As the requests to the renderer
759 // process are sequential, the OnSeekComplete() will only occur 764 // process are sequential, the OnSeekComplete() will only occur
760 // once OnPlaybackComplete() is done. As the playback can only be executed 765 // once OnPlaybackComplete() is done. As the playback can only be executed
761 // upon completion of OnSeekComplete(), the request needs to be saved. 766 // upon completion of OnSeekComplete(), the request needs to be saved.
762 is_playing_ = false; 767 is_playing_ = false;
763 if (seeking_ && seek_time_ == base::TimeDelta()) 768 if (seeking_ && seek_time_ == base::TimeDelta())
764 pending_playback_ = true; 769 pending_playback_ = true;
(...skipping 11 matching lines...) Expand all
776 781
777 void WebMediaPlayerAndroid::OnSeekComplete( 782 void WebMediaPlayerAndroid::OnSeekComplete(
778 const base::TimeDelta& current_time) { 783 const base::TimeDelta& current_time) {
779 DCHECK(main_thread_checker_.CalledOnValidThread()); 784 DCHECK(main_thread_checker_.CalledOnValidThread());
780 seeking_ = false; 785 seeking_ = false;
781 if (pending_seek_) { 786 if (pending_seek_) {
782 pending_seek_ = false; 787 pending_seek_ = false;
783 seek(pending_seek_time_.InSecondsF()); 788 seek(pending_seek_time_.InSecondsF());
784 return; 789 return;
785 } 790 }
786 791 interpolator_.SetBounds(current_time, current_time);
787 OnTimeUpdate(current_time);
788 792
789 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 793 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
790 794
791 client_->timeChanged(); 795 client_->timeChanged();
792 796
793 if (pending_playback_) { 797 if (pending_playback_) {
794 play(); 798 play();
795 pending_playback_ = false; 799 pending_playback_ = false;
796 } 800 }
797 } 801 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0))); 865 cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0)));
862 client_->setWebLayer(video_weblayer_.get()); 866 client_->setWebLayer(video_weblayer_.get());
863 } 867 }
864 868
865 // TODO(qinmin): This is a hack. We need the media element to stop showing the 869 // TODO(qinmin): This is a hack. We need the media element to stop showing the
866 // poster image by forcing it to call setDisplayMode(video). Should move the 870 // poster image by forcing it to call setDisplayMode(video). Should move the
867 // logic into HTMLMediaElement.cpp. 871 // logic into HTMLMediaElement.cpp.
868 client_->timeChanged(); 872 client_->timeChanged();
869 } 873 }
870 874
871 void WebMediaPlayerAndroid::OnTimeUpdate(const base::TimeDelta& current_time) { 875 void WebMediaPlayerAndroid::OnTimeUpdate(base::TimeDelta current_timestamp,
876 base::TimeTicks current_time_ticks) {
872 DCHECK(main_thread_checker_.CalledOnValidThread()); 877 DCHECK(main_thread_checker_.CalledOnValidThread());
873 current_time_ = current_time.InSecondsF(); 878 // Compensate the current_timestamp with the IPC latency.
874 if (is_local_resource_ && current_time_ <= duration()) 879 base::TimeDelta lower_bound =
875 buffered_[0].end = current_time_; 880 base::TimeTicks::Now() - current_time_ticks + current_timestamp;
881 base::TimeDelta upper_bound = lower_bound;
882 // We should get another time update in about |kTimeUpdateInterval|
883 // milliseconds.
884 if (is_playing_) {
885 upper_bound += base::TimeDelta::FromMilliseconds(
886 media::kTimeUpdateInterval);
887 }
888 // if the lower_bound is smaller than the current time, just use the current
889 // time so that the timer is always progressing.
890 lower_bound =
891 std::min(lower_bound, base::TimeDelta::FromSecondsD(currentTime()));
892 interpolator_.SetBounds(lower_bound, upper_bound);
876 } 893 }
877 894
878 void WebMediaPlayerAndroid::OnConnectedToRemoteDevice( 895 void WebMediaPlayerAndroid::OnConnectedToRemoteDevice(
879 const std::string& remote_playback_message) { 896 const std::string& remote_playback_message) {
880 DCHECK(main_thread_checker_.CalledOnValidThread()); 897 DCHECK(main_thread_checker_.CalledOnValidThread());
881 DCHECK(!media_source_delegate_); 898 DCHECK(!media_source_delegate_);
882 DrawRemotePlaybackText(remote_playback_message); 899 DrawRemotePlaybackText(remote_playback_message);
883 is_remote_ = true; 900 is_remote_ = true;
884 SetNeedsEstablishPeer(false); 901 SetNeedsEstablishPeer(false);
885 } 902 }
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 void WebMediaPlayerAndroid::setPoster(const blink::WebURL& poster) { 1304 void WebMediaPlayerAndroid::setPoster(const blink::WebURL& poster) {
1288 player_manager_->SetPoster(player_id_, poster); 1305 player_manager_->SetPoster(player_id_, poster);
1289 } 1306 }
1290 1307
1291 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) { 1308 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
1292 const bool was_playing = is_playing_; 1309 const bool was_playing = is_playing_;
1293 is_playing_ = is_playing; 1310 is_playing_ = is_playing;
1294 if (!delegate_ || was_playing == is_playing_) 1311 if (!delegate_ || was_playing == is_playing_)
1295 return; 1312 return;
1296 if (is_playing) 1313 if (is_playing)
1314 interpolator_.StartInterpolating();
1315 else
1316 interpolator_.StopInterpolating();
1317 if (is_playing)
1297 delegate_->DidPlay(this); 1318 delegate_->DidPlay(this);
1298 else 1319 else
1299 delegate_->DidPause(this); 1320 delegate_->DidPause(this);
1300 } 1321 }
1301 1322
1302 #if defined(VIDEO_HOLE) 1323 #if defined(VIDEO_HOLE)
1303 bool WebMediaPlayerAndroid::UpdateBoundaryRectangle() { 1324 bool WebMediaPlayerAndroid::UpdateBoundaryRectangle() {
1304 if (!video_weblayer_) 1325 if (!video_weblayer_)
1305 return false; 1326 return false;
1306 1327
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 1791
1771 bool WebMediaPlayerAndroid::IsHLSStream() const { 1792 bool WebMediaPlayerAndroid::IsHLSStream() const {
1772 std::string mime; 1793 std::string mime;
1773 GURL url = redirected_url_.is_empty() ? url_ : redirected_url_; 1794 GURL url = redirected_url_.is_empty() ? url_ : redirected_url_;
1774 if (!net::GetMimeTypeFromFile(base::FilePath(url.path()), &mime)) 1795 if (!net::GetMimeTypeFromFile(base::FilePath(url.path()), &mime))
1775 return false; 1796 return false;
1776 return !mime.compare("application/x-mpegurl"); 1797 return !mime.compare("application/x-mpegurl");
1777 } 1798 }
1778 1799
1779 } // namespace content 1800 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/android/webmediaplayer_android.h ('k') | media/base/android/media_common_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698