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

Side by Side Diff: media/blink/webmediaplayer_impl.cc

Issue 1053113002: Prime the landing pad for the new video rendering pipeline. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix cc_unittests Created 5 years, 8 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 "media/blink/webmediaplayer_impl.h" 5 #include "media/blink/webmediaplayer_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 ended_(false), 127 ended_(false),
128 pending_seek_(false), 128 pending_seek_(false),
129 pending_seek_seconds_(0.0f), 129 pending_seek_seconds_(0.0f),
130 should_notify_time_changed_(false), 130 should_notify_time_changed_(false),
131 client_(client), 131 client_(client),
132 delegate_(delegate), 132 delegate_(delegate),
133 defer_load_cb_(params.defer_load_cb()), 133 defer_load_cb_(params.defer_load_cb()),
134 context_3d_cb_(params.context_3d_cb()), 134 context_3d_cb_(params.context_3d_cb()),
135 supports_save_(true), 135 supports_save_(true),
136 chunk_demuxer_(NULL), 136 chunk_demuxer_(NULL),
137 compositor_task_runner_(params.compositor_task_runner()), 137 // Threaded compositing isn't enabled universally yet.
138 compositor_task_runner_(
139 params.compositor_task_runner()
140 ? params.compositor_task_runner()
141 : base::MessageLoop::current()->task_runner()),
138 compositor_(new VideoFrameCompositor( 142 compositor_(new VideoFrameCompositor(
143 compositor_task_runner_,
139 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), 144 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged),
140 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), 145 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))),
141 encrypted_media_support_( 146 encrypted_media_support_(
142 cdm_factory.Pass(), 147 cdm_factory.Pass(),
143 client, 148 client,
144 params.media_permission(), 149 params.media_permission(),
145 base::Bind(&WebMediaPlayerImpl::SetCdm, AsWeakPtr())), 150 base::Bind(&WebMediaPlayerImpl::SetCdm, AsWeakPtr())),
146 renderer_factory_(renderer_factory.Pass()) { 151 renderer_factory_(renderer_factory.Pass()) {
147 // Threaded compositing isn't enabled universally yet.
148 if (!compositor_task_runner_.get())
149 compositor_task_runner_ = base::MessageLoopProxy::current();
150
151 media_log_->AddEvent( 152 media_log_->AddEvent(
152 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 153 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED));
153 154
154 if (params.initial_cdm()) { 155 if (params.initial_cdm()) {
155 SetCdm( 156 SetCdm(
156 ToWebContentDecryptionModuleImpl(params.initial_cdm())->GetCdmContext(), 157 ToWebContentDecryptionModuleImpl(params.initial_cdm())->GetCdmContext(),
157 base::Bind(&IgnoreCdmAttached)); 158 base::Bind(&IgnoreCdmAttached));
158 } 159 }
159 160
160 // TODO(xhwang): When we use an external Renderer, many methods won't work, 161 // TODO(xhwang): When we use an external Renderer, many methods won't work,
161 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 162 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861
162 163
163 // Use the null sink if no sink was provided. 164 // Use the null sink if no sink was provided.
164 audio_source_provider_ = new WebAudioSourceProviderImpl( 165 audio_source_provider_ = new WebAudioSourceProviderImpl(
165 params.audio_renderer_sink().get() 166 params.audio_renderer_sink().get()
166 ? params.audio_renderer_sink() 167 ? params.audio_renderer_sink()
167 : new NullAudioSink(media_task_runner_)); 168 : new NullAudioSink(media_task_runner_));
168 } 169 }
169 170
170 WebMediaPlayerImpl::~WebMediaPlayerImpl() { 171 WebMediaPlayerImpl::~WebMediaPlayerImpl() {
171 client_->setWebLayer(NULL); 172 client_->setWebLayer(NULL);
172 173
173 DCHECK(main_task_runner_->BelongsToCurrentThread()); 174 DCHECK(main_task_runner_->BelongsToCurrentThread());
174 media_log_->AddEvent( 175 media_log_->AddEvent(
175 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); 176 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
176 177
177 if (delegate_) 178 if (delegate_)
178 delegate_->PlayerGone(this); 179 delegate_->PlayerGone(this);
180 compositor_->StopRendering();
179 181
180 // Abort any pending IO so stopping the pipeline doesn't get blocked. 182 // Abort any pending IO so stopping the pipeline doesn't get blocked.
181 if (data_source_) 183 if (data_source_)
182 data_source_->Abort(); 184 data_source_->Abort();
183 if (chunk_demuxer_) { 185 if (chunk_demuxer_) {
184 chunk_demuxer_->Shutdown(); 186 chunk_demuxer_->Shutdown();
185 chunk_demuxer_ = NULL; 187 chunk_demuxer_ = NULL;
186 } 188 }
187 189
188 renderer_factory_.reset(); 190 renderer_factory_.reset();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 DVLOG(1) << __FUNCTION__; 253 DVLOG(1) << __FUNCTION__;
252 DCHECK(main_task_runner_->BelongsToCurrentThread()); 254 DCHECK(main_task_runner_->BelongsToCurrentThread());
253 255
254 paused_ = false; 256 paused_ = false;
255 pipeline_.SetPlaybackRate(playback_rate_); 257 pipeline_.SetPlaybackRate(playback_rate_);
256 if (data_source_) 258 if (data_source_)
257 data_source_->MediaIsPlaying(); 259 data_source_->MediaIsPlaying();
258 260
259 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); 261 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY));
260 262
261 if (delegate_ && playback_rate_ > 0) 263 if (playback_rate_ > 0) {
262 delegate_->DidPlay(this); 264 compositor_->StartRendering();
265 if (delegate_)
266 delegate_->DidPlay(this);
267 }
263 } 268 }
264 269
265 void WebMediaPlayerImpl::pause() { 270 void WebMediaPlayerImpl::pause() {
266 DVLOG(1) << __FUNCTION__; 271 DVLOG(1) << __FUNCTION__;
267 DCHECK(main_task_runner_->BelongsToCurrentThread()); 272 DCHECK(main_task_runner_->BelongsToCurrentThread());
268 273
269 const bool was_already_paused = paused_ || playback_rate_ == 0; 274 const bool was_already_paused = paused_ || playback_rate_ == 0;
270 paused_ = true; 275 paused_ = true;
271 pipeline_.SetPlaybackRate(0.0f); 276 pipeline_.SetPlaybackRate(0.0f);
272 if (data_source_) 277 if (data_source_)
273 data_source_->MediaIsPaused(); 278 data_source_->MediaIsPaused();
274 UpdatePausedTime(); 279 UpdatePausedTime();
275 280
276 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); 281 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE));
277 282
278 if (!was_already_paused && delegate_) 283 if (!was_already_paused) {
279 delegate_->DidPause(this); 284 compositor_->StopRendering();
285 if (delegate_)
286 delegate_->DidPause(this);
287 }
280 } 288 }
281 289
282 bool WebMediaPlayerImpl::supportsSave() const { 290 bool WebMediaPlayerImpl::supportsSave() const {
283 DCHECK(main_task_runner_->BelongsToCurrentThread()); 291 DCHECK(main_task_runner_->BelongsToCurrentThread());
284 return supports_save_; 292 return supports_save_;
285 } 293 }
286 294
287 void WebMediaPlayerImpl::seek(double seconds) { 295 void WebMediaPlayerImpl::seek(double seconds) {
288 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; 296 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)";
289 DCHECK(main_task_runner_->BelongsToCurrentThread()); 297 DCHECK(main_task_runner_->BelongsToCurrentThread());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // following checks so rewind uses reasonable values also. 349 // following checks so rewind uses reasonable values also.
342 if (rate < 0.0) 350 if (rate < 0.0)
343 return; 351 return;
344 352
345 // Limit rates to reasonable values by clamping. 353 // Limit rates to reasonable values by clamping.
346 if (rate != 0.0) { 354 if (rate != 0.0) {
347 if (rate < kMinRate) 355 if (rate < kMinRate)
348 rate = kMinRate; 356 rate = kMinRate;
349 else if (rate > kMaxRate) 357 else if (rate > kMaxRate)
350 rate = kMaxRate; 358 rate = kMaxRate;
351 if (playback_rate_ == 0 && !paused_ && delegate_) 359 if (playback_rate_ == 0 && !paused_) {
352 delegate_->DidPlay(this); 360 compositor_->StartRendering();
353 } else if (playback_rate_ != 0 && !paused_ && delegate_) { 361 if (delegate_)
354 delegate_->DidPause(this); 362 delegate_->DidPlay(this);
363 }
364 } else if (playback_rate_ != 0 && !paused_) {
365 compositor_->StopRendering();
366 if (delegate_)
367 delegate_->DidPause(this);
355 } 368 }
356 369
357 playback_rate_ = rate; 370 playback_rate_ = rate;
358 if (!paused_) { 371 if (!paused_) {
359 pipeline_.SetPlaybackRate(rate); 372 pipeline_.SetPlaybackRate(rate);
360 if (data_source_) 373 if (data_source_)
361 data_source_->MediaPlaybackRateChanged(rate); 374 data_source_->MediaPlaybackRateChanged(rate);
362 } 375 }
363 } 376 }
364 377
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), 910 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened),
898 encrypted_media_init_data_cb, mse_log_cb, media_log_, true); 911 encrypted_media_init_data_cb, mse_log_cb, media_log_, true);
899 demuxer_.reset(chunk_demuxer_); 912 demuxer_.reset(chunk_demuxer_);
900 } 913 }
901 914
902 // ... and we're ready to go! 915 // ... and we're ready to go!
903 seeking_ = true; 916 seeking_ = true;
904 917
905 pipeline_.Start( 918 pipeline_.Start(
906 demuxer_.get(), 919 demuxer_.get(),
907 renderer_factory_->CreateRenderer(media_task_runner_, 920 renderer_factory_->CreateRenderer(
908 audio_source_provider_.get()), 921 media_task_runner_, audio_source_provider_.get(), compositor_),
909 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), 922 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
910 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), 923 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
911 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false), 924 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false),
912 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), 925 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata),
913 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), 926 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged),
914 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
915 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged), 927 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged),
916 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack), 928 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack),
917 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey)); 929 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey));
918 } 930 }
919 931
920 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { 932 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) {
921 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; 933 DVLOG(1) << __FUNCTION__ << "(" << state << ")";
922 DCHECK(main_task_runner_->BelongsToCurrentThread()); 934 DCHECK(main_task_runner_->BelongsToCurrentThread());
923 network_state_ = state; 935 network_state_ = state;
924 // Always notify to ensure client has the latest value. 936 // Always notify to ensure client has the latest value.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 987
976 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { 988 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) {
977 DCHECK(main_task_runner_->BelongsToCurrentThread()); 989 DCHECK(main_task_runner_->BelongsToCurrentThread());
978 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); 990 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing);
979 991
980 opaque_ = opaque; 992 opaque_ = opaque;
981 if (video_weblayer_) 993 if (video_weblayer_)
982 video_weblayer_->setOpaque(opaque_); 994 video_weblayer_->setOpaque(opaque_);
983 } 995 }
984 996
985 void WebMediaPlayerImpl::FrameReady(
986 const scoped_refptr<VideoFrame>& frame) {
987 compositor_task_runner_->PostTask(
988 FROM_HERE,
989 base::Bind(&VideoFrameCompositor::UpdateCurrentFrame,
990 base::Unretained(compositor_),
991 frame));
992 }
993
994 static void GetCurrentFrameAndSignal(
995 VideoFrameCompositor* compositor,
996 scoped_refptr<VideoFrame>* video_frame_out,
997 base::WaitableEvent* event) {
998 TRACE_EVENT0("media", "GetCurrentFrameAndSignal");
999 *video_frame_out = compositor->GetCurrentFrame();
1000 event->Signal();
1001 }
1002
1003 scoped_refptr<VideoFrame> 997 scoped_refptr<VideoFrame>
1004 WebMediaPlayerImpl::GetCurrentFrameFromCompositor() { 998 WebMediaPlayerImpl::GetCurrentFrameFromCompositor() {
1005 TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor"); 999 TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
1006 if (compositor_task_runner_->BelongsToCurrentThread()) 1000 // Since the compositor is driving frame collection, this should be at most
1007 return compositor_->GetCurrentFrame(); 1001 // one frame off; which is as good as we can get without a push based model.
1008 1002 return compositor_->GetCurrentFrame();
1009 // Use a posted task and waitable event instead of a lock otherwise
1010 // WebGL/Canvas can see different content than what the compositor is seeing.
1011 scoped_refptr<VideoFrame> video_frame;
1012 base::WaitableEvent event(false, false);
1013 compositor_task_runner_->PostTask(FROM_HERE,
1014 base::Bind(&GetCurrentFrameAndSignal,
1015 base::Unretained(compositor_),
1016 &video_frame,
1017 &event));
1018 event.Wait();
1019 return video_frame;
1020 } 1003 }
1021 1004
1022 void WebMediaPlayerImpl::UpdatePausedTime() { 1005 void WebMediaPlayerImpl::UpdatePausedTime() {
1023 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1006 DCHECK(main_task_runner_->BelongsToCurrentThread());
1024 1007
1025 // pause() may be called after playback has ended and the HTMLMediaElement 1008 // pause() may be called after playback has ended and the HTMLMediaElement
1026 // requires that currentTime() == duration() after ending. We want to ensure 1009 // requires that currentTime() == duration() after ending. We want to ensure
1027 // |paused_time_| matches currentTime() in this case or a future seek() may 1010 // |paused_time_| matches currentTime() in this case or a future seek() may
1028 // incorrectly discard what it thinks is a seek to the existing time. 1011 // incorrectly discard what it thinks is a seek to the existing time.
1029 paused_time_ = 1012 paused_time_ =
1030 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); 1013 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime();
1031 } 1014 }
1032 1015
1033 } // namespace media 1016 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698