diff options
34 files changed, 443 insertions, 382 deletions
diff --git a/content/renderer/media/android/media_source_delegate.cc b/content/renderer/media/android/media_source_delegate.cc index 4c0477b..9b4d312 100644 --- a/content/renderer/media/android/media_source_delegate.cc +++ b/content/renderer/media/android/media_source_delegate.cc @@ -146,7 +146,7 @@ void MediaSourceDelegate::InitializeMediaSource( const MediaSourceOpenedCB& media_source_opened_cb, const media::Demuxer::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, - const media::SetDecryptorReadyCB& set_decryptor_ready_cb, + const media::SetCdmReadyCB& set_cdm_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, const DurationChangeCB& duration_change_cb, const base::Closure& waiting_for_decryption_key_cb) { @@ -154,7 +154,7 @@ void MediaSourceDelegate::InitializeMediaSource( DCHECK(!media_source_opened_cb.is_null()); media_source_opened_cb_ = media_source_opened_cb; encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; - set_decryptor_ready_cb_ = media::BindToCurrentLoop(set_decryptor_ready_cb); + set_cdm_ready_cb_ = media::BindToCurrentLoop(set_cdm_ready_cb); update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); duration_change_cb_ = duration_change_cb; waiting_for_decryption_key_cb_ = @@ -496,7 +496,7 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { video_stream_ = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); if (audio_stream_ && audio_stream_->audio_decoder_config().is_encrypted() && - !set_decryptor_ready_cb_.is_null()) { + !set_cdm_ready_cb_.is_null()) { InitAudioDecryptingDemuxerStream(); // InitVideoDecryptingDemuxerStream() will be called in // OnAudioDecryptingDemuxerStreamInitDone(). @@ -504,7 +504,7 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { } if (video_stream_ && video_stream_->video_decoder_config().is_encrypted() && - !set_decryptor_ready_cb_.is_null()) { + !set_cdm_ready_cb_.is_null()) { InitVideoDecryptingDemuxerStream(); return; } @@ -517,10 +517,10 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { DCHECK(media_task_runner_->BelongsToCurrentThread()); DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; - DCHECK(!set_decryptor_ready_cb_.is_null()); + DCHECK(!set_cdm_ready_cb_.is_null()); audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( - media_task_runner_, media_log_, set_decryptor_ready_cb_, + media_task_runner_, media_log_, set_cdm_ready_cb_, waiting_for_decryption_key_cb_)); audio_decrypting_demuxer_stream_->Initialize( audio_stream_, @@ -531,10 +531,10 @@ void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { DCHECK(media_task_runner_->BelongsToCurrentThread()); DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; - DCHECK(!set_decryptor_ready_cb_.is_null()); + DCHECK(!set_cdm_ready_cb_.is_null()); video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( - media_task_runner_, media_log_, set_decryptor_ready_cb_, + media_task_runner_, media_log_, set_cdm_ready_cb_, waiting_for_decryption_key_cb_)); video_decrypting_demuxer_stream_->Initialize( video_stream_, diff --git a/content/renderer/media/android/media_source_delegate.h b/content/renderer/media/android/media_source_delegate.h index e644230..ee5e1a4 100644 --- a/content/renderer/media/android/media_source_delegate.h +++ b/content/renderer/media/android/media_source_delegate.h @@ -13,7 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "media/base/decryptor.h" +#include "media/base/cdm_context.h" #include "media/base/demuxer.h" #include "media/base/media_keys.h" #include "media/base/pipeline_status.h" @@ -60,7 +60,7 @@ class MediaSourceDelegate : public media::DemuxerHost { const MediaSourceOpenedCB& media_source_opened_cb, const media::Demuxer::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, - const media::SetDecryptorReadyCB& set_decryptor_ready_cb, + const media::SetCdmReadyCB& set_cdm_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, const DurationChangeCB& duration_change_cb, const base::Closure& waiting_for_decryption_key_cb); @@ -186,7 +186,7 @@ class MediaSourceDelegate : public media::DemuxerHost { scoped_ptr<media::ChunkDemuxer> chunk_demuxer_; bool is_demuxer_ready_; - media::SetDecryptorReadyCB set_decryptor_ready_cb_; + media::SetCdmReadyCB set_cdm_ready_cb_; scoped_ptr<media::DecryptingDemuxerStream> audio_decrypting_demuxer_stream_; scoped_ptr<media::DecryptingDemuxerStream> video_decrypting_demuxer_stream_; diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index ceecc08..cfd92af 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc @@ -186,19 +186,18 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid( needs_establish_peer_(true), has_size_info_(false), // Threaded compositing isn't enabled universally yet. - compositor_task_runner_( - params.compositor_task_runner() - ? params.compositor_task_runner() - : base::ThreadTaskRunnerHandle::Get()), + compositor_task_runner_(params.compositor_task_runner() + ? params.compositor_task_runner() + : base::ThreadTaskRunnerHandle::Get()), stream_texture_factory_(factory), needs_external_surface_(false), is_fullscreen_(false), - video_frame_provider_client_(NULL), + video_frame_provider_client_(nullptr), player_type_(MEDIA_PLAYER_TYPE_URL), is_remote_(false), media_log_(params.media_log()), init_data_type_(media::EmeInitDataType::UNKNOWN), - cdm_context_(NULL), + cdm_context_(nullptr), allow_stored_credentials_(false), is_local_resource_(false), interpolator_(&default_tick_clock_), @@ -326,7 +325,7 @@ void WebMediaPlayerAndroid::DoLoad(LoadType load_type, weak_factory_.GetWeakPtr()), base::Bind(&WebMediaPlayerAndroid::OnEncryptedMediaInitData, weak_factory_.GetWeakPtr()), - base::Bind(&WebMediaPlayerAndroid::SetDecryptorReadyCB, + base::Bind(&WebMediaPlayerAndroid::SetCdmReadyCB, weak_factory_.GetWeakPtr()), base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, weak_factory_.GetWeakPtr()), @@ -1711,12 +1710,12 @@ void WebMediaPlayerAndroid::setContentDecryptionModule( cdm_context_ = media::ToWebContentDecryptionModuleImpl(cdm)->GetCdmContext(); if (is_player_initialized_) { - SetCdmInternal(media::BindToCurrentLoop( + SetCdmInternal( base::Bind(&WebMediaPlayerAndroid::ContentDecryptionModuleAttached, - weak_factory_.GetWeakPtr(), result))); + weak_factory_.GetWeakPtr(), result)); } else { // No pipeline/decoder connected, so resolve the promise. When something - // is connected, setting the CDM will happen in SetDecryptorReadyCB(). + // is connected, setting the CDM will happen in SetCdmReadyCB(). ContentDecryptionModuleAttached(result, true); } } @@ -1830,70 +1829,69 @@ void WebMediaPlayerAndroid::OnCdmContextReady(media::CdmContext* cdm_context) { void WebMediaPlayerAndroid::SetCdmInternal( const media::CdmAttachedCB& cdm_attached_cb) { + DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(cdm_context_ && is_player_initialized_); DCHECK(cdm_context_->GetDecryptor() || cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId) << "CDM should support either a Decryptor or a CDM ID."; - media::Decryptor* decryptor = cdm_context_->GetDecryptor(); - - // Note: - // - If |decryptor| is non-null, only handles |decryptor_ready_cb_| and - // ignores the CDM ID. - // - If |decryptor| is null (in which case the CDM ID should be valid), - // returns any pending |decryptor_ready_cb_| with null, so that - // MediaSourceDelegate will fall back to use a browser side (IPC-based) CDM, - // then calls SetCdm() through the |player_manager_|. - - if (decryptor) { - if (!decryptor_ready_cb_.is_null()) { - base::ResetAndReturn(&decryptor_ready_cb_) - .Run(decryptor, cdm_attached_cb); - } else { - cdm_attached_cb.Run(true); - } + if (cdm_ready_cb_.is_null()) { + cdm_attached_cb.Run(true); return; } - // |decryptor| is null. - if (!decryptor_ready_cb_.is_null()) { - base::ResetAndReturn(&decryptor_ready_cb_) - .Run(nullptr, base::Bind(&media::IgnoreCdmAttached)); + // Satisfy |cdm_ready_cb_|. Use BindToCurrentLoop() since the callback could + // be fired on other threads. + base::ResetAndReturn(&cdm_ready_cb_) + .Run(cdm_context_, media::BindToCurrentLoop(base::Bind( + &WebMediaPlayerAndroid::OnCdmAttached, + weak_factory_.GetWeakPtr(), cdm_attached_cb))); +} + +void WebMediaPlayerAndroid::OnCdmAttached( + const media::CdmAttachedCB& cdm_attached_cb, + bool success) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + if (!success) { + if (cdm_context_->GetCdmId() == media::CdmContext::kInvalidCdmId) { + NOTREACHED() << "CDM cannot be attached to media player."; + cdm_attached_cb.Run(false); + return; + } + + // If the CDM is not attached (e.g. the CDM does not support a Decryptor), + // MediaSourceDelegate will fall back to use a browser side (IPC-based) CDM. + player_manager_->SetCdm(player_id_, cdm_context_->GetCdmId()); } - DCHECK(cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId); - player_manager_->SetCdm(player_id_, cdm_context_->GetCdmId()); cdm_attached_cb.Run(true); } -void WebMediaPlayerAndroid::SetDecryptorReadyCB( - const media::DecryptorReadyCB& decryptor_ready_cb) { +void WebMediaPlayerAndroid::SetCdmReadyCB( + const media::CdmReadyCB& cdm_ready_cb) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(is_player_initialized_); - // Cancels the previous decryptor request. - if (decryptor_ready_cb.is_null()) { - if (!decryptor_ready_cb_.is_null()) { - base::ResetAndReturn(&decryptor_ready_cb_) - .Run(NULL, base::Bind(&media::IgnoreCdmAttached)); + // 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(&media::IgnoreCdmAttached)); } return; } - // TODO(xhwang): Support multiple decryptor notification request (e.g. from + // TODO(xhwang): Support multiple CDM notification request (e.g. from // video and audio). The current implementation is okay for the current // media pipeline since we initialize audio and video decoders in sequence. - // But WebMediaPlayerImpl should not depend on media pipeline's implementation - // detail. - DCHECK(decryptor_ready_cb_.is_null()); + // But WebMediaPlayerAndroid should not depend on media pipeline's + // implementation detail. + DCHECK(cdm_ready_cb_.is_null()); + cdm_ready_cb_ = cdm_ready_cb; - if (cdm_context_) { - decryptor_ready_cb.Run(cdm_context_->GetDecryptor(), - base::Bind(&media::IgnoreCdmAttached)); - return; - } - - decryptor_ready_cb_ = decryptor_ready_cb; + if (cdm_context_) + SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); } bool WebMediaPlayerAndroid::supportsOverlayFullscreenVideo() { diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index 2dea4b4..59859ff 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h @@ -320,15 +320,18 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer, void OnCdmContextReady(media::CdmContext* cdm_context); // Sets the CDM. Should only be called when |is_player_initialized_| is true - // and a new non-null |cdm_context_| is available. Fires |cdm_attached_cb_| - // with the result after the CDM is attached. + // and a new non-null |cdm_context_| is available. Fires |cdm_attached_cb_| on + // the main thread with the result after the CDM is attached. void SetCdmInternal(const media::CdmAttachedCB& cdm_attached_cb); - // Requests that this object notifies when a decryptor is ready through the - // |decryptor_ready_cb| provided. - // If |decryptor_ready_cb| is null, the existing callback will be fired with + // Called when the CDM is attached. + void OnCdmAttached(const media::CdmAttachedCB& cdm_attached_cb, bool success); + + // Requests that this object notifies when a CDM is ready through the + // |cdm_ready_cb| provided. + // If |cdm_ready_cb| is null, the existing callback will be fired with // NULL immediately and reset. - void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb); + void SetCdmReadyCB(const media::CdmReadyCB& cdm_ready_cb); // Called when the ContentDecryptionModule has been attached to the // pipeline/decoders. @@ -509,7 +512,7 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer, // side CDM will be used. This is similar to WebMediaPlayerImpl. For other key // systems, a browser side CDM will be used and we set CDM by calling // player_manager_->SetCdm() directly. - media::DecryptorReadyCB decryptor_ready_cb_; + media::CdmReadyCB cdm_ready_cb_; SkBitmap bitmap_; diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h index 586936a..aa59bf3 100644 --- a/media/base/audio_renderer.h +++ b/media/base/audio_renderer.h @@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/time/time.h" #include "media/base/buffering_state.h" -#include "media/base/decryptor.h" +#include "media/base/cdm_context.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" @@ -28,8 +28,8 @@ class MEDIA_EXPORT AudioRenderer { // completion. If initialization fails, only |init_cb| (not |error_cb|) will // be called. // - // |set_decryptor_ready_cb| is fired when a Decryptor is needed, i.e. when the - // |stream| is encrypted. + // |set_cdm_ready_cb| is fired when a CDM is needed, i.e. when the |stream| is + // encrypted. // // |statistics_cb| is executed periodically with audio rendering stats. // @@ -45,7 +45,7 @@ class MEDIA_EXPORT AudioRenderer { virtual void Initialize( DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, diff --git a/media/base/cdm_context.h b/media/base/cdm_context.h index 7d89760..c64f276 100644 --- a/media/base/cdm_context.h +++ b/media/base/cdm_context.h @@ -68,6 +68,19 @@ typedef base::Callback<void(bool)> CdmAttachedCB; // A dummy implementation of CdmAttachedCB. MEDIA_EXPORT void IgnoreCdmAttached(bool success); +// Callback to notify that a CDM is ready. CdmAttachedCB is called when the CDM +// has been completely attached to the media pipeline. +typedef base::Callback<void(CdmContext*, const CdmAttachedCB&)> CdmReadyCB; + +// Callback to set/cancel a CdmReadyCB. +// Calling this callback with a non-null callback registers CDM ready +// notification. When the CDM is ready, notification will be sent +// through the provided callback. +// Calling this callback with a null callback cancels previously registered CDM +// ready notification. Any previously provided callback will be fired +// immediately with NULL. +typedef base::Callback<void(const CdmReadyCB&)> SetCdmReadyCB; + } // namespace media #endif // MEDIA_BASE_CDM_CONTEXT_H_ diff --git a/media/base/decryptor.h b/media/base/decryptor.h index 47b4645..f0d8be8 100644 --- a/media/base/decryptor.h +++ b/media/base/decryptor.h @@ -163,24 +163,6 @@ class MEDIA_EXPORT Decryptor { DISALLOW_COPY_AND_ASSIGN(Decryptor); }; -// Callback to notify that the decryptor has been completely attached into the -// pipeline. Parameter indicates whether the operation succeeded. -typedef base::Callback<void(bool)> DecryptorAttachedCB; - -// Callback to notify that a decryptor is ready. DecryptorAttachedCB is called -// when the decryptor has been completely inserted into the pipeline. -typedef base::Callback<void(Decryptor*, const DecryptorAttachedCB&)> - DecryptorReadyCB; - -// Callback to set/cancel a DecryptorReadyCB. -// Calling this callback with a non-null callback registers decryptor ready -// notification. When the decryptor is ready, notification will be sent -// through the provided callback. -// Calling this callback with a null callback cancels previously registered -// decryptor ready notification. Any previously provided callback will be -// fired immediately with NULL. -typedef base::Callback<void(const DecryptorReadyCB&)> SetDecryptorReadyCB; - } // namespace media #endif // MEDIA_BASE_DECRYPTOR_H_ diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc index f9fd4b5..98c23be 100644 --- a/media/base/mock_filters.cc +++ b/media/base/mock_filters.cc @@ -108,4 +108,12 @@ MockDecryptor::MockDecryptor() {} MockDecryptor::~MockDecryptor() {} +MockCdmContext::MockCdmContext() {} + +MockCdmContext::~MockCdmContext() {} + +int MockCdmContext::GetCdmId() const { + return CdmContext::kInvalidCdmId; +} + } // namespace media diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index dffbab0..5fb2a3e 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h @@ -8,9 +8,11 @@ #include <string> #include "base/callback.h" +#include "base/macros.h" #include "media/base/audio_decoder.h" #include "media/base/audio_decoder_config.h" #include "media/base/audio_renderer.h" +#include "media/base/cdm_context.h" #include "media/base/decoder_buffer.h" #include "media/base/decryptor.h" #include "media/base/demuxer.h" @@ -127,7 +129,7 @@ class MockVideoRenderer : public VideoRenderer { MOCK_METHOD9(Initialize, void(DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, @@ -151,7 +153,7 @@ class MockAudioRenderer : public AudioRenderer { MOCK_METHOD8(Initialize, void(DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, @@ -259,6 +261,18 @@ class MockDecryptor : public Decryptor { DISALLOW_COPY_AND_ASSIGN(MockDecryptor); }; +class MockCdmContext : public CdmContext { + public: + MockCdmContext(); + ~MockCdmContext() override; + + MOCK_METHOD0(GetDecryptor, Decryptor*()); + int GetCdmId() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(MockCdmContext); +}; + } // namespace media #endif // MEDIA_BASE_MOCK_FILTERS_H_ diff --git a/media/base/video_renderer.h b/media/base/video_renderer.h index 454c664..d85ec60 100644 --- a/media/base/video_renderer.h +++ b/media/base/video_renderer.h @@ -9,7 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "media/base/buffering_state.h" -#include "media/base/decryptor.h" +#include "media/base/cdm_context.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" #include "media/base/time_source.h" @@ -34,8 +34,8 @@ class MEDIA_EXPORT VideoRenderer { // completion. If initialization fails, only |init_cb| (not |error_cb|) will // be called. // - // |set_decryptor_ready_cb| is fired when a Decryptor is needed, i.e. when the - // |stream| is encrypted. + // |set_cdm_ready_cb| is fired when a CDM is needed, i.e. when the |stream| is + // encrypted. // // |statistics_cb| is executed periodically with video rendering stats, such // as dropped frames. @@ -55,7 +55,7 @@ class MEDIA_EXPORT VideoRenderer { virtual void Initialize( DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, diff --git a/media/filters/audio_decoder_selector_unittest.cc b/media/filters/audio_decoder_selector_unittest.cc index 6e248fe..b2b8a8a 100644 --- a/media/filters/audio_decoder_selector_unittest.cc +++ b/media/filters/audio_decoder_selector_unittest.cc @@ -26,10 +26,10 @@ using ::testing::StrictMock; // times across multiple test files. Sadly we can't use static for them. namespace { -ACTION_P3(ExecuteCallbackWithVerifier, decryptor, done_cb, verifier) { +ACTION_P3(ExecuteCallbackWithVerifier, cdm_context, done_cb, verifier) { // verifier must be called first since |done_cb| call will invoke it as well. verifier->RecordACalled(); - arg0.Run(decryptor, done_cb); + arg0.Run(cdm_context, done_cb); } ACTION_P(ReportCallback, verifier) { @@ -62,6 +62,7 @@ class AudioDecoderSelectorTest : public ::testing::Test { AudioDecoderSelectorTest() : demuxer_stream_( new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new NiceMock<MockDecryptor>()), decoder_1_(new StrictMock<MockAudioDecoder>()), decoder_2_(new StrictMock<MockAudioDecoder>()) { @@ -73,10 +74,10 @@ class AudioDecoderSelectorTest : public ::testing::Test { message_loop_.RunUntilIdle(); } - MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); + MOCK_METHOD1(SetCdmReadyCallback, void(const CdmReadyCB&)); MOCK_METHOD2(OnDecoderSelected, void(AudioDecoder*, DecryptingDemuxerStream*)); - MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD1(CdmSet, void(bool)); void MockOnDecoderSelected(scoped_ptr<AudioDecoder> decoder, scoped_ptr<DecryptingDemuxerStream> stream) { @@ -102,13 +103,15 @@ class AudioDecoderSelectorTest : public ::testing::Test { int num_decoders) { if (decryptor_capability == kDecryptOnly || decryptor_capability == kDecryptAndDecode) { - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(decryptor_.get())); + + EXPECT_CALL(*this, SetCdmReadyCallback(_)) .WillRepeatedly(ExecuteCallbackWithVerifier( - decryptor_.get(), - base::Bind(&AudioDecoderSelectorTest::DecryptorSet, - base::Unretained(this)), + cdm_context_.get(), base::Bind(&AudioDecoderSelectorTest::CdmSet, + base::Unretained(this)), &verifier_)); - EXPECT_CALL(*this, DecryptorSet(true)) + EXPECT_CALL(*this, CdmSet(true)) .WillRepeatedly(ReportCallback(&verifier_)); if (decryptor_capability == kDecryptOnly) { @@ -119,11 +122,10 @@ class AudioDecoderSelectorTest : public ::testing::Test { .WillRepeatedly(RunCallback<1>(true)); } } else if (decryptor_capability == kHoldSetDecryptor) { - // Set and cancel DecryptorReadyCB but the callback is never fired. - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) - .Times(2); + // Set and cancel CdmReadyCB but the callback is never fired. + EXPECT_CALL(*this, SetCdmReadyCallback(_)).Times(2); } else if (decryptor_capability == kNoDecryptor) { - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) + EXPECT_CALL(*this, SetCdmReadyCallback(_)) .WillRepeatedly( RunCallback<0>(nullptr, base::Bind(&IgnoreCdmAttached))); } @@ -140,7 +142,7 @@ class AudioDecoderSelectorTest : public ::testing::Test { void SelectDecoder() { decoder_selector_->SelectDecoder( demuxer_stream_.get(), - base::Bind(&AudioDecoderSelectorTest::SetDecryptorReadyCallback, + base::Bind(&AudioDecoderSelectorTest::SetCdmReadyCallback, base::Unretained(this)), base::Bind(&AudioDecoderSelectorTest::MockOnDecoderSelected, base::Unretained(this)), @@ -167,11 +169,12 @@ class AudioDecoderSelectorTest : public ::testing::Test { // Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since // |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|. - scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_; + scoped_ptr<StrictMock<MockDemuxerStream>> demuxer_stream_; + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; // Use NiceMock since we don't care about most of calls on the decryptor, e.g. // RegisterNewKeyCB(). - scoped_ptr<NiceMock<MockDecryptor> > decryptor_; + scoped_ptr<NiceMock<MockDecryptor>> decryptor_; scoped_ptr<AudioDecoderSelector> decoder_selector_; diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc index 7fcc234..0f99e79 100644 --- a/media/filters/decoder_selector.cc +++ b/media/filters/decoder_selector.cc @@ -78,7 +78,7 @@ DecoderSelector<StreamType>::~DecoderSelector() { template <DemuxerStream::Type StreamType> void DecoderSelector<StreamType>::SelectDecoder( DemuxerStream* stream, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const SelectDecoderCB& select_decoder_cb, const typename Decoder::OutputCB& output_cb, const base::Closure& waiting_for_decryption_key_cb) { @@ -87,7 +87,7 @@ void DecoderSelector<StreamType>::SelectDecoder( DCHECK(stream); DCHECK(select_decoder_cb_.is_null()); - set_decryptor_ready_cb_ = set_decryptor_ready_cb; + set_cdm_ready_cb_ = set_cdm_ready_cb; waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; // Make sure |select_decoder_cb| runs on a different execution stack. @@ -109,7 +109,7 @@ void DecoderSelector<StreamType>::SelectDecoder( // This could be null during fallback after decoder reinitialization failure. // See DecoderStream<StreamType>::OnDecoderReinitialized(). - if (set_decryptor_ready_cb_.is_null()) { + if (set_cdm_ready_cb_.is_null()) { ReturnNullDecoder(); return; } @@ -125,7 +125,7 @@ void DecoderSelector<StreamType>::SelectDecoder( template <DemuxerStream::Type StreamType> void DecoderSelector<StreamType>::InitializeDecryptingDecoder() { decoder_.reset(new typename StreamTraits::DecryptingDecoderType( - task_runner_, media_log_, set_decryptor_ready_cb_, + task_runner_, media_log_, set_cdm_ready_cb_, waiting_for_decryption_key_cb_)); DecoderStreamTraits<StreamType>::InitializeDecoder( @@ -156,9 +156,9 @@ void DecoderSelector<StreamType>::DecryptingDecoderInitDone(bool success) { template <DemuxerStream::Type StreamType> void DecoderSelector<StreamType>::InitializeDecryptingDemuxerStream() { - decrypted_stream_.reset(new DecryptingDemuxerStream( - task_runner_, media_log_, set_decryptor_ready_cb_, - waiting_for_decryption_key_cb_)); + decrypted_stream_.reset( + new DecryptingDemuxerStream(task_runner_, media_log_, set_cdm_ready_cb_, + waiting_for_decryption_key_cb_)); decrypted_stream_->Initialize( input_stream_, diff --git a/media/filters/decoder_selector.h b/media/filters/decoder_selector.h index 6db6061a..c8a8ff9 100644 --- a/media/filters/decoder_selector.h +++ b/media/filters/decoder_selector.h @@ -9,7 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" -#include "media/base/decryptor.h" +#include "media/base/cdm_context.h" #include "media/base/demuxer_stream.h" #include "media/base/pipeline_status.h" #include "media/filters/decoder_stream_traits.h" @@ -22,7 +22,6 @@ namespace media { class DecoderBuffer; class DecryptingDemuxerStream; -class Decryptor; class MediaLog; // DecoderSelector (creates if necessary and) initializes the proper @@ -67,10 +66,10 @@ class MEDIA_EXPORT DecoderSelector { // 1. This must not be called again before |select_decoder_cb| is run. // 2. Decoders that fail to initialize will be deleted. Future calls will // select from the decoders following the decoder that was last returned. - // 3. |set_decryptor_ready_cb| is optional. If |set_decryptor_ready_cb| is - // null, no decryptor will be available to perform decryption. + // 3. |set_cdm_ready_cb| is optional. If |set_cdm_ready_cb| is + // null, no CDM will be available to perform decryption. void SelectDecoder(DemuxerStream* stream, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const SelectDecoderCB& select_decoder_cb, const typename Decoder::OutputCB& output_cb, const base::Closure& waiting_for_decryption_key_cb); @@ -91,7 +90,7 @@ class MEDIA_EXPORT DecoderSelector { scoped_refptr<MediaLog> media_log_; DemuxerStream* input_stream_; - SetDecryptorReadyCB set_decryptor_ready_cb_; + SetCdmReadyCB set_cdm_ready_cb_; SelectDecoderCB select_decoder_cb_; typename Decoder::OutputCB output_cb_; base::Closure waiting_for_decryption_key_cb_; diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index e601da4..91a5b1e 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc @@ -89,7 +89,7 @@ template <DemuxerStream::Type StreamType> void DecoderStream<StreamType>::Initialize( DemuxerStream* stream, const InitCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const base::Closure& waiting_for_decryption_key_cb) { FUNCTION_DVLOG(2); @@ -104,7 +104,7 @@ void DecoderStream<StreamType>::Initialize( stream_ = stream; state_ = STATE_INITIALIZING; - SelectDecoder(set_decryptor_ready_cb); + SelectDecoder(set_cdm_ready_cb); } template <DemuxerStream::Type StreamType> @@ -215,9 +215,9 @@ bool DecoderStream<StreamType>::CanDecodeMore() const { template <DemuxerStream::Type StreamType> void DecoderStream<StreamType>::SelectDecoder( - const SetDecryptorReadyCB& set_decryptor_ready_cb) { + const SetCdmReadyCB& set_cdm_ready_cb) { decoder_selector_->SelectDecoder( - stream_, set_decryptor_ready_cb, + stream_, set_cdm_ready_cb, base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, weak_factory_.GetWeakPtr()), base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, @@ -542,7 +542,7 @@ void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { // once is safe. // For simplicity, don't attempt to fall back to a decryptor. Calling this // with a null callback ensures that one won't be selected. - SelectDecoder(SetDecryptorReadyCB()); + SelectDecoder(SetCdmReadyCB()); } else { CompleteDecoderReinitialization(true); } diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index d5205f3..94b6b7b 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h @@ -5,6 +5,8 @@ #ifndef MEDIA_FILTERS_DECODER_STREAM_H_ #define MEDIA_FILTERS_DECODER_STREAM_H_ +#include <list> + #include "base/basictypes.h" #include "base/callback.h" #include "base/compiler_specific.h" @@ -12,7 +14,7 @@ #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "media/base/audio_decoder.h" -#include "media/base/decryptor.h" +#include "media/base/cdm_context.h" #include "media/base/demuxer_stream.h" #include "media/base/media_export.h" #include "media/base/media_log.h" @@ -65,7 +67,7 @@ class MEDIA_EXPORT DecoderStream { // through |init_cb|. Note that |init_cb| is always called asynchronously. void Initialize(DemuxerStream* stream, const InitCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const base::Closure& waiting_for_decryption_key_cb); @@ -129,7 +131,7 @@ class MEDIA_EXPORT DecoderStream { STATE_ERROR }; - void SelectDecoder(const SetDecryptorReadyCB& set_decryptor_ready_cb); + void SelectDecoder(const SetCdmReadyCB& set_cdm_ready_cb); // Called when |decoder_selector| selected the |selected_decoder|. // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc index 52a85f1..1c620a7 100644 --- a/media/filters/decrypting_audio_decoder.cc +++ b/media/filters/decrypting_audio_decoder.cc @@ -34,17 +34,16 @@ static inline bool IsOutOfSync(const base::TimeDelta& timestamp_1, DecryptingAudioDecoder::DecryptingAudioDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), media_log_(media_log), state_(kUninitialized), waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), - set_decryptor_ready_cb_(set_decryptor_ready_cb), + set_cdm_ready_cb_(set_cdm_ready_cb), decryptor_(NULL), key_added_while_decode_pending_(false), - weak_factory_(this) { -} + weak_factory_(this) {} std::string DecryptingAudioDecoder::GetDisplayName() const { return "DecryptingAudioDecoder"; @@ -78,8 +77,8 @@ void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config, if (state_ == kUninitialized) { state_ = kDecryptorRequested; - set_decryptor_ready_cb_.Run(BindToCurrentLoop( - base::Bind(&DecryptingAudioDecoder::SetDecryptor, weak_this_))); + set_cdm_ready_cb_.Run(BindToCurrentLoop( + base::Bind(&DecryptingAudioDecoder::SetCdm, weak_this_))); return; } @@ -161,8 +160,8 @@ DecryptingAudioDecoder::~DecryptingAudioDecoder() { decryptor_->DeinitializeDecoder(Decryptor::kAudio); decryptor_ = NULL; } - if (!set_decryptor_ready_cb_.is_null()) - base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); + if (!set_cdm_ready_cb_.is_null()) + base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); pending_buffer_to_decode_ = NULL; if (!init_cb_.is_null()) base::ResetAndReturn(&init_cb_).Run(false); @@ -172,29 +171,28 @@ DecryptingAudioDecoder::~DecryptingAudioDecoder() { base::ResetAndReturn(&reset_cb_).Run(); } -void DecryptingAudioDecoder::SetDecryptor( - Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb) { - DVLOG(2) << "SetDecryptor()"; +void DecryptingAudioDecoder::SetCdm(CdmContext* cdm_context, + const CdmAttachedCB& cdm_attached_cb) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kDecryptorRequested) << state_; DCHECK(!init_cb_.is_null()); - DCHECK(!set_decryptor_ready_cb_.is_null()); + DCHECK(!set_cdm_ready_cb_.is_null()); - set_decryptor_ready_cb_.Reset(); + set_cdm_ready_cb_.Reset(); - if (!decryptor) { + if (!cdm_context || !cdm_context->GetDecryptor()) { MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor set"; base::ResetAndReturn(&init_cb_).Run(false); state_ = kError; - decryptor_attached_cb.Run(false); + cdm_attached_cb.Run(false); return; } - decryptor_ = decryptor; + decryptor_ = cdm_context->GetDecryptor(); InitializeDecoder(); - decryptor_attached_cb.Run(true); + cdm_attached_cb.Run(true); } void DecryptingAudioDecoder::InitializeDecoder() { diff --git a/media/filters/decrypting_audio_decoder.h b/media/filters/decrypting_audio_decoder.h index 7919172..b566fdd 100644 --- a/media/filters/decrypting_audio_decoder.h +++ b/media/filters/decrypting_audio_decoder.h @@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "media/base/audio_decoder.h" +#include "media/base/cdm_context.h" #include "media/base/decryptor.h" #include "media/base/demuxer_stream.h" @@ -34,7 +35,7 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder { DecryptingAudioDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb); ~DecryptingAudioDecoder() override; @@ -63,10 +64,9 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder { kError }; - // Callback for DecryptorHost::RequestDecryptor(). |decryptor_attached_cb| is - // called when the decryptor has been completely attached to the pipeline. - void SetDecryptor(Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb); + // Callback to set CDM. |cdm_attached_cb| is called when the decryptor in the + // CDM has been completely attached to the pipeline. + void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); // Initializes the audio decoder on the |decryptor_| with |config_|. void InitializeDecoder(); @@ -106,8 +106,8 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder { // The current decoder configuration. AudioDecoderConfig config_; - // Callback to request/cancel decryptor creation notification. - SetDecryptorReadyCB set_decryptor_ready_cb_; + // Callback to request/cancel CDM ready notification. + SetCdmReadyCB set_cdm_ready_cb_; Decryptor* decryptor_; diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc index 4f749ce..016e09a4 100644 --- a/media/filters/decrypting_audio_decoder_unittest.cc +++ b/media/filters/decrypting_audio_decoder_unittest.cc @@ -21,6 +21,7 @@ using ::testing::_; using ::testing::AtMost; +using ::testing::Return; using ::testing::SaveArg; using ::testing::StrictMock; @@ -63,11 +64,11 @@ class DecryptingAudioDecoderTest : public testing::Test { : decoder_(new DecryptingAudioDecoder( message_loop_.task_runner(), new MediaLog(), - base::Bind( - &DecryptingAudioDecoderTest::RequestDecryptorNotification, - base::Unretained(this)), + base::Bind(&DecryptingAudioDecoderTest::RequestCdmNotification, + base::Unretained(this)), base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey, base::Unretained(this)))), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new StrictMock<MockDecryptor>()), num_decrypt_and_decode_calls_(0), num_frames_in_decryptor_(0), @@ -76,8 +77,7 @@ class DecryptingAudioDecoderTest : public testing::Test { decoded_frame_list_() {} virtual ~DecryptingAudioDecoderTest() { - EXPECT_CALL(*this, RequestDecryptorNotification(_)) - .Times(testing::AnyNumber()); + EXPECT_CALL(*this, RequestCdmNotification(_)).Times(testing::AnyNumber()); Destroy(); } @@ -102,19 +102,30 @@ class DecryptingAudioDecoderTest : public testing::Test { message_loop_.RunUntilIdle(); } - void ExpectDecryptorNotification(Decryptor* decryptor, bool expected_result) { - EXPECT_CALL(*this, RequestDecryptorNotification(_)).WillOnce( - RunCallback<0>(decryptor, - base::Bind(&DecryptingAudioDecoderTest::DecryptorSet, - base::Unretained(this)))); - EXPECT_CALL(*this, DecryptorSet(expected_result)); + enum CdmType { NO_CDM, CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR }; + + void SetCdmType(CdmType cdm_type) { + const bool has_cdm = cdm_type != NO_CDM; + const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR; + + EXPECT_CALL(*this, RequestCdmNotification(_)) + .WillOnce(RunCallback<0>(has_cdm ? cdm_context_.get() : nullptr, + base::Bind(&DecryptingAudioDecoderTest::CdmSet, + base::Unretained(this)))); + + if (has_cdm) { + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr)); + } + + EXPECT_CALL(*this, CdmSet(has_decryptor)); } void Initialize() { + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) .Times(AtMost(1)) .WillOnce(RunCallback<1>(true)); - ExpectDecryptorNotification(decryptor_.get(), true); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); @@ -250,18 +261,19 @@ class DecryptingAudioDecoderTest : public testing::Test { message_loop_.RunUntilIdle(); } - MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&)); + MOCK_METHOD1(RequestCdmNotification, void(const CdmReadyCB&)); MOCK_METHOD1(FrameReady, void(const scoped_refptr<AudioBuffer>&)); MOCK_METHOD1(DecodeDone, void(AudioDecoder::Status)); - MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD1(CdmSet, void(bool)); MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); base::MessageLoop message_loop_; scoped_ptr<DecryptingAudioDecoder> decoder_; - scoped_ptr<StrictMock<MockDecryptor> > decryptor_; + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; + scoped_ptr<StrictMock<MockDecryptor>> decryptor_; AudioDecoderConfig config_; // Variables to help the |decryptor_| to simulate decoding delay and flushing. @@ -304,9 +316,9 @@ TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) { // Ensure decoder handles unsupported audio configs without crashing. TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) { + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _)) .WillOnce(RunCallback<1>(false)); - ExpectDecryptorNotification(decryptor_.get(), true); AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, kSampleRate, @@ -314,8 +326,16 @@ TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) { InitializeAndExpectResult(config, false); } -TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) { - ExpectDecryptorNotification(NULL, false); +TEST_F(DecryptingAudioDecoderTest, Initialize_NoCdm) { + SetCdmType(NO_CDM); + AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, + CHANNEL_LAYOUT_STEREO, kSampleRate, + EmptyExtraData(), true); + InitializeAndExpectResult(config, false); +} + +TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) { + SetCdmType(CDM_WITHOUT_DECRYPTOR); AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(), true); diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index 3e67a29..2189545 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc @@ -28,18 +28,17 @@ static bool IsStreamValidAndEncrypted(DemuxerStream* stream) { DecryptingDemuxerStream::DecryptingDemuxerStream( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), media_log_(media_log), state_(kUninitialized), waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), demuxer_stream_(NULL), - set_decryptor_ready_cb_(set_decryptor_ready_cb), + set_cdm_ready_cb_(set_cdm_ready_cb), decryptor_(NULL), key_added_while_decrypt_pending_(false), - weak_factory_(this) { -} + weak_factory_(this) {} std::string DecryptingDemuxerStream::GetDisplayName() const { return "DecryptingDemuxerStream"; @@ -59,8 +58,8 @@ void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, InitializeDecoderConfig(); state_ = kDecryptorRequested; - set_decryptor_ready_cb_.Run(BindToCurrentLoop( - base::Bind(&DecryptingDemuxerStream::SetDecryptor, weak_this_))); + set_cdm_ready_cb_.Run(BindToCurrentLoop( + base::Bind(&DecryptingDemuxerStream::SetCdm, weak_this_))); } void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { @@ -88,7 +87,7 @@ void DecryptingDemuxerStream::Reset(const base::Closure& closure) { // condition and clean up related tests. if (state_ == kDecryptorRequested) { DCHECK(!init_cb_.is_null()); - set_decryptor_ready_cb_.Run(DecryptorReadyCB()); + set_cdm_ready_cb_.Run(CdmReadyCB()); base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); DoReset(); return; @@ -160,8 +159,8 @@ DecryptingDemuxerStream::~DecryptingDemuxerStream() { decryptor_->CancelDecrypt(GetDecryptorStreamType()); decryptor_ = NULL; } - if (!set_decryptor_ready_cb_.is_null()) - base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); + if (!set_cdm_ready_cb_.is_null()) + base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); if (!init_cb_.is_null()) base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); if (!read_cb_.is_null()) @@ -171,26 +170,25 @@ DecryptingDemuxerStream::~DecryptingDemuxerStream() { pending_buffer_to_decrypt_ = NULL; } -void DecryptingDemuxerStream::SetDecryptor( - Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb) { +void DecryptingDemuxerStream::SetCdm(CdmContext* cdm_context, + const CdmAttachedCB& cdm_attached_cb) { DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kDecryptorRequested) << state_; DCHECK(!init_cb_.is_null()); - DCHECK(!set_decryptor_ready_cb_.is_null()); + DCHECK(!set_cdm_ready_cb_.is_null()); - set_decryptor_ready_cb_.Reset(); + set_cdm_ready_cb_.Reset(); - if (!decryptor) { + if (!cdm_context || !cdm_context->GetDecryptor()) { MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": decryptor not set"; state_ = kUninitialized; base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); - decryptor_attached_cb.Run(false); + cdm_attached_cb.Run(false); return; } - decryptor_ = decryptor; + decryptor_ = cdm_context->GetDecryptor(); decryptor_->RegisterNewKeyCB( GetDecryptorStreamType(), @@ -199,7 +197,7 @@ void DecryptingDemuxerStream::SetDecryptor( state_ = kIdle; base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); - decryptor_attached_cb.Run(true); + cdm_attached_cb.Run(true); } void DecryptingDemuxerStream::DecryptBuffer( diff --git a/media/filters/decrypting_demuxer_stream.h b/media/filters/decrypting_demuxer_stream.h index a04709e..88f86a2 100644 --- a/media/filters/decrypting_demuxer_stream.h +++ b/media/filters/decrypting_demuxer_stream.h @@ -9,6 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "media/base/audio_decoder_config.h" +#include "media/base/cdm_context.h" #include "media/base/decryptor.h" #include "media/base/demuxer_stream.h" #include "media/base/pipeline_status.h" @@ -32,14 +33,13 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream { DecryptingDemuxerStream( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb); // Cancels all pending operations immediately and fires all pending callbacks. ~DecryptingDemuxerStream() override; - void Initialize(DemuxerStream* stream, - const PipelineStatusCB& status_cb); + void Initialize(DemuxerStream* stream, const PipelineStatusCB& status_cb); // Cancels all pending operations and fires all pending callbacks. If in // kPendingDemuxerRead or kPendingDecrypt state, waits for the pending @@ -74,10 +74,9 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream { kWaitingForKey }; - // Callback for DecryptorHost::RequestDecryptor(). |decryptor_attached_cb| is - // called when the decryptor has been completely attached to the pipeline. - void SetDecryptor(Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb); + // Callback to set CDM. |cdm_attached_cb| is called when the decryptor in the + // CDM has been completely attached to the pipeline. + void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); // Callback for DemuxerStream::Read(). void DecryptBuffer(DemuxerStream::Status status, @@ -120,8 +119,8 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream { AudioDecoderConfig audio_config_; VideoDecoderConfig video_config_; - // Callback to request/cancel decryptor creation notification. - SetDecryptorReadyCB set_decryptor_ready_cb_; + // Callback to request/cancel CDM ready notification. + SetCdmReadyCB set_cdm_ready_cb_; Decryptor* decryptor_; diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc index c679b56..7275029 100644 --- a/media/filters/decrypting_demuxer_stream_unittest.cc +++ b/media/filters/decrypting_demuxer_stream_unittest.cc @@ -51,20 +51,6 @@ ACTION_P(ReturnBuffer, buffer) { arg0.Run(buffer.get() ? DemuxerStream::kOk : DemuxerStream::kAborted, buffer); } -// Sets the |decryptor| if the DecryptorReadyCB (arg0) is not null. Sets -// |is_decryptor_set| to true if a non-NULL |decryptor| has been set through the -// callback. -ACTION_P3(SetDecryptorIfNotNull, decryptor, done_cb, is_decryptor_set) { - if (!arg0.is_null()) - arg0.Run(decryptor, done_cb); - - *is_decryptor_set = !arg0.is_null() && decryptor; -} - -ACTION_P2(ResetAndRunCallback, callback, param) { - base::ResetAndReturn(callback).Run(param); -} - MATCHER(IsEndOfStream, "end of stream") { return arg->end_of_stream(); } @@ -77,13 +63,13 @@ class DecryptingDemuxerStreamTest : public testing::Test { : demuxer_stream_(new DecryptingDemuxerStream( message_loop_.task_runner(), new MediaLog(), - base::Bind( - &DecryptingDemuxerStreamTest::RequestDecryptorNotification, - base::Unretained(this)), + base::Bind(&DecryptingDemuxerStreamTest::RequestCdmNotification, + base::Unretained(this)), base::Bind(&DecryptingDemuxerStreamTest::OnWaitingForDecryptionKey, base::Unretained(this)))), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new StrictMock<MockDecryptor>()), - is_decryptor_set_(false), + is_cdm_set_(false), input_audio_stream_( new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)), input_video_stream_( @@ -93,7 +79,7 @@ class DecryptingDemuxerStreamTest : public testing::Test { decrypted_buffer_(new DecoderBuffer(kFakeBufferSize)) {} virtual ~DecryptingDemuxerStreamTest() { - if (is_decryptor_set_) + if (is_cdm_set_) EXPECT_CALL(*decryptor_, CancelDecrypt(_)); demuxer_stream_.reset(); message_loop_.RunUntilIdle(); @@ -115,14 +101,25 @@ class DecryptingDemuxerStreamTest : public testing::Test { message_loop_.RunUntilIdle(); } - void ExpectDecryptorNotification(Decryptor* decryptor, bool expected_result) { - EXPECT_CALL(*this, RequestDecryptorNotification(_)) - .WillOnce(SetDecryptorIfNotNull( - decryptor, - base::Bind(&DecryptingDemuxerStreamTest::DecryptorSet, - base::Unretained(this)), - &is_decryptor_set_)); - EXPECT_CALL(*this, DecryptorSet(expected_result)); + enum CdmType { NO_CDM, CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR }; + + void SetCdmType(CdmType cdm_type) { + const bool has_cdm = cdm_type != NO_CDM; + const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR; + + EXPECT_CALL(*this, RequestCdmNotification(_)) + .WillOnce( + RunCallback<0>(has_cdm ? cdm_context_.get() : nullptr, + base::Bind(&DecryptingDemuxerStreamTest::CdmSet, + base::Unretained(this)))); + + if (has_cdm) { + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr)); + } + + EXPECT_CALL(*this, CdmSet(has_decryptor)) + .WillOnce(SaveArg<0>(&is_cdm_set_)); } // The following functions are used to test stream-type-neutral logic in @@ -131,7 +128,7 @@ class DecryptingDemuxerStreamTest : public testing::Test { // demuxer stream. void Initialize() { - ExpectDecryptorNotification(decryptor_.get(), true); + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); @@ -247,7 +244,7 @@ class DecryptingDemuxerStreamTest : public testing::Test { } void Reset() { - if (is_decryptor_set_) { + if (is_cdm_set_) { EXPECT_CALL(*decryptor_, CancelDecrypt(Decryptor::kAudio)) .WillRepeatedly(InvokeWithoutArgs( this, &DecryptingDemuxerStreamTest::AbortPendingDecryptCB)); @@ -257,20 +254,18 @@ class DecryptingDemuxerStreamTest : public testing::Test { message_loop_.RunUntilIdle(); } - MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&)); - + MOCK_METHOD1(RequestCdmNotification, void(const CdmReadyCB&)); MOCK_METHOD2(BufferReady, void(DemuxerStream::Status, const scoped_refptr<DecoderBuffer>&)); - - MOCK_METHOD1(DecryptorSet, void(bool)); - + MOCK_METHOD1(CdmSet, void(bool)); MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); base::MessageLoop message_loop_; scoped_ptr<DecryptingDemuxerStream> demuxer_stream_; - scoped_ptr<StrictMock<MockDecryptor> > decryptor_; + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; + scoped_ptr<StrictMock<MockDecryptor>> decryptor_; // Whether a valid Decryptor has been set in the |demuxer_stream_|. - bool is_decryptor_set_; + bool is_cdm_set_; scoped_ptr<StrictMock<MockDemuxerStream> > input_audio_stream_; scoped_ptr<StrictMock<MockDemuxerStream> > input_video_stream_; @@ -293,7 +288,7 @@ TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalAudio) { } TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) { - ExpectDecryptorNotification(decryptor_.get(), true); + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); @@ -313,8 +308,16 @@ TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) { ASSERT_EQ(input_config.extra_data(), output_config.extra_data()); } -TEST_F(DecryptingDemuxerStreamTest, Initialize_NullDecryptor) { - ExpectDecryptorNotification(NULL, false); +TEST_F(DecryptingDemuxerStreamTest, Initialize_NoCdm) { + SetCdmType(NO_CDM); + AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, + CHANNEL_LAYOUT_STEREO, 44100, + EmptyExtraData(), true); + InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED); +} + +TEST_F(DecryptingDemuxerStreamTest, Initialize_CdmWithoutDecryptor) { + SetCdmType(CDM_WITHOUT_DECRYPTOR); AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), true); @@ -389,8 +392,7 @@ TEST_F(DecryptingDemuxerStreamTest, KeyAdded_DruingPendingDecrypt) { // Test resetting in kDecryptorRequested state. TEST_F(DecryptingDemuxerStreamTest, Reset_DuringDecryptorRequested) { // One for decryptor request, one for canceling request during Reset(). - EXPECT_CALL(*this, RequestDecryptorNotification(_)) - .Times(2); + EXPECT_CALL(*this, RequestCdmNotification(_)).Times(2); AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), true); @@ -510,8 +512,7 @@ TEST_F(DecryptingDemuxerStreamTest, Reset_DuringConfigChangedDemuxerRead) { // Test destruction in kDecryptorRequested state. TEST_F(DecryptingDemuxerStreamTest, Destroy_DuringDecryptorRequested) { // One for decryptor request, one for canceling request during Reset(). - EXPECT_CALL(*this, RequestDecryptorNotification(_)) - .Times(2); + EXPECT_CALL(*this, RequestCdmNotification(_)).Times(2); AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), true); diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index 19e62b3..ac6a244 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc @@ -23,18 +23,17 @@ const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder"; DecryptingVideoDecoder::DecryptingVideoDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), media_log_(media_log), state_(kUninitialized), waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), - set_decryptor_ready_cb_(set_decryptor_ready_cb), + set_cdm_ready_cb_(set_cdm_ready_cb), decryptor_(NULL), key_added_while_decode_pending_(false), trace_id_(0), - weak_factory_(this) { -} + weak_factory_(this) {} std::string DecryptingVideoDecoder::GetDisplayName() const { return kDecoderName; @@ -61,8 +60,8 @@ void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, if (state_ == kUninitialized) { state_ = kDecryptorRequested; - set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( - &DecryptingVideoDecoder::SetDecryptor, weak_this_))); + set_cdm_ready_cb_.Run(BindToCurrentLoop( + base::Bind(&DecryptingVideoDecoder::SetCdm, weak_this_))); return; } @@ -145,8 +144,8 @@ DecryptingVideoDecoder::~DecryptingVideoDecoder() { decryptor_->DeinitializeDecoder(Decryptor::kVideo); decryptor_ = NULL; } - if (!set_decryptor_ready_cb_.is_null()) - base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); + if (!set_cdm_ready_cb_.is_null()) + base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); pending_buffer_to_decode_ = NULL; if (!init_cb_.is_null()) base::ResetAndReturn(&init_cb_).Run(false); @@ -156,32 +155,31 @@ DecryptingVideoDecoder::~DecryptingVideoDecoder() { base::ResetAndReturn(&reset_cb_).Run(); } -void DecryptingVideoDecoder::SetDecryptor( - Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb) { - DVLOG(2) << "SetDecryptor()"; +void DecryptingVideoDecoder::SetCdm(CdmContext* cdm_context, + const CdmAttachedCB& cdm_attached_cb) { + DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kDecryptorRequested) << state_; DCHECK(!init_cb_.is_null()); - DCHECK(!set_decryptor_ready_cb_.is_null()); - set_decryptor_ready_cb_.Reset(); + DCHECK(!set_cdm_ready_cb_.is_null()); + set_cdm_ready_cb_.Reset(); - if (!decryptor) { + if (!cdm_context || !cdm_context->GetDecryptor()) { MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor set"; base::ResetAndReturn(&init_cb_).Run(false); state_ = kError; - decryptor_attached_cb.Run(false); + cdm_attached_cb.Run(false); return; } - decryptor_ = decryptor; + decryptor_ = cdm_context->GetDecryptor(); state_ = kPendingDecoderInit; decryptor_->InitializeVideoDecoder( config_, BindToCurrentLoop(base::Bind( &DecryptingVideoDecoder::FinishInitialization, weak_this_))); - decryptor_attached_cb.Run(true); + cdm_attached_cb.Run(true); } void DecryptingVideoDecoder::FinishInitialization(bool success) { diff --git a/media/filters/decrypting_video_decoder.h b/media/filters/decrypting_video_decoder.h index 80b3b81..1ac97b8 100644 --- a/media/filters/decrypting_video_decoder.h +++ b/media/filters/decrypting_video_decoder.h @@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "media/base/cdm_context.h" #include "media/base/decryptor.h" #include "media/base/video_decoder.h" #include "media/base/video_decoder_config.h" @@ -30,7 +31,7 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder { DecryptingVideoDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<MediaLog>& media_log, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const base::Closure& waiting_for_decryption_key_cb); ~DecryptingVideoDecoder() override; @@ -61,10 +62,9 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder { kError }; - // Callback for DecryptorHost::RequestDecryptor(). |decryptor_attached_cb| is - // called when the decryptor has been completely attached to the pipeline. - void SetDecryptor(Decryptor* decryptor, - const DecryptorAttachedCB& decryptor_attached_cb); + // Callback to set CDM. |cdm_attached_cb| is called when the decryptor in the + // CDM has been completely attached to the pipeline. + void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); // Callback for Decryptor::InitializeVideoDecoder() during initialization. void FinishInitialization(bool success); @@ -97,8 +97,8 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder { VideoDecoderConfig config_; - // Callback to request/cancel decryptor creation notification. - SetDecryptorReadyCB set_decryptor_ready_cb_; + // Callback to request/cancel CDM ready notification. + SetCdmReadyCB set_cdm_ready_cb_; Decryptor* decryptor_; diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc index 5b8cf5c..dba3e2e 100644 --- a/media/filters/decrypting_video_decoder_unittest.cc +++ b/media/filters/decrypting_video_decoder_unittest.cc @@ -19,6 +19,7 @@ using ::testing::_; using ::testing::Invoke; +using ::testing::Return; using ::testing::SaveArg; using ::testing::StrictMock; @@ -56,11 +57,11 @@ class DecryptingVideoDecoderTest : public testing::Test { : decoder_(new DecryptingVideoDecoder( message_loop_.task_runner(), new MediaLog(), - base::Bind( - &DecryptingVideoDecoderTest::RequestDecryptorNotification, - base::Unretained(this)), + base::Bind(&DecryptingVideoDecoderTest::RequestCdmNotification, + base::Unretained(this)), base::Bind(&DecryptingVideoDecoderTest::OnWaitingForDecryptionKey, base::Unretained(this)))), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new StrictMock<MockDecryptor>()), num_decrypt_and_decode_calls_(0), num_frames_in_decryptor_(0), @@ -73,12 +74,23 @@ class DecryptingVideoDecoderTest : public testing::Test { Destroy(); } - void ExpectDecryptorNotification(Decryptor* decryptor, bool expected_result) { - EXPECT_CALL(*this, RequestDecryptorNotification(_)).WillOnce( - RunCallback<0>(decryptor, - base::Bind(&DecryptingVideoDecoderTest::DecryptorSet, - base::Unretained(this)))); - EXPECT_CALL(*this, DecryptorSet(expected_result)); + enum CdmType { NO_CDM, CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR }; + + void SetCdmType(CdmType cdm_type) { + const bool has_cdm = cdm_type != NO_CDM; + const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR; + + EXPECT_CALL(*this, RequestCdmNotification(_)) + .WillOnce(RunCallback<0>(has_cdm ? cdm_context_.get() : nullptr, + base::Bind(&DecryptingVideoDecoderTest::CdmSet, + base::Unretained(this)))); + + if (has_cdm) { + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr)); + } + + EXPECT_CALL(*this, CdmSet(has_decryptor)); } // Initializes the |decoder_| and expects |success|. Note the initialization @@ -93,7 +105,7 @@ class DecryptingVideoDecoderTest : public testing::Test { // Initialize the |decoder_| and expects it to succeed. void Initialize() { - ExpectDecryptorNotification(decryptor_.get(), true); + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) .WillOnce(RunCallback<1>(true)); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) @@ -223,18 +235,19 @@ class DecryptingVideoDecoderTest : public testing::Test { message_loop_.RunUntilIdle(); } - MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&)); + MOCK_METHOD1(RequestCdmNotification, void(const CdmReadyCB&)); MOCK_METHOD1(FrameReady, void(const scoped_refptr<VideoFrame>&)); MOCK_METHOD1(DecodeDone, void(VideoDecoder::Status)); - MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD1(CdmSet, void(bool)); MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); base::MessageLoop message_loop_; scoped_ptr<DecryptingVideoDecoder> decoder_; - scoped_ptr<StrictMock<MockDecryptor> > decryptor_; + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; + scoped_ptr<StrictMock<MockDecryptor>> decryptor_; // Variables to help the |decryptor_| to simulate decoding delay and flushing. int num_decrypt_and_decode_calls_; @@ -257,8 +270,13 @@ TEST_F(DecryptingVideoDecoderTest, Initialize_Normal) { Initialize(); } -TEST_F(DecryptingVideoDecoderTest, Initialize_NullDecryptor) { - ExpectDecryptorNotification(NULL, false); +TEST_F(DecryptingVideoDecoderTest, Initialize_NoCdm) { + SetCdmType(NO_CDM); + InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false); +} + +TEST_F(DecryptingVideoDecoderTest, Initialize_CdmWithoutDecryptor) { + SetCdmType(CDM_WITHOUT_DECRYPTOR); InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false); } @@ -267,7 +285,7 @@ TEST_F(DecryptingVideoDecoderTest, Initialize_Failure) { .WillRepeatedly(RunCallback<1>(false)); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) .WillRepeatedly(SaveArg<1>(&key_added_cb_)); - EXPECT_CALL(*this, RequestDecryptorNotification(_)).Times(2); + EXPECT_CALL(*this, RequestCdmNotification(_)).Times(2); InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false); } @@ -407,31 +425,31 @@ TEST_F(DecryptingVideoDecoderTest, Reset_AfterReset) { // Test destruction when the decoder is in kDecryptorRequested state. TEST_F(DecryptingVideoDecoderTest, Destroy_DuringDecryptorRequested) { - DecryptorReadyCB decryptor_ready_cb; - EXPECT_CALL(*this, RequestDecryptorNotification(_)) - .WillOnce(SaveArg<0>(&decryptor_ready_cb)); + CdmReadyCB cdm_ready_cb; + EXPECT_CALL(*this, RequestCdmNotification(_)) + .WillOnce(SaveArg<0>(&cdm_ready_cb)); decoder_->Initialize(TestVideoConfig::NormalEncrypted(), false, NewExpectedBoolCB(false), base::Bind(&DecryptingVideoDecoderTest::FrameReady, base::Unretained(this))); message_loop_.RunUntilIdle(); - // |decryptor_ready_cb| is saved but not called here. - EXPECT_FALSE(decryptor_ready_cb.is_null()); - - // During destruction, RequestDecryptorNotification() should be called with a - // NULL callback to cancel the |decryptor_ready_cb|. - EXPECT_CALL(*this, RequestDecryptorNotification(IsNullCallback())).WillOnce( - ResetAndRunCallback(&decryptor_ready_cb, - reinterpret_cast<Decryptor*>(NULL), - base::Bind(&DecryptingVideoDecoderTest::DecryptorSet, - base::Unretained(this)))); - EXPECT_CALL(*this, DecryptorSet(_)).Times(0); + // |cdm_ready_cb| is saved but not called here. + EXPECT_FALSE(cdm_ready_cb.is_null()); + + // During destruction, RequestCdmNotification() should be called with a + // NULL callback to cancel the |cdm_ready_cb|. + EXPECT_CALL(*this, RequestCdmNotification(IsNullCallback())) + .WillOnce( + ResetAndRunCallback(&cdm_ready_cb, nullptr, + base::Bind(&DecryptingVideoDecoderTest::CdmSet, + base::Unretained(this)))); + EXPECT_CALL(*this, CdmSet(_)).Times(0); Destroy(); } // Test destruction when the decoder is in kPendingDecoderInit state. TEST_F(DecryptingVideoDecoderTest, Destroy_DuringPendingDecoderInit) { - ExpectDecryptorNotification(decryptor_.get(), true); + SetCdmType(CDM_WITH_DECRYPTOR); EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) .WillOnce(SaveArg<1>(&pending_init_cb_)); diff --git a/media/filters/video_decoder_selector_unittest.cc b/media/filters/video_decoder_selector_unittest.cc index a0a889c..087661d 100644 --- a/media/filters/video_decoder_selector_unittest.cc +++ b/media/filters/video_decoder_selector_unittest.cc @@ -24,10 +24,10 @@ using ::testing::StrictMock; // times across multiple test files. Sadly we can't use static for them. namespace { -ACTION_P3(ExecuteCallbackWithVerifier, decryptor, done_cb, verifier) { +ACTION_P3(ExecuteCallbackWithVerifier, cdm_context, done_cb, verifier) { // verifier must be called first since |done_cb| call will invoke it as well. verifier->RecordACalled(); - arg0.Run(decryptor, done_cb); + arg0.Run(cdm_context, done_cb); } ACTION_P(ReportCallback, verifier) { @@ -60,21 +60,25 @@ class VideoDecoderSelectorTest : public ::testing::Test { VideoDecoderSelectorTest() : demuxer_stream_( new StrictMock<MockDemuxerStream>(DemuxerStream::VIDEO)), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new NiceMock<MockDecryptor>()), decoder_1_(new StrictMock<MockVideoDecoder>()), decoder_2_(new StrictMock<MockVideoDecoder>()) { all_decoders_.push_back(decoder_1_); all_decoders_.push_back(decoder_2_); + + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(decryptor_.get())); } ~VideoDecoderSelectorTest() { message_loop_.RunUntilIdle(); } - MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); + MOCK_METHOD1(SetCdmReadyCallback, void(const media::CdmReadyCB&)); MOCK_METHOD2(OnDecoderSelected, void(VideoDecoder*, DecryptingDemuxerStream*)); - MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD1(CdmSet, void(bool)); void MockOnDecoderSelected( scoped_ptr<VideoDecoder> decoder, @@ -96,13 +100,12 @@ class VideoDecoderSelectorTest : public ::testing::Test { int num_decoders) { if (decryptor_capability == kDecryptOnly || decryptor_capability == kDecryptAndDecode) { - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) + EXPECT_CALL(*this, SetCdmReadyCallback(_)) .WillRepeatedly(ExecuteCallbackWithVerifier( - decryptor_.get(), - base::Bind(&VideoDecoderSelectorTest::DecryptorSet, - base::Unretained(this)), + cdm_context_.get(), base::Bind(&VideoDecoderSelectorTest::CdmSet, + base::Unretained(this)), &verifier_)); - EXPECT_CALL(*this, DecryptorSet(true)) + EXPECT_CALL(*this, CdmSet(true)) .WillRepeatedly(ReportCallback(&verifier_)); if (decryptor_capability == kDecryptOnly) { @@ -113,11 +116,10 @@ class VideoDecoderSelectorTest : public ::testing::Test { .WillRepeatedly(RunCallback<1>(true)); } } else if (decryptor_capability == kHoldSetDecryptor) { - // Set and cancel DecryptorReadyCB but the callback is never fired. - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) - .Times(2); + // Set and cancel CdmReadyCB but the callback is never fired. + EXPECT_CALL(*this, SetCdmReadyCallback(_)).Times(2); } else if (decryptor_capability == kNoDecryptor) { - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) + EXPECT_CALL(*this, SetCdmReadyCallback(_)) .WillRepeatedly( RunCallback<0>(nullptr, base::Bind(&IgnoreCdmAttached))); } @@ -134,7 +136,7 @@ class VideoDecoderSelectorTest : public ::testing::Test { void SelectDecoder() { decoder_selector_->SelectDecoder( demuxer_stream_.get(), - base::Bind(&VideoDecoderSelectorTest::SetDecryptorReadyCallback, + base::Bind(&VideoDecoderSelectorTest::SetCdmReadyCallback, base::Unretained(this)), base::Bind(&VideoDecoderSelectorTest::MockOnDecoderSelected, base::Unretained(this)), @@ -163,11 +165,13 @@ class VideoDecoderSelectorTest : public ::testing::Test { // Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since // |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|. - scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_; + scoped_ptr<StrictMock<MockDemuxerStream>> demuxer_stream_; + + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; // Use NiceMock since we don't care about most of calls on the decryptor, e.g. // RegisterNewKeyCB(). - scoped_ptr<NiceMock<MockDecryptor> > decryptor_; + scoped_ptr<NiceMock<MockDecryptor>> decryptor_; scoped_ptr<VideoDecoderSelector> decoder_selector_; diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc index d195565..c9e9f0a 100644 --- a/media/filters/video_frame_stream_unittest.cc +++ b/media/filters/video_frame_stream_unittest.cc @@ -22,6 +22,7 @@ using ::testing::InvokeWithoutArgs; using ::testing::NiceMock; using ::testing::Return; using ::testing::SaveArg; +using ::testing::StrictMock; static const int kNumConfigs = 4; static const int kNumBuffersInOneConfig = 5; @@ -30,10 +31,10 @@ static const int kNumBuffersInOneConfig = 5; // times across multiple test files. Sadly we can't use static for them. namespace { -ACTION_P3(ExecuteCallbackWithVerifier, decryptor, done_cb, verifier) { +ACTION_P3(ExecuteCallbackWithVerifier, cdm_context, done_cb, verifier) { // verifier must be called first since |done_cb| call will invoke it as well. verifier->RecordACalled(); - arg0.Run(decryptor, done_cb); + arg0.Run(cdm_context, done_cb); } ACTION_P(ReportCallback, verifier) { @@ -65,23 +66,26 @@ class VideoFrameStreamTest : demuxer_stream_(new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, GetParam().is_encrypted)), + cdm_context_(new StrictMock<MockCdmContext>()), decryptor_(new NiceMock<MockDecryptor>()), - decoder1_(new FakeVideoDecoder( - GetParam().decoding_delay, - GetParam().parallel_decoding, - base::Bind(&VideoFrameStreamTest::OnBytesDecoded, - base::Unretained(this)))), - decoder2_(new FakeVideoDecoder( - GetParam().decoding_delay, - GetParam().parallel_decoding, - base::Bind(&VideoFrameStreamTest::OnBytesDecoded, - base::Unretained(this)))), - decoder3_(new FakeVideoDecoder( - GetParam().decoding_delay, - GetParam().parallel_decoding, - base::Bind(&VideoFrameStreamTest::OnBytesDecoded, - base::Unretained(this)))), - + decoder1_( + new FakeVideoDecoder(GetParam().decoding_delay, + GetParam().parallel_decoding, + base::Bind( + &VideoFrameStreamTest::OnBytesDecoded, + base::Unretained(this)))), + decoder2_( + new FakeVideoDecoder(GetParam().decoding_delay, + GetParam().parallel_decoding, + base::Bind( + &VideoFrameStreamTest::OnBytesDecoded, + base::Unretained(this)))), + decoder3_( + new FakeVideoDecoder(GetParam().decoding_delay, + GetParam().parallel_decoding, + base::Bind( + &VideoFrameStreamTest::OnBytesDecoded, + base::Unretained(this)))), is_initialized_(false), num_decoded_frames_(0), pending_initialize_(false), @@ -98,6 +102,9 @@ class VideoFrameStreamTest video_frame_stream_.reset(new VideoFrameStream( message_loop_.task_runner(), decoders.Pass(), new MediaLog())); + EXPECT_CALL(*cdm_context_, GetDecryptor()) + .WillRepeatedly(Return(decryptor_.get())); + // Decryptor can only decrypt (not decrypt-and-decode) so that // DecryptingDemuxerStream will be used. EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) @@ -124,8 +131,8 @@ class VideoFrameStreamTest } MOCK_METHOD1(OnNewSpliceBuffer, void(base::TimeDelta)); - MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); - MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD1(SetCdmReadyCallback, void(const media::CdmReadyCB&)); + MOCK_METHOD1(CdmSet, void(bool)); MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); void OnStatistics(const PipelineStatistics& statistics) { @@ -155,7 +162,7 @@ class VideoFrameStreamTest video_frame_stream_->Initialize( demuxer_stream_.get(), base::Bind(&VideoFrameStreamTest::OnInitialized, base::Unretained(this)), - base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback, + base::Bind(&VideoFrameStreamTest::SetCdmReadyCallback, base::Unretained(this)), base::Bind(&VideoFrameStreamTest::OnStatistics, base::Unretained(this)), base::Bind(&VideoFrameStreamTest::OnWaitingForDecryptionKey, @@ -246,15 +253,13 @@ class VideoFrameStreamTest DECODER_RESET }; - void ExpectDecryptorNotification() { - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) + void ExpectCdmNotification() { + EXPECT_CALL(*this, SetCdmReadyCallback(_)) .WillRepeatedly(ExecuteCallbackWithVerifier( - decryptor_.get(), - base::Bind(&VideoFrameStreamTest::DecryptorSet, - base::Unretained(this)), + cdm_context_.get(), + base::Bind(&VideoFrameStreamTest::CdmSet, base::Unretained(this)), &verifier_)); - EXPECT_CALL(*this, DecryptorSet(true)) - .WillRepeatedly(ReportCallback(&verifier_)); + EXPECT_CALL(*this, CdmSet(true)).WillRepeatedly(ReportCallback(&verifier_)); } void EnterPendingState(PendingState state) { @@ -275,9 +280,8 @@ class VideoFrameStreamTest break; case SET_DECRYPTOR: - // Hold DecryptorReadyCB. - EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) - .Times(2); + // Hold CdmReadyCB. + EXPECT_CALL(*this, SetCdmReadyCallback(_)).Times(2); // Initialize will fail because no decryptor is available. InitializeVideoFrameStream(); break; @@ -285,13 +289,13 @@ class VideoFrameStreamTest case DECRYPTOR_NO_KEY: if (GetParam().is_encrypted) EXPECT_CALL(*this, OnWaitingForDecryptionKey()); - ExpectDecryptorNotification(); + ExpectCdmNotification(); has_no_key_ = true; ReadOneFrame(); break; case DECODER_INIT: - ExpectDecryptorNotification(); + ExpectCdmNotification(); decoder->HoldNextInit(); InitializeVideoFrameStream(); break; @@ -387,9 +391,11 @@ class VideoFrameStreamTest scoped_ptr<VideoFrameStream> video_frame_stream_; scoped_ptr<FakeDemuxerStream> demuxer_stream_; + scoped_ptr<StrictMock<MockCdmContext>> cdm_context_; + // Use NiceMock since we don't care about most of calls on the decryptor, // e.g. RegisterNewKeyCB(). - scoped_ptr<NiceMock<MockDecryptor> > decryptor_; + scoped_ptr<NiceMock<MockDecryptor>> decryptor_; // Three decoders are needed to test that decoder fallback can occur more than // once on a config change. They are owned by |video_frame_stream_|. FakeVideoDecoder* decoder1_; diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index deb8dfe2..9a0cdf9 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc @@ -308,7 +308,7 @@ void AudioRendererImpl::StartPlaying() { void AudioRendererImpl::Initialize( DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, @@ -367,7 +367,7 @@ void AudioRendererImpl::Initialize( audio_buffer_stream_->Initialize( stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, weak_factory_.GetWeakPtr()), - set_decryptor_ready_cb, statistics_cb, waiting_for_decryption_key_cb); + set_cdm_ready_cb, statistics_cb, waiting_for_decryption_key_cb); } void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h index 0d3418d..de0cbda 100644 --- a/media/renderers/audio_renderer_impl.h +++ b/media/renderers/audio_renderer_impl.h @@ -78,7 +78,7 @@ class MEDIA_EXPORT AudioRendererImpl // AudioRenderer implementation. void Initialize(DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc index d26c0d8..0dd3969 100644 --- a/media/renderers/audio_renderer_impl_unittest.cc +++ b/media/renderers/audio_renderer_impl_unittest.cc @@ -124,7 +124,7 @@ class AudioRendererImplTest : public ::testing::Test { void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); renderer_->Initialize( - &demuxer_stream_, pipeline_status_cb, SetDecryptorReadyCB(), + &demuxer_stream_, pipeline_status_cb, SetCdmReadyCB(), base::Bind(&AudioRendererImplTest::OnStatistics, base::Unretained(this)), base::Bind(&AudioRendererImplTest::OnBufferingStateChange, diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 63c4a5f..a7bd113 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc @@ -121,13 +121,12 @@ void RendererImpl::SetCdm(CdmContext* cdm_context, cdm_context_ = cdm_context; - if (decryptor_ready_cb_.is_null()) { + if (cdm_ready_cb_.is_null()) { cdm_attached_cb.Run(true); return; } - base::ResetAndReturn(&decryptor_ready_cb_) - .Run(cdm_context->GetDecryptor(), cdm_attached_cb); + base::ResetAndReturn(&cdm_ready_cb_).Run(cdm_context, cdm_attached_cb); } void RendererImpl::Flush(const base::Closure& flush_cb) { @@ -253,27 +252,25 @@ bool RendererImpl::GetWallClockTimes( return time_source_->GetWallClockTimes(media_timestamps, wall_clock_times); } -void RendererImpl::SetDecryptorReadyCallback( - const DecryptorReadyCB& decryptor_ready_cb) { - // Cancels the previous decryptor request. - if (decryptor_ready_cb.is_null()) { - if (!decryptor_ready_cb_.is_null()) { - base::ResetAndReturn(&decryptor_ready_cb_) +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; } // We initialize audio and video decoders in sequence. - DCHECK(decryptor_ready_cb_.is_null()); + DCHECK(cdm_ready_cb_.is_null()); if (cdm_context_) { - decryptor_ready_cb.Run(cdm_context_->GetDecryptor(), - base::Bind(IgnoreCdmAttached)); + cdm_ready_cb.Run(cdm_context_, base::Bind(IgnoreCdmAttached)); return; } - decryptor_ready_cb_ = decryptor_ready_cb; + cdm_ready_cb_ = cdm_ready_cb; } void RendererImpl::InitializeAudioRenderer() { @@ -295,7 +292,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::SetDecryptorReadyCallback, weak_this_), + base::Bind(&RendererImpl::SetCdmReadyCallback, weak_this_), base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_), base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_, &audio_buffering_state_), @@ -342,7 +339,7 @@ void RendererImpl::InitializeVideoRenderer() { video_renderer_->Initialize( demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), done_cb, - base::Bind(&RendererImpl::SetDecryptorReadyCallback, weak_this_), + base::Bind(&RendererImpl::SetCdmReadyCallback, weak_this_), base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_), base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_, &video_buffering_state_), diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h index 56887c2..ccaabbe 100644 --- a/media/renderers/renderer_impl.h +++ b/media/renderers/renderer_impl.h @@ -85,11 +85,11 @@ class MEDIA_EXPORT RendererImpl : public Renderer { bool GetWallClockTimes(const std::vector<base::TimeDelta>& media_timestamps, std::vector<base::TimeTicks>* wall_clock_times); - // Requests that this object notifies when a decryptor is ready through the - // |decryptor_ready_cb| provided. - // If |decryptor_ready_cb| is null, the existing callback will be fired with + // Requests that this object notifies when a CDM is ready through the + // |cdm_ready_cb| provided. + // If |cdm_ready_cb| is null, the existing callback will be fired with // nullptr immediately and reset. - void SetDecryptorReadyCallback(const DecryptorReadyCB& decryptor_ready_cb); + void SetCdmReadyCallback(const CdmReadyCB& cdm_ready_cb); // Helper functions and callbacks for Initialize(). void InitializeAudioRenderer(); @@ -170,12 +170,12 @@ class MEDIA_EXPORT RendererImpl : public Renderer { CdmContext* cdm_context_; // Callback registered by filters (decoder or demuxer) to be informed of a - // Decryptor. + // CDM. // Note: We could have multiple filters registering this callback. One // callback is okay because: // 1, We always initialize filters in sequence. // 2, Filter initialization will not finish until this callback is satisfied. - DecryptorReadyCB decryptor_ready_cb_; + CdmReadyCB cdm_ready_cb_; bool underflow_disabled_for_testing_; bool clockless_video_playback_enabled_for_testing_; diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index fe724cb..e54e827 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc @@ -120,7 +120,7 @@ void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { void VideoRendererImpl::Initialize( DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, @@ -165,7 +165,7 @@ void VideoRendererImpl::Initialize( video_frame_stream_->Initialize( stream, base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized, weak_factory_.GetWeakPtr()), - set_decryptor_ready_cb, statistics_cb, waiting_for_decryption_key_cb); + set_cdm_ready_cb, statistics_cb, waiting_for_decryption_key_cb); } scoped_refptr<VideoFrame> VideoRendererImpl::Render( diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h index 75a8d03..974da42 100644 --- a/media/renderers/video_renderer_impl.h +++ b/media/renderers/video_renderer_impl.h @@ -62,7 +62,7 @@ class MEDIA_EXPORT VideoRendererImpl // VideoRenderer implementation. void Initialize(DemuxerStream* stream, const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, + const SetCdmReadyCB& set_cdm_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc index f7dcb10..74d9a1e 100644 --- a/media/renderers/video_renderer_impl_unittest.cc +++ b/media/renderers/video_renderer_impl_unittest.cc @@ -119,7 +119,7 @@ class VideoRendererImplTest DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(expect_to_success))); EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); renderer_->Initialize( - &demuxer_stream_, status_cb, media::SetDecryptorReadyCB(), + &demuxer_stream_, status_cb, SetCdmReadyCB(), base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, base::Unretained(this)), base::Bind(&StrictMock<MockCB>::BufferingStateChange, |