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

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

Issue 2558213002: Fix crash in renderer initialization when media pipeline is stopped (Closed)
Patch Set: Add test expectations for DemuxStreamProvider GetStream Created 4 years 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 } 124 }
125 125
126 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, 126 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider,
127 RendererClient* client, 127 RendererClient* client,
128 const PipelineStatusCB& init_cb) { 128 const PipelineStatusCB& init_cb) {
129 DVLOG(1) << __func__; 129 DVLOG(1) << __func__;
130 DCHECK(task_runner_->BelongsToCurrentThread()); 130 DCHECK(task_runner_->BelongsToCurrentThread());
131 DCHECK_EQ(state_, STATE_UNINITIALIZED); 131 DCHECK_EQ(state_, STATE_UNINITIALIZED);
132 DCHECK(!init_cb.is_null()); 132 DCHECK(!init_cb.is_null());
133 DCHECK(client); 133 DCHECK(client);
134 DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) ||
135 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO));
136 134
137 client_ = client; 135 client_ = client;
138 demuxer_stream_provider_ = demuxer_stream_provider; 136 demuxer_stream_provider_ = demuxer_stream_provider;
139 init_cb_ = init_cb; 137 init_cb_ = init_cb;
140 138
141 DemuxerStream* audio_stream = 139 DemuxerStream* audio_stream =
DaleCurtis 2016/12/12 23:43:09 Can you move these into InitializeAudioRenderer()
servolk 2016/12/12 23:59:23 Yes, done.
142 demuxer_stream_provider->GetStream(DemuxerStream::AUDIO); 140 demuxer_stream_provider->GetStream(DemuxerStream::AUDIO);
143 if (audio_stream) 141 if (audio_stream)
DaleCurtis 2016/12/12 23:43:09 Needs {}
servolk 2016/12/12 23:59:23 The if is no longer necessary now that it's called
144 audio_stream->SetStreamStatusChangeCB(base::Bind( 142 audio_stream->SetStreamStatusChangeCB(base::Bind(
145 &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream)); 143 &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream));
146 DemuxerStream* video_stream = 144 DemuxerStream* video_stream =
147 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO); 145 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO);
148 if (video_stream) 146 if (video_stream)
DaleCurtis 2016/12/12 23:43:09 Multiline if needs {}
servolk 2016/12/12 23:59:23 ditto
149 video_stream->SetStreamStatusChangeCB(base::Bind( 147 video_stream->SetStreamStatusChangeCB(base::Bind(
150 &RendererImpl::RestartStreamPlayback, weak_this_, video_stream)); 148 &RendererImpl::RestartStreamPlayback, weak_this_, video_stream));
151 149
152 if (HasEncryptedStream() && !cdm_context_) { 150 if (HasEncryptedStream() && !cdm_context_) {
153 state_ = STATE_INIT_PENDING_CDM; 151 state_ = STATE_INIT_PENDING_CDM;
154 return; 152 return;
155 } 153 }
156 154
157 state_ = STATE_INITIALIZING; 155 state_ = STATE_INITIALIZING;
158 InitializeAudioRenderer(); 156 InitializeAudioRenderer();
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 366
369 void RendererImpl::FinishInitialization(PipelineStatus status) { 367 void RendererImpl::FinishInitialization(PipelineStatus status) {
370 DCHECK(!init_cb_.is_null()); 368 DCHECK(!init_cb_.is_null());
371 369
372 if (!pending_cdm_attached_cb_.is_null()) 370 if (!pending_cdm_attached_cb_.is_null())
373 base::ResetAndReturn(&pending_cdm_attached_cb_).Run(status == PIPELINE_OK); 371 base::ResetAndReturn(&pending_cdm_attached_cb_).Run(status == PIPELINE_OK);
374 372
375 base::ResetAndReturn(&init_cb_).Run(status); 373 base::ResetAndReturn(&init_cb_).Run(status);
376 } 374 }
377 375
378 void RendererImpl::InitializeAudioRenderer() { 376 void RendererImpl::InitializeAudioRenderer() {
DaleCurtis 2016/12/12 23:43:09 Pass in DemuxerStream* here and add a comment abou
servolk 2016/12/12 23:59:23 I guess we could pass DemuxerStream* in here, but
379 DVLOG(1) << __func__; 377 DVLOG(1) << __func__;
380 DCHECK(task_runner_->BelongsToCurrentThread()); 378 DCHECK(task_runner_->BelongsToCurrentThread());
381 DCHECK_EQ(state_, STATE_INITIALIZING); 379 DCHECK_EQ(state_, STATE_INITIALIZING);
382 DCHECK(!init_cb_.is_null()); 380 DCHECK(!init_cb_.is_null());
383 381
384 PipelineStatusCB done_cb = 382 PipelineStatusCB done_cb =
385 base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_); 383 base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_);
386 384
387 if (!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)) { 385 DemuxerStream* audio_stream =
386 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
387 if (!audio_stream) {
388 audio_renderer_.reset(); 388 audio_renderer_.reset();
389 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 389 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
390 return; 390 return;
391 } 391 }
392 392
393 audio_renderer_client_.reset( 393 audio_renderer_client_.reset(
394 new RendererClientInternal(DemuxerStream::AUDIO, this)); 394 new RendererClientInternal(DemuxerStream::AUDIO, this));
395 // Note: After the initialization of a renderer, error events from it may 395 // Note: After the initialization of a renderer, error events from it may
396 // happen at any time and all future calls must guard against STATE_ERROR. 396 // happen at any time and all future calls must guard against STATE_ERROR.
397 audio_renderer_->Initialize( 397 audio_renderer_->Initialize(audio_stream, cdm_context_,
398 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), cdm_context_, 398 audio_renderer_client_.get(), done_cb);
399 audio_renderer_client_.get(), done_cb);
400 } 399 }
401 400
402 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { 401 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
403 DVLOG(1) << __func__ << ": " << status; 402 DVLOG(1) << __func__ << ": " << status;
404 DCHECK(task_runner_->BelongsToCurrentThread()); 403 DCHECK(task_runner_->BelongsToCurrentThread());
405 404
406 // OnError() may be fired at any time by the renderers, even if they thought 405 // OnError() may be fired at any time by the renderers, even if they thought
407 // they initialized successfully (due to delayed output device setup). 406 // they initialized successfully (due to delayed output device setup).
408 if (state_ != STATE_INITIALIZING) { 407 if (state_ != STATE_INITIALIZING) {
409 DCHECK(init_cb_.is_null()); 408 DCHECK(init_cb_.is_null());
(...skipping 12 matching lines...) Expand all
422 421
423 void RendererImpl::InitializeVideoRenderer() { 422 void RendererImpl::InitializeVideoRenderer() {
424 DVLOG(1) << __func__; 423 DVLOG(1) << __func__;
425 DCHECK(task_runner_->BelongsToCurrentThread()); 424 DCHECK(task_runner_->BelongsToCurrentThread());
426 DCHECK_EQ(state_, STATE_INITIALIZING); 425 DCHECK_EQ(state_, STATE_INITIALIZING);
427 DCHECK(!init_cb_.is_null()); 426 DCHECK(!init_cb_.is_null());
428 427
429 PipelineStatusCB done_cb = 428 PipelineStatusCB done_cb =
430 base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_); 429 base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_);
431 430
432 if (!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)) { 431 DemuxerStream* video_stream =
432 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
433 if (!video_stream) {
433 video_renderer_.reset(); 434 video_renderer_.reset();
434 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 435 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
435 return; 436 return;
436 } 437 }
437 438
438 video_renderer_client_.reset( 439 video_renderer_client_.reset(
439 new RendererClientInternal(DemuxerStream::VIDEO, this)); 440 new RendererClientInternal(DemuxerStream::VIDEO, this));
440 video_renderer_->Initialize( 441 video_renderer_->Initialize(
441 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), cdm_context_, 442 video_stream, cdm_context_, video_renderer_client_.get(),
442 video_renderer_client_.get(),
443 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), 443 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
444 done_cb); 444 done_cb);
445 } 445 }
446 446
447 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { 447 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
448 DVLOG(1) << __func__ << ": " << status; 448 DVLOG(1) << __func__ << ": " << status;
449 DCHECK(task_runner_->BelongsToCurrentThread()); 449 DCHECK(task_runner_->BelongsToCurrentThread());
450 450
451 // OnError() may be fired at any time by the renderers, even if they thought 451 // OnError() may be fired at any time by the renderers, even if they thought
452 // they initialized successfully (due to delayed output device setup). 452 // they initialized successfully (due to delayed output device setup).
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 DCHECK(task_runner_->BelongsToCurrentThread()); 839 DCHECK(task_runner_->BelongsToCurrentThread());
840 client_->OnVideoNaturalSizeChange(size); 840 client_->OnVideoNaturalSizeChange(size);
841 } 841 }
842 842
843 void RendererImpl::OnVideoOpacityChange(bool opaque) { 843 void RendererImpl::OnVideoOpacityChange(bool opaque) {
844 DCHECK(task_runner_->BelongsToCurrentThread()); 844 DCHECK(task_runner_->BelongsToCurrentThread());
845 client_->OnVideoOpacityChange(opaque); 845 client_->OnVideoOpacityChange(opaque);
846 } 846 }
847 847
848 } // namespace media 848 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/renderers/renderer_impl_unittest.cc » ('j') | media/renderers/renderer_impl_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698