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

Side by Side Diff: media/renderers/renderer_impl.cc

Issue 1935873002: Implement disabling and enabling media tracks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@track-control2
Patch Set: Minor improvements Created 4 years, 7 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
« media/base/demuxer_stream.h ('K') | « media/renderers/renderer_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/renderers/renderer_impl.h" 5 #include "media/renderers/renderer_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 194 }
195 195
196 time_source_->SetMediaTime(time); 196 time_source_->SetMediaTime(time);
197 197
198 if (audio_renderer_) 198 if (audio_renderer_)
199 audio_renderer_->StartPlaying(); 199 audio_renderer_->StartPlaying();
200 if (video_renderer_) 200 if (video_renderer_)
201 video_renderer_->StartPlayingFrom(time); 201 video_renderer_->StartPlayingFrom(time);
202 } 202 }
203 203
204 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream,
205 base::TimeDelta time) {
206 DVLOG(1) << __FUNCTION__ << " stream=" << stream
207 << " time=" << time.InSecondsF();
208 DCHECK(task_runner_->BelongsToCurrentThread());
209 if (stream->type() == DemuxerStream::VIDEO) {
210 DCHECK(video_renderer_);
211 DCHECK(video_ended_);
212 video_ended_ = false;
213 restarting_video_ = true;
214 video_renderer_->Flush(base::Bind(
215 &RendererImpl::OnVideoRendererFlushDone_ForRestart, weak_this_, time));
216 } else if (stream->type() == DemuxerStream::AUDIO) {
217 DCHECK(audio_renderer_);
218 DCHECK(time_source_);
219 DCHECK(audio_ended_);
220 audio_ended_ = false;
221 restarting_audio_ = true;
222 // We need to stop ticking (transition into paused state) before calling
223 // Flush, since after Flush we'll need to restart playback by invoking
224 // StartPlaying that dchecks we are not in playing state.
wolenetz 2016/05/27 20:49:42 nit: we usually don't refer to implementation deta
servolk 2016/06/01 17:36:16 Done.
225 time_ticking_ = false;
226 time_source_->StopTicking();
227 audio_renderer_->Flush(base::Bind(
228 &RendererImpl::OnAudioRendererFlushDone_ForRestart, weak_this_, time));
229 }
230 }
231
232 void RendererImpl::OnVideoRendererFlushDone_ForRestart(base::TimeDelta time) {
233 DCHECK(task_runner_->BelongsToCurrentThread());
234 if (state_ == STATE_PLAYING) {
235 DCHECK(video_renderer_);
236 // TODO(servolk): VideoRenderer should ensure that Flush callback is called
237 // outside of its internal lock, to allow calling renderer methods directly.
238 task_runner_->PostTask(
239 FROM_HERE, base::Bind(&VideoRenderer::StartPlayingFrom,
240 base::Unretained(video_renderer_.get()), time));
241 }
242 }
243
244 void RendererImpl::OnAudioRendererFlushDone_ForRestart(base::TimeDelta time) {
245 DCHECK(task_runner_->BelongsToCurrentThread());
246 if (state_ == STATE_PLAYING) {
247 DCHECK(time_source_);
248 DCHECK(audio_renderer_);
249 audio_renderer_->StartPlaying();
250 }
251 }
252
204 void RendererImpl::SetPlaybackRate(double playback_rate) { 253 void RendererImpl::SetPlaybackRate(double playback_rate) {
205 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 254 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
206 DCHECK(task_runner_->BelongsToCurrentThread()); 255 DCHECK(task_runner_->BelongsToCurrentThread());
207 256
208 // Playback rate changes are only carried out while playing. 257 // Playback rate changes are only carried out while playing.
209 if (state_ != STATE_PLAYING) 258 if (state_ != STATE_PLAYING)
210 return; 259 return;
211 260
212 time_source_->SetPlaybackRate(playback_rate); 261 time_source_->SetPlaybackRate(playback_rate);
213 262
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 ? &audio_buffering_state_ 544 ? &audio_buffering_state_
496 : &video_buffering_state_; 545 : &video_buffering_state_;
497 546
498 DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", " 547 DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", "
499 << new_buffering_state << ") " 548 << new_buffering_state << ") "
500 << (type == DemuxerStream::AUDIO ? "audio" : "video"); 549 << (type == DemuxerStream::AUDIO ? "audio" : "video");
501 DCHECK(task_runner_->BelongsToCurrentThread()); 550 DCHECK(task_runner_->BelongsToCurrentThread());
502 551
503 bool was_waiting_for_enough_data = WaitingForEnoughData(); 552 bool was_waiting_for_enough_data = WaitingForEnoughData();
504 553
554 // When restarting video stream playback we want to ignore the
555 // BUFFERING_HAVE_NOTHING notification so that audio keeps playing while
556 // video decoder is catching up.
557 if (type == DemuxerStream::VIDEO && restarting_video_) {
558 if (new_buffering_state == BUFFERING_HAVE_NOTHING) {
559 DVLOG(1) << __FUNCTION__ << " Ignoring BUFFERING_HAVE_NOTHING for video "
560 "stream which is being restarted.";
561 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) {
562 DVLOG(1)
563 << __FUNCTION__
564 << " Got BUFFERING_HAVE_ENOUGH for video stream, resuming playback.";
565 restarting_video_ = false;
566 if (playback_rate_ > 0)
567 video_renderer_->OnTimeStateChanged(true);
568 }
569 return;
570 }
571
572 if (type == DemuxerStream::AUDIO && restarting_audio_) {
573 if (new_buffering_state == BUFFERING_HAVE_NOTHING) {
574 DVLOG(1) << __FUNCTION__ << " Ignoring BUFFERING_HAVE_NOTHING for "
575 << (type == DemuxerStream::AUDIO ? "audio" : "video")
576 << " stream";
577 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) {
578 DVLOG(1) << __FUNCTION__ << " Got BUFFERING_HAVE_ENOUGH for "
579 << (type == DemuxerStream::AUDIO ? "audio" : "video")
580 << " stream";
581
582 restarting_audio_ = false;
583
584 // Now that we have decoded enough audio, pause and unpause playback
585 // momentarily to ensure video renderer is synchronised with audio.
586 double curr_playback_rate = playback_rate_;
587 SetPlaybackRate(0);
588 SetPlaybackRate(curr_playback_rate);
589
590 time_source_->StartTicking();
591 }
592 return;
593 }
594
505 // When audio is present and has enough data, defer video underflow callbacks 595 // When audio is present and has enough data, defer video underflow callbacks
506 // for some time to avoid unnecessary glitches in audio; see 596 // for some time to avoid unnecessary glitches in audio; see
507 // http://crbug.com/144683#c53. 597 // http://crbug.com/144683#c53.
508 if (audio_renderer_ && type == DemuxerStream::VIDEO && 598 if (audio_renderer_ && type == DemuxerStream::VIDEO &&
509 state_ == STATE_PLAYING) { 599 state_ == STATE_PLAYING) {
510 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && 600 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
511 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH && 601 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
512 new_buffering_state == BUFFERING_HAVE_NOTHING && 602 new_buffering_state == BUFFERING_HAVE_NOTHING &&
513 deferred_underflow_cb_.IsCancelled()) { 603 deferred_underflow_cb_.IsCancelled()) {
514 deferred_underflow_cb_.Reset( 604 deferred_underflow_cb_.Reset(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 DCHECK(!time_ticking_); 695 DCHECK(!time_ticking_);
606 DCHECK(!WaitingForEnoughData()); 696 DCHECK(!WaitingForEnoughData());
607 697
608 time_ticking_ = true; 698 time_ticking_ = true;
609 time_source_->StartTicking(); 699 time_source_->StartTicking();
610 if (playback_rate_ > 0 && video_renderer_) 700 if (playback_rate_ > 0 && video_renderer_)
611 video_renderer_->OnTimeStateChanged(true); 701 video_renderer_->OnTimeStateChanged(true);
612 } 702 }
613 703
614 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) { 704 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) {
615 DVLOG(1) << __FUNCTION__; 705 DVLOG(1) << __FUNCTION__
706 << (type == DemuxerStream::AUDIO ? " audio" : " video");
616 DCHECK(task_runner_->BelongsToCurrentThread()); 707 DCHECK(task_runner_->BelongsToCurrentThread());
617 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); 708 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO));
618 709
619 if (state_ != STATE_PLAYING) 710 if (state_ != STATE_PLAYING)
620 return; 711 return;
621 712
622 if (type == DemuxerStream::AUDIO) { 713 if (type == DemuxerStream::AUDIO) {
623 DCHECK(!audio_ended_); 714 DCHECK(!audio_ended_);
624 audio_ended_ = true; 715 audio_ended_ = true;
625 } else { 716 } else {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 DCHECK(task_runner_->BelongsToCurrentThread()); 782 DCHECK(task_runner_->BelongsToCurrentThread());
692 client_->OnVideoNaturalSizeChange(size); 783 client_->OnVideoNaturalSizeChange(size);
693 } 784 }
694 785
695 void RendererImpl::OnVideoOpacityChange(bool opaque) { 786 void RendererImpl::OnVideoOpacityChange(bool opaque) {
696 DCHECK(task_runner_->BelongsToCurrentThread()); 787 DCHECK(task_runner_->BelongsToCurrentThread());
697 client_->OnVideoOpacityChange(opaque); 788 client_->OnVideoOpacityChange(opaque);
698 } 789 }
699 790
700 } // namespace media 791 } // namespace media
OLDNEW
« media/base/demuxer_stream.h ('K') | « media/renderers/renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698