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

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

Issue 2605473002: Fix processing of multiple stream status changes by renderer (Closed)
Patch Set: Created 3 years, 12 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 14 matching lines...) Expand all
25 #include "media/base/video_renderer.h" 25 #include "media/base/video_renderer.h"
26 #include "media/base/wall_clock_time_source.h" 26 #include "media/base/wall_clock_time_source.h"
27 27
28 namespace media { 28 namespace media {
29 29
30 // See |video_underflow_threshold_|. 30 // See |video_underflow_threshold_|.
31 static const int kDefaultVideoUnderflowThresholdMs = 3000; 31 static const int kDefaultVideoUnderflowThresholdMs = 3000;
32 32
33 static const int kAudioRestartUnderflowThresholdMs = 2000; 33 static const int kAudioRestartUnderflowThresholdMs = 2000;
34 34
35 // Specifies the delay for postponed stream status changes while another status
36 // change of the same stream type is being handled.
37 static const int kStreamStatusHandlingDelayMs = 10;
xhwang 2017/01/04 19:34:02 nit: no need to use "static" here. Namespace scope
servolk 2017/01/04 21:29:30 Done.
38
35 class RendererImpl::RendererClientInternal : public RendererClient { 39 class RendererImpl::RendererClientInternal : public RendererClient {
36 public: 40 public:
37 RendererClientInternal(DemuxerStream::Type type, RendererImpl* renderer) 41 RendererClientInternal(DemuxerStream::Type type, RendererImpl* renderer)
38 : type_(type), renderer_(renderer) { 42 : type_(type), renderer_(renderer) {
39 DCHECK((type_ == DemuxerStream::AUDIO) || (type_ == DemuxerStream::VIDEO)); 43 DCHECK((type_ == DemuxerStream::AUDIO) || (type_ == DemuxerStream::VIDEO));
40 } 44 }
41 45
42 void OnError(PipelineStatus error) override { renderer_->OnError(error); } 46 void OnError(PipelineStatus error) override { renderer_->OnError(error); }
43 void OnEnded() override { renderer_->OnRendererEnded(type_); } 47 void OnEnded() override { renderer_->OnRendererEnded(type_); }
44 void OnStatisticsUpdate(const PipelineStatistics& stats) override { 48 void OnStatisticsUpdate(const PipelineStatistics& stats) override {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 205 }
202 206
203 time_source_->SetMediaTime(time); 207 time_source_->SetMediaTime(time);
204 208
205 if (audio_renderer_) 209 if (audio_renderer_)
206 audio_renderer_->StartPlaying(); 210 audio_renderer_->StartPlaying();
207 if (video_renderer_) 211 if (video_renderer_)
208 video_renderer_->StartPlayingFrom(time); 212 video_renderer_->StartPlayingFrom(time);
209 } 213 }
210 214
211 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, 215 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
212 bool enabled, 216 bool enabled,
213 base::TimeDelta time) { 217 base::TimeDelta time) {
214 DCHECK(task_runner_->BelongsToCurrentThread()); 218 DCHECK(task_runner_->BelongsToCurrentThread());
215 DCHECK(stream); 219 DCHECK(stream);
216 bool video = (stream->type() == DemuxerStream::VIDEO); 220 bool video = (stream->type() == DemuxerStream::VIDEO);
217 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream 221 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream
218 << " enabled=" << stream->enabled() << " time=" << time.InSecondsF(); 222 << " enabled=" << enabled << " time=" << time.InSecondsF();
219 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_)) 223 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_))
220 return; 224 return;
221 if (stream->type() == DemuxerStream::VIDEO) { 225 if (stream->type() == DemuxerStream::VIDEO) {
222 DCHECK(video_renderer_); 226 DCHECK(video_renderer_);
223 if (restarting_video_) 227 if (restarting_video_) {
228 DVLOG(3) << __func__ << ": postponed stream " << stream
229 << " status change handling.";
230 task_runner_->PostDelayedTask(
231 FROM_HERE, base::Bind(&RendererImpl::OnStreamStatusChanged,
232 weak_this_, stream, enabled, time),
233 base::TimeDelta::FromMilliseconds(kStreamStatusHandlingDelayMs));
224 return; 234 return;
235 }
225 restarting_video_ = true; 236 restarting_video_ = true;
226 video_renderer_->Flush( 237 video_renderer_->Flush(
227 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); 238 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
228 } else if (stream->type() == DemuxerStream::AUDIO) { 239 } else if (stream->type() == DemuxerStream::AUDIO) {
229 DCHECK(audio_renderer_); 240 DCHECK(audio_renderer_);
230 DCHECK(time_source_); 241 DCHECK(time_source_);
231 if (restarting_audio_) 242 if (restarting_audio_) {
243 DVLOG(3) << __func__ << ": postponed stream " << stream
244 << " status change handling.";
245 task_runner_->PostDelayedTask(
246 FROM_HERE, base::Bind(&RendererImpl::OnStreamStatusChanged,
247 weak_this_, stream, enabled, time),
248 base::TimeDelta::FromMilliseconds(kStreamStatusHandlingDelayMs));
232 return; 249 return;
250 }
233 restarting_audio_ = true; 251 restarting_audio_ = true;
234 // Stop ticking (transition into paused state) in audio renderer before 252 // Stop ticking (transition into paused state) in audio renderer before
235 // calling Flush, since after Flush we are going to restart playback by 253 // calling Flush, since after Flush we are going to restart playback by
236 // calling audio renderer StartPlaying which would fail in playing state. 254 // calling audio renderer StartPlaying which would fail in playing state.
237 if (time_ticking_) { 255 if (time_ticking_) {
238 time_ticking_ = false; 256 time_ticking_ = false;
239 time_source_->StopTicking(); 257 time_source_->StopTicking();
240 } 258 }
241 audio_renderer_->Flush( 259 audio_renderer_->Flush(
242 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); 260 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 391
374 DemuxerStream* audio_stream = 392 DemuxerStream* audio_stream =
375 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); 393 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
376 if (!audio_stream) { 394 if (!audio_stream) {
377 audio_renderer_.reset(); 395 audio_renderer_.reset();
378 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 396 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
379 return; 397 return;
380 } 398 }
381 399
382 audio_stream->SetStreamStatusChangeCB(base::Bind( 400 audio_stream->SetStreamStatusChangeCB(base::Bind(
383 &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream)); 401 &RendererImpl::OnStreamStatusChanged, weak_this_, audio_stream));
384 402
385 audio_renderer_client_.reset( 403 audio_renderer_client_.reset(
386 new RendererClientInternal(DemuxerStream::AUDIO, this)); 404 new RendererClientInternal(DemuxerStream::AUDIO, this));
387 // Note: After the initialization of a renderer, error events from it may 405 // Note: After the initialization of a renderer, error events from it may
388 // happen at any time and all future calls must guard against STATE_ERROR. 406 // happen at any time and all future calls must guard against STATE_ERROR.
389 audio_renderer_->Initialize(audio_stream, cdm_context_, 407 audio_renderer_->Initialize(audio_stream, cdm_context_,
390 audio_renderer_client_.get(), done_cb); 408 audio_renderer_client_.get(), done_cb);
391 } 409 }
392 410
393 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { 411 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
(...skipping 28 matching lines...) Expand all
422 440
423 DemuxerStream* video_stream = 441 DemuxerStream* video_stream =
424 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); 442 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
425 if (!video_stream) { 443 if (!video_stream) {
426 video_renderer_.reset(); 444 video_renderer_.reset();
427 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 445 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
428 return; 446 return;
429 } 447 }
430 448
431 video_stream->SetStreamStatusChangeCB(base::Bind( 449 video_stream->SetStreamStatusChangeCB(base::Bind(
432 &RendererImpl::RestartStreamPlayback, weak_this_, video_stream)); 450 &RendererImpl::OnStreamStatusChanged, weak_this_, video_stream));
433 451
434 video_renderer_client_.reset( 452 video_renderer_client_.reset(
435 new RendererClientInternal(DemuxerStream::VIDEO, this)); 453 new RendererClientInternal(DemuxerStream::VIDEO, this));
436 video_renderer_->Initialize( 454 video_renderer_->Initialize(
437 video_stream, cdm_context_, video_renderer_client_.get(), 455 video_stream, cdm_context_, video_renderer_client_.get(),
438 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), 456 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
439 done_cb); 457 done_cb);
440 } 458 }
441 459
442 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { 460 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 DCHECK(task_runner_->BelongsToCurrentThread()); 852 DCHECK(task_runner_->BelongsToCurrentThread());
835 client_->OnVideoNaturalSizeChange(size); 853 client_->OnVideoNaturalSizeChange(size);
836 } 854 }
837 855
838 void RendererImpl::OnVideoOpacityChange(bool opaque) { 856 void RendererImpl::OnVideoOpacityChange(bool opaque) {
839 DCHECK(task_runner_->BelongsToCurrentThread()); 857 DCHECK(task_runner_->BelongsToCurrentThread());
840 client_->OnVideoOpacityChange(opaque); 858 client_->OnVideoOpacityChange(opaque);
841 } 859 }
842 860
843 } // namespace media 861 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698