| Index: media/renderers/renderer_impl.cc
|
| diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
|
| index 0f6a4f3e5ddf36844cacb4a7f388c68ffd99dff4..38f49d4b66099adbb753cd1cccf67e8d79524e2d 100644
|
| --- a/media/renderers/renderer_impl.cc
|
| +++ b/media/renderers/renderer_impl.cc
|
| @@ -14,11 +14,13 @@
|
| #include "base/location.h"
|
| #include "base/single_thread_task_runner.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "media/base/audio_decoder_config.h"
|
| #include "media/base/audio_renderer.h"
|
| #include "media/base/bind_to_current_loop.h"
|
| #include "media/base/demuxer_stream_provider.h"
|
| #include "media/base/media_switches.h"
|
| #include "media/base/time_source.h"
|
| +#include "media/base/video_decoder_config.h"
|
| #include "media/base/video_renderer.h"
|
| #include "media/base/wall_clock_time_source.h"
|
|
|
| @@ -72,10 +74,11 @@ RendererImpl::~RendererImpl() {
|
| video_renderer_.reset();
|
| audio_renderer_.reset();
|
|
|
| - if (!init_cb_.is_null())
|
| - base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
|
| - else if (!flush_cb_.is_null())
|
| + if (!init_cb_.is_null()) {
|
| + FinishInitialization(PIPELINE_ERROR_ABORT);
|
| + } else if (!flush_cb_.is_null()) {
|
| base::ResetAndReturn(&flush_cb_).Run();
|
| + }
|
| }
|
|
|
| void RendererImpl::Initialize(
|
| @@ -105,6 +108,11 @@ void RendererImpl::Initialize(
|
| init_cb_ = init_cb;
|
| waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
|
|
|
| + if (HasEncryptedStream() && !cdm_context_) {
|
| + state_ = STATE_INIT_PENDING_CDM;
|
| + return;
|
| + }
|
| +
|
| state_ = STATE_INITIALIZING;
|
| InitializeAudioRenderer();
|
| }
|
| @@ -123,12 +131,17 @@ void RendererImpl::SetCdm(CdmContext* cdm_context,
|
|
|
| cdm_context_ = cdm_context;
|
|
|
| - if (cdm_ready_cb_.is_null()) {
|
| + if (state_ != STATE_INIT_PENDING_CDM) {
|
| cdm_attached_cb.Run(true);
|
| return;
|
| }
|
|
|
| - base::ResetAndReturn(&cdm_ready_cb_).Run(cdm_context, cdm_attached_cb);
|
| + DCHECK(!init_cb_.is_null());
|
| + state_ = STATE_INITIALIZING;
|
| + // |cdm_attached_cb| will be fired after initialization finishes.
|
| + pending_cdm_attached_cb_ = cdm_attached_cb;
|
| +
|
| + InitializeAudioRenderer();
|
| }
|
|
|
| void RendererImpl::Flush(const base::Closure& flush_cb) {
|
| @@ -254,25 +267,27 @@ bool RendererImpl::GetWallClockTimes(
|
| return time_source_->GetWallClockTimes(media_timestamps, wall_clock_times);
|
| }
|
|
|
| -void RendererImpl::SetCdmReadyCallback(const CdmReadyCB& cdm_ready_cb) {
|
| - // Cancels the previous CDM request.
|
| - if (cdm_ready_cb.is_null()) {
|
| - if (!cdm_ready_cb_.is_null()) {
|
| - base::ResetAndReturn(&cdm_ready_cb_)
|
| - .Run(nullptr, base::Bind(IgnoreCdmAttached));
|
| - }
|
| - return;
|
| - }
|
| +bool RendererImpl::HasEncryptedStream() {
|
| + DemuxerStream* audio_stream =
|
| + demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
|
| + if (audio_stream && audio_stream->audio_decoder_config().is_encrypted())
|
| + return true;
|
|
|
| - // We initialize audio and video decoders in sequence.
|
| - DCHECK(cdm_ready_cb_.is_null());
|
| + DemuxerStream* video_stream =
|
| + demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
|
| + if (video_stream && video_stream->video_decoder_config().is_encrypted())
|
| + return true;
|
|
|
| - if (cdm_context_) {
|
| - cdm_ready_cb.Run(cdm_context_, base::Bind(IgnoreCdmAttached));
|
| - return;
|
| - }
|
| + return false;
|
| +}
|
| +
|
| +void RendererImpl::FinishInitialization(PipelineStatus status) {
|
| + DCHECK(!init_cb_.is_null());
|
|
|
| - cdm_ready_cb_ = cdm_ready_cb;
|
| + if (!pending_cdm_attached_cb_.is_null())
|
| + base::ResetAndReturn(&pending_cdm_attached_cb_).Run(status == PIPELINE_OK);
|
| +
|
| + base::ResetAndReturn(&init_cb_).Run(status);
|
| }
|
|
|
| void RendererImpl::InitializeAudioRenderer() {
|
| @@ -294,8 +309,7 @@ void RendererImpl::InitializeAudioRenderer() {
|
| // happen at any time and all future calls must guard against STATE_ERROR.
|
| audio_renderer_->Initialize(
|
| demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), done_cb,
|
| - base::Bind(&RendererImpl::SetCdmReadyCallback, weak_this_),
|
| - base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_),
|
| + cdm_context_, base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_),
|
| base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_,
|
| &audio_buffering_state_),
|
| base::Bind(&RendererImpl::OnAudioRendererEnded, weak_this_),
|
| @@ -316,7 +330,7 @@ void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
|
| }
|
|
|
| if (status != PIPELINE_OK) {
|
| - base::ResetAndReturn(&init_cb_).Run(status);
|
| + FinishInitialization(status);
|
| return;
|
| }
|
|
|
| @@ -341,8 +355,7 @@ void RendererImpl::InitializeVideoRenderer() {
|
|
|
| video_renderer_->Initialize(
|
| demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), done_cb,
|
| - base::Bind(&RendererImpl::SetCdmReadyCallback, weak_this_),
|
| - base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_),
|
| + cdm_context_, base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_),
|
| base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_,
|
| &video_buffering_state_),
|
| base::Bind(&RendererImpl::OnVideoRendererEnded, weak_this_),
|
| @@ -367,7 +380,7 @@ void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
|
| DCHECK(!init_cb_.is_null());
|
|
|
| if (status != PIPELINE_OK) {
|
| - base::ResetAndReturn(&init_cb_).Run(status);
|
| + FinishInitialization(status);
|
| return;
|
| }
|
|
|
| @@ -381,7 +394,8 @@ void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
|
| state_ = STATE_PLAYING;
|
| DCHECK(time_source_);
|
| DCHECK(audio_renderer_ || video_renderer_);
|
| - base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
|
| +
|
| + FinishInitialization(PIPELINE_OK);
|
| }
|
|
|
| void RendererImpl::FlushAudioRenderer() {
|
| @@ -545,6 +559,7 @@ void RendererImpl::PausePlayback() {
|
| break;
|
|
|
| case STATE_UNINITIALIZED:
|
| + case STATE_INIT_PENDING_CDM:
|
| case STATE_INITIALIZING:
|
| NOTREACHED() << "Invalid state: " << state_;
|
| break;
|
| @@ -637,8 +652,10 @@ void RendererImpl::OnError(PipelineStatus error) {
|
| const State old_state = state_;
|
| state_ = STATE_ERROR;
|
|
|
| - if (old_state == STATE_INITIALIZING) {
|
| - base::ResetAndReturn(&init_cb_).Run(error);
|
| + if (!init_cb_.is_null()) {
|
| + DCHECK(old_state == STATE_INITIALIZING ||
|
| + old_state == STATE_INIT_PENDING_CDM);
|
| + FinishInitialization(error);
|
| return;
|
| }
|
|
|
|
|