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

Unified Diff: media/renderers/renderer_impl.cc

Issue 2684103005: Allow media track switching. (Closed)
Patch Set: Updated GpuMemoryBufferVideoFramePool comment Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: media/renderers/renderer_impl.cc
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index f03b2da865c7f2b02b748b4f9f7f26f2627ebd50..2b28dd3d91183a2c1e249e5ec8df3779399592ca 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -80,6 +80,8 @@ RendererImpl::RendererImpl(
task_runner_(task_runner),
audio_renderer_(std::move(audio_renderer)),
video_renderer_(std::move(video_renderer)),
+ current_audio_stream_(nullptr),
+ current_video_stream_(nullptr),
time_source_(NULL),
time_ticking_(false),
playback_rate_(0.0),
@@ -192,6 +194,15 @@ void RendererImpl::Flush(const base::Closure& flush_cb) {
flush_cb_ = flush_cb;
state_ = STATE_FLUSHING;
+ // If we are currently handling a media stream status change, then postpone
+ // Flush until after that's done (because stream status changes also flush
+ // audio_renderer_/video_renderer_ and they need to be restarted before they
+ // can be flushed again). OnStreamRestartCompleted will resume Flush
+ // processing after audio/video restart has completed and there are no other
+ // pending stream status changes.
+ if (restarting_audio_ || restarting_video_)
+ return;
+
if (time_ticking_)
PausePlayback();
@@ -237,7 +248,10 @@ void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
DCHECK(video_renderer_);
restarting_video_ = true;
video_renderer_->Flush(
- base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
+ base::Bind((stream == current_video_stream_)
DaleCurtis 2017/03/31 21:22:08 Unnecessary parens.
servolk 2017/03/31 23:53:55 Done.
+ ? &RendererImpl::RestartVideoRenderer
+ : &RendererImpl::ReinitializeVideoRenderer,
+ weak_this_, stream, time));
} else if (stream->type() == DemuxerStream::AUDIO) {
DCHECK(audio_renderer_);
DCHECK(time_source_);
@@ -250,25 +264,88 @@ void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
time_source_->StopTicking();
}
audio_renderer_->Flush(
- base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time));
+ base::Bind((stream == current_audio_stream_)
DaleCurtis 2017/03/31 21:22:08 Ditto.
servolk 2017/03/31 23:53:55 Done.
+ ? &RendererImpl::RestartAudioRenderer
+ : &RendererImpl::ReinitializeAudioRenderer,
+ weak_this_, stream, time));
+ }
+}
+
+void RendererImpl::ReinitializeVideoRenderer(DemuxerStream* stream,
+ base::TimeDelta time) {
+ DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK_NE(stream, current_video_stream_);
+
+ current_video_stream_ = stream;
+ video_renderer_->OnTimeStopped();
+ video_renderer_->Initialize(
+ stream, cdm_context_, video_renderer_client_.get(),
+ base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
+ base::Bind(&RendererImpl::OnVideoRendererReinitialized, weak_this_,
+ stream, time));
+}
+
+void RendererImpl::OnVideoRendererReinitialized(DemuxerStream* stream,
+ base::TimeDelta time,
+ PipelineStatus status) {
+ DVLOG(2) << __func__ << ": status=" << status;
+ DCHECK_EQ(stream, current_video_stream_);
+
+ if (status != PIPELINE_OK) {
+ OnError(status);
+ return;
}
+ RestartVideoRenderer(stream, time);
}
-void RendererImpl::RestartVideoRenderer(base::TimeDelta time) {
- DVLOG(3) << __func__;
+void RendererImpl::RestartVideoRenderer(DemuxerStream* stream,
+ base::TimeDelta time) {
+ DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(video_renderer_);
- DCHECK_EQ(state_, STATE_PLAYING);
+ DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHING);
+ DCHECK_EQ(stream, current_video_stream_);
+
video_ended_ = false;
video_renderer_->StartPlayingFrom(time);
DaleCurtis 2017/03/31 21:22:08 This doesn't seem to toggle OnTimeProgressing?
servolk 2017/03/31 23:53:55 Yes, this simply tells video renderer to start rea
}
-void RendererImpl::RestartAudioRenderer(base::TimeDelta time) {
- DVLOG(3) << __func__;
+void RendererImpl::ReinitializeAudioRenderer(DemuxerStream* stream,
+ base::TimeDelta time) {
+ DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK_EQ(state_, STATE_PLAYING);
+ DCHECK_NE(stream, current_audio_stream_);
+
+ current_audio_stream_ = stream;
+ audio_renderer_->Initialize(
+ stream, cdm_context_, audio_renderer_client_.get(),
+ base::Bind(&RendererImpl::OnAudioRendererReinitialized, weak_this_,
+ stream, time));
+}
+
+void RendererImpl::OnAudioRendererReinitialized(DemuxerStream* stream,
+ base::TimeDelta time,
+ PipelineStatus status) {
+ DVLOG(2) << __func__ << ": status=" << status;
+ DCHECK_EQ(stream, current_audio_stream_);
+
+ if (status != PIPELINE_OK) {
+ OnError(status);
+ return;
+ }
+ RestartAudioRenderer(stream, time);
+}
+
+void RendererImpl::RestartAudioRenderer(DemuxerStream* stream,
+ base::TimeDelta time) {
+ DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHING);
DCHECK(time_source_);
DCHECK(audio_renderer_);
+ DCHECK_EQ(stream, current_audio_stream_);
+
audio_ended_ = false;
audio_renderer_->StartPlaying();
xhwang 2017/03/31 23:38:11 Not for this CL and I think we discussed this befo
servolk 2017/03/31 23:53:55 Because a. We don't know if the pending stream sta
}
@@ -394,6 +471,8 @@ void RendererImpl::InitializeAudioRenderer() {
return;
}
+ current_audio_stream_ = audio_stream;
+
audio_renderer_client_.reset(
new RendererClientInternal(DemuxerStream::AUDIO, this));
// Note: After the initialization of a renderer, error events from it may
@@ -442,6 +521,8 @@ void RendererImpl::InitializeVideoRenderer() {
return;
}
+ current_video_stream_ = video_stream;
+
video_renderer_client_.reset(
new RendererClientInternal(DemuxerStream::VIDEO, this));
video_renderer_->Initialize(
@@ -628,12 +709,22 @@ bool RendererImpl::HandleRestartedStreamBufferingChanges(
}
void RendererImpl::OnStreamRestartCompleted() {
+ DVLOG(3) << __func__ << " a=" << restarting_audio_
+ << " v=" << restarting_video_;
xhwang 2017/03/31 23:38:11 nit: it's gonna be hard to understand what a=1 mea
servolk 2017/03/31 23:53:55 Done.
DCHECK(restarting_audio_ || restarting_video_);
restarting_audio_ = false;
restarting_video_ = false;
if (!pending_stream_status_notifications_.empty()) {
pending_stream_status_notifications_.front().Run();
pending_stream_status_notifications_.pop_front();
xhwang 2017/03/31 23:38:11 nit: The Run() part calls OnStreamStatusChanged()
servolk 2017/03/31 23:53:55 Done.
+ } else if (flush_cb_) {
+ DCHECK_EQ(state_, STATE_FLUSHING);
+ DVLOG(3) << __func__ << " completing pending Flush";
+ // Resume pending Flush processing.
+ if (time_ticking_)
+ PausePlayback();
+
+ FlushAudioRenderer();
}
}

Powered by Google App Engine
This is Rietveld 408576698