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

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: rebase + buildfix Created 4 years, 6 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 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 DCHECK_EQ(state_, STATE_UNINITIALIZED); 122 DCHECK_EQ(state_, STATE_UNINITIALIZED);
123 DCHECK(!init_cb.is_null()); 123 DCHECK(!init_cb.is_null());
124 DCHECK(client); 124 DCHECK(client);
125 DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) || 125 DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) ||
126 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO)); 126 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO));
127 127
128 client_ = client; 128 client_ = client;
129 demuxer_stream_provider_ = demuxer_stream_provider; 129 demuxer_stream_provider_ = demuxer_stream_provider;
130 init_cb_ = init_cb; 130 init_cb_ = init_cb;
131 131
132 DemuxerStream* audio_stream =
133 demuxer_stream_provider->GetStream(DemuxerStream::AUDIO);
134 if (audio_stream)
135 audio_stream->SetStreamRestartedCB(
136 base::Bind(&RendererImpl::RestartStreamPlayback, weak_this_));
137 DemuxerStream* video_stream =
138 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO);
139 if (video_stream)
140 video_stream->SetStreamRestartedCB(
141 base::Bind(&RendererImpl::RestartStreamPlayback, weak_this_));
142
132 if (HasEncryptedStream() && !cdm_context_) { 143 if (HasEncryptedStream() && !cdm_context_) {
133 state_ = STATE_INIT_PENDING_CDM; 144 state_ = STATE_INIT_PENDING_CDM;
134 return; 145 return;
135 } 146 }
136 147
137 state_ = STATE_INITIALIZING; 148 state_ = STATE_INITIALIZING;
138 InitializeAudioRenderer(); 149 InitializeAudioRenderer();
139 } 150 }
140 151
141 void RendererImpl::SetCdm(CdmContext* cdm_context, 152 void RendererImpl::SetCdm(CdmContext* cdm_context,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 205 }
195 206
196 time_source_->SetMediaTime(time); 207 time_source_->SetMediaTime(time);
197 208
198 if (audio_renderer_) 209 if (audio_renderer_)
199 audio_renderer_->StartPlaying(); 210 audio_renderer_->StartPlaying();
200 if (video_renderer_) 211 if (video_renderer_)
201 video_renderer_->StartPlayingFrom(time); 212 video_renderer_->StartPlayingFrom(time);
202 } 213 }
203 214
215 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream,
216 base::TimeDelta time) {
217 DVLOG(1) << __FUNCTION__ << " stream=" << stream
218 << " time=" << time.InSecondsF();
219 DCHECK(task_runner_->BelongsToCurrentThread());
220 if (stream->type() == DemuxerStream::VIDEO) {
221 DCHECK(video_renderer_);
222 DCHECK(video_ended_);
223 video_ended_ = false;
224 restarting_video_ = true;
225 video_renderer_->Flush(
226 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
227 } else if (stream->type() == DemuxerStream::AUDIO) {
228 DCHECK(audio_renderer_);
229 DCHECK(time_source_);
230 DCHECK(audio_ended_);
231 audio_ended_ = false;
232 restarting_audio_ = true;
233 // Stop ticking (transition into paused state) in audio renderer before
234 // calling Flush, since after Flush we are going to restart playback by
235 // calling audio renderer StartPlaying which would fail in playing state.
236 time_ticking_ = false;
237 time_source_->StopTicking();
238 audio_renderer_->Flush(
239 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time));
240 }
241 }
242
243 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) {
244 DCHECK(task_runner_->BelongsToCurrentThread());
245 if (state_ == STATE_PLAYING) {
246 DCHECK(video_renderer_);
247 video_renderer_->StartPlayingFrom(time);
248 }
249 }
250
251 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) {
252 DCHECK(task_runner_->BelongsToCurrentThread());
253 if (state_ == STATE_PLAYING) {
254 DCHECK(time_source_);
255 DCHECK(audio_renderer_);
256 audio_renderer_->StartPlaying();
257 }
258 }
259
204 void RendererImpl::SetPlaybackRate(double playback_rate) { 260 void RendererImpl::SetPlaybackRate(double playback_rate) {
205 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 261 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
206 DCHECK(task_runner_->BelongsToCurrentThread()); 262 DCHECK(task_runner_->BelongsToCurrentThread());
207 263
208 // Playback rate changes are only carried out while playing. 264 // Playback rate changes are only carried out while playing.
209 if (state_ != STATE_PLAYING) 265 if (state_ != STATE_PLAYING)
210 return; 266 return;
211 267
212 time_source_->SetPlaybackRate(playback_rate); 268 time_source_->SetPlaybackRate(playback_rate);
213 269
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 ? &audio_buffering_state_ 551 ? &audio_buffering_state_
496 : &video_buffering_state_; 552 : &video_buffering_state_;
497 553
498 DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", " 554 DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", "
499 << new_buffering_state << ") " 555 << new_buffering_state << ") "
500 << (type == DemuxerStream::AUDIO ? "audio" : "video"); 556 << (type == DemuxerStream::AUDIO ? "audio" : "video");
501 DCHECK(task_runner_->BelongsToCurrentThread()); 557 DCHECK(task_runner_->BelongsToCurrentThread());
502 558
503 bool was_waiting_for_enough_data = WaitingForEnoughData(); 559 bool was_waiting_for_enough_data = WaitingForEnoughData();
504 560
561 // When restarting video stream playback we want to ignore the
562 // BUFFERING_HAVE_NOTHING notification so that audio keeps playing while
563 // video decoder is catching up.
564 if (type == DemuxerStream::VIDEO && restarting_video_) {
565 if (new_buffering_state == BUFFERING_HAVE_NOTHING) {
566 DVLOG(1) << __FUNCTION__ << " Ignoring BUFFERING_HAVE_NOTHING for video "
567 "stream which is being restarted.";
568 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) {
569 DVLOG(1)
570 << __FUNCTION__
571 << " Got BUFFERING_HAVE_ENOUGH for video stream, resuming playback.";
572 restarting_video_ = false;
573 if (playback_rate_ > 0)
574 video_renderer_->OnTimeStateChanged(true);
575 }
576 return;
577 }
578
579 if (type == DemuxerStream::AUDIO && restarting_audio_) {
580 if (new_buffering_state == BUFFERING_HAVE_NOTHING) {
581 DVLOG(1) << __FUNCTION__ << " Ignoring BUFFERING_HAVE_NOTHING for "
582 << (type == DemuxerStream::AUDIO ? "audio" : "video")
583 << " stream";
584 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) {
585 DVLOG(1) << __FUNCTION__ << " Got BUFFERING_HAVE_ENOUGH for "
586 << (type == DemuxerStream::AUDIO ? "audio" : "video")
587 << " stream";
588
589 restarting_audio_ = false;
590
591 // Now that we have decoded enough audio, pause and unpause playback
592 // momentarily to ensure video renderer is synchronised with audio.
593 double curr_playback_rate = playback_rate_;
594 SetPlaybackRate(0);
595 SetPlaybackRate(curr_playback_rate);
596
597 time_ticking_ = true;
598 time_source_->StartTicking();
599 }
600 return;
601 }
602
505 // When audio is present and has enough data, defer video underflow callbacks 603 // When audio is present and has enough data, defer video underflow callbacks
506 // for some time to avoid unnecessary glitches in audio; see 604 // for some time to avoid unnecessary glitches in audio; see
507 // http://crbug.com/144683#c53. 605 // http://crbug.com/144683#c53.
508 if (audio_renderer_ && type == DemuxerStream::VIDEO && 606 if (audio_renderer_ && type == DemuxerStream::VIDEO &&
509 state_ == STATE_PLAYING) { 607 state_ == STATE_PLAYING) {
510 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && 608 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
511 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH && 609 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
512 new_buffering_state == BUFFERING_HAVE_NOTHING && 610 new_buffering_state == BUFFERING_HAVE_NOTHING &&
513 deferred_underflow_cb_.IsCancelled()) { 611 deferred_underflow_cb_.IsCancelled()) {
514 deferred_underflow_cb_.Reset( 612 deferred_underflow_cb_.Reset(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 DCHECK(!time_ticking_); 703 DCHECK(!time_ticking_);
606 DCHECK(!WaitingForEnoughData()); 704 DCHECK(!WaitingForEnoughData());
607 705
608 time_ticking_ = true; 706 time_ticking_ = true;
609 time_source_->StartTicking(); 707 time_source_->StartTicking();
610 if (playback_rate_ > 0 && video_renderer_) 708 if (playback_rate_ > 0 && video_renderer_)
611 video_renderer_->OnTimeStateChanged(true); 709 video_renderer_->OnTimeStateChanged(true);
612 } 710 }
613 711
614 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) { 712 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) {
615 DVLOG(1) << __FUNCTION__; 713 DVLOG(1) << __FUNCTION__
714 << (type == DemuxerStream::AUDIO ? " audio" : " video");
616 DCHECK(task_runner_->BelongsToCurrentThread()); 715 DCHECK(task_runner_->BelongsToCurrentThread());
617 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); 716 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO));
618 717
619 if (state_ != STATE_PLAYING) 718 if (state_ != STATE_PLAYING)
620 return; 719 return;
621 720
622 if (type == DemuxerStream::AUDIO) { 721 if (type == DemuxerStream::AUDIO) {
623 DCHECK(!audio_ended_); 722 DCHECK(!audio_ended_);
624 audio_ended_ = true; 723 audio_ended_ = true;
625 } else { 724 } else {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 DCHECK(task_runner_->BelongsToCurrentThread()); 790 DCHECK(task_runner_->BelongsToCurrentThread());
692 client_->OnVideoNaturalSizeChange(size); 791 client_->OnVideoNaturalSizeChange(size);
693 } 792 }
694 793
695 void RendererImpl::OnVideoOpacityChange(bool opaque) { 794 void RendererImpl::OnVideoOpacityChange(bool opaque) {
696 DCHECK(task_runner_->BelongsToCurrentThread()); 795 DCHECK(task_runner_->BelongsToCurrentThread());
697 client_->OnVideoOpacityChange(opaque); 796 client_->OnVideoOpacityChange(opaque);
698 } 797 }
699 798
700 } // namespace media 799 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698