summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorjrummell <jrummell@chromium.org>2015-03-02 14:48:27 -0800
committerCommit bot <commit-bot@chromium.org>2015-03-02 22:49:21 +0000
commit74fc4f9447f3ea2e277350dccce4de67e5ee4ea4 (patch)
tree5421eca29629684887a485bac69460fc6cbd5032 /media
parente86e411c3038fd5be67438da29f0ff17828f226f (diff)
downloadchromium_src-74fc4f9447f3ea2e277350dccce4de67e5ee4ea4.zip
chromium_src-74fc4f9447f3ea2e277350dccce4de67e5ee4ea4.tar.gz
chromium_src-74fc4f9447f3ea2e277350dccce4de67e5ee4ea4.tar.bz2
Decryptors can report kNoKey to WebMediaPlayer
Add callback so that kNoKey can get passed to blink in order to generate the HTMLMediaElement.waitingforkey event. BUG=337975 TEST=updated tests pass Review URL: https://codereview.chromium.org/935243002 Cr-Commit-Position: refs/heads/master@{#318787}
Diffstat (limited to 'media')
-rw-r--r--media/base/audio_renderer.h19
-rw-r--r--media/base/mock_filters.h42
-rw-r--r--media/base/pipeline.cc7
-rw-r--r--media/base/pipeline.h6
-rw-r--r--media/base/pipeline_unittest.cc14
-rw-r--r--media/base/renderer.h18
-rw-r--r--media/base/video_renderer.h23
-rw-r--r--media/blink/webmediaplayer_impl.cc12
-rw-r--r--media/blink/webmediaplayer_impl.h4
-rw-r--r--media/filters/audio_decoder_selector_unittest.cc7
-rw-r--r--media/filters/decoder_selector.cc10
-rw-r--r--media/filters/decoder_selector.h4
-rw-r--r--media/filters/decoder_stream.cc7
-rw-r--r--media/filters/decoder_stream.h4
-rw-r--r--media/filters/decrypting_audio_decoder.cc8
-rw-r--r--media/filters/decrypting_audio_decoder.h4
-rw-r--r--media/filters/decrypting_audio_decoder_unittest.cc7
-rw-r--r--media/filters/decrypting_demuxer_stream.cc8
-rw-r--r--media/filters/decrypting_demuxer_stream.h4
-rw-r--r--media/filters/decrypting_demuxer_stream_unittest.cc7
-rw-r--r--media/filters/decrypting_video_decoder.cc8
-rw-r--r--media/filters/decrypting_video_decoder.h4
-rw-r--r--media/filters/decrypting_video_decoder_unittest.cc10
-rw-r--r--media/filters/video_decoder_selector_unittest.cc6
-rw-r--r--media/filters/video_frame_stream_unittest.cc6
-rw-r--r--media/mojo/services/mojo_renderer_impl.cc6
-rw-r--r--media/mojo/services/mojo_renderer_impl.h3
-rw-r--r--media/mojo/services/mojo_renderer_service.cc3
-rw-r--r--media/renderers/audio_renderer_impl.cc5
-rw-r--r--media/renderers/audio_renderer_impl.h3
-rw-r--r--media/renderers/audio_renderer_impl_unittest.cc6
-rw-r--r--media/renderers/renderer_impl.cc23
-rw-r--r--media/renderers/renderer_impl.h4
-rw-r--r--media/renderers/renderer_impl_unittest.cc12
-rw-r--r--media/renderers/video_renderer_impl.cc5
-rw-r--r--media/renderers/video_renderer_impl.h3
-rw-r--r--media/renderers/video_renderer_impl_unittest.cc7
-rw-r--r--media/test/pipeline_integration_test.cc16
-rw-r--r--media/test/pipeline_integration_test_base.cc8
-rw-r--r--media/test/pipeline_integration_test_base.h1
-rw-r--r--media/tools/player_x11/player_x11.cc3
41 files changed, 253 insertions, 104 deletions
diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h
index 7d0e3d7..586936a 100644
--- a/media/base/audio_renderer.h
+++ b/media/base/audio_renderer.h
@@ -39,13 +39,18 @@ class MEDIA_EXPORT AudioRenderer {
// |ended_cb| is executed when audio rendering has reached the end of stream.
//
// |error_cb| is executed if an error was encountered after initialization.
- virtual void Initialize(DemuxerStream* stream,
- const PipelineStatusCB& init_cb,
- const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) = 0;
+ //
+ // |waiting_for_decryption_key_cb| is called whenever the key needed to
+ // decrypt the stream is not available.
+ virtual void Initialize(
+ DemuxerStream* stream,
+ const PipelineStatusCB& init_cb,
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) = 0;
// Returns the TimeSource associated with audio rendering.
virtual TimeSource* GetTimeSource() = 0;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index c8d1c82..9731fd0 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -121,16 +121,17 @@ class MockVideoRenderer : public VideoRenderer {
virtual ~MockVideoRenderer();
// VideoRenderer implementation.
- MOCK_METHOD9(Initialize,
- void(DemuxerStream* stream,
- const PipelineStatusCB& init_cb,
- const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const PaintCB& paint_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const TimeDeltaCB& get_time_cb));
+ MOCK_METHOD10(Initialize,
+ void(DemuxerStream* stream,
+ const PipelineStatusCB& init_cb,
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const TimeDeltaCB& get_time_cb,
+ const base::Closure& waiting_for_decryption_key_cb));
MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta));
@@ -144,14 +145,15 @@ class MockAudioRenderer : public AudioRenderer {
virtual ~MockAudioRenderer();
// AudioRenderer implementation.
- MOCK_METHOD7(Initialize,
+ MOCK_METHOD8(Initialize,
void(DemuxerStream* stream,
const PipelineStatusCB& init_cb,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb));
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb));
MOCK_METHOD0(GetTimeSource, TimeSource*());
MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD0(StartPlaying, void());
@@ -167,13 +169,15 @@ class MockRenderer : public Renderer {
virtual ~MockRenderer();
// Renderer implementation.
- MOCK_METHOD7(Initialize, void(DemuxerStreamProvider* demuxer_stream_provider,
- const PipelineStatusCB& init_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const PaintCB& paint_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb));
+ MOCK_METHOD8(Initialize,
+ void(DemuxerStreamProvider* demuxer_stream_provider,
+ const PipelineStatusCB& init_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb));
MOCK_METHOD1(Flush, void(const base::Closure& flush_cb));
MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta timestamp));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index e9c52d6..d1fae01 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -70,7 +70,8 @@ void Pipeline::Start(Demuxer* demuxer,
const BufferingStateCB& buffering_state_cb,
const PaintCB& paint_cb,
const base::Closure& duration_change_cb,
- const AddTextTrackCB& add_text_track_cb) {
+ const AddTextTrackCB& add_text_track_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
DCHECK(!ended_cb.is_null());
DCHECK(!error_cb.is_null());
DCHECK(!seek_cb.is_null());
@@ -92,6 +93,7 @@ void Pipeline::Start(Demuxer* demuxer,
paint_cb_ = paint_cb;
duration_change_cb_ = duration_change_cb;
add_text_track_cb_ = add_text_track_cb;
+ waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
task_runner_->PostTask(
FROM_HERE, base::Bind(&Pipeline::StartTask, weak_factory_.GetWeakPtr()));
@@ -724,7 +726,8 @@ void Pipeline::InitializeRenderer(const PipelineStatusCB& done_cb) {
base::Bind(&Pipeline::BufferingStateChanged, weak_this),
base::ResetAndReturn(&paint_cb_),
base::Bind(&Pipeline::OnRendererEnded, weak_this),
- base::Bind(&Pipeline::OnError, weak_this));
+ base::Bind(&Pipeline::OnError, weak_this),
+ waiting_for_decryption_key_cb_);
}
void Pipeline::ReportMetadata() {
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 6bca477..30707b3 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -105,6 +105,8 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// |duration_change_cb| optional callback that will be executed whenever the
// presentation duration changes.
// |add_text_track_cb| will be executed whenever a text track is added.
+ // |waiting_for_decryption_key_cb| will be executed whenever the key needed
+ // to decrypt the stream is not available.
// It is an error to call this method after the pipeline has already started.
void Start(Demuxer* demuxer,
scoped_ptr<Renderer> renderer,
@@ -115,7 +117,8 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
const BufferingStateCB& buffering_state_cb,
const PaintCB& paint_cb,
const base::Closure& duration_change_cb,
- const AddTextTrackCB& add_text_track_cb);
+ const AddTextTrackCB& add_text_track_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
// Asynchronously stops the pipeline, executing |stop_cb| when the pipeline
// teardown has completed.
@@ -360,6 +363,7 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
PaintCB paint_cb_;
base::Closure duration_change_cb_;
AddTextTrackCB add_text_track_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
// Holds the initialized demuxer. Used for seeking. Owned by client.
Demuxer* demuxer_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index affb643..147e744 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -170,7 +170,7 @@ class PipelineTest : public ::testing::Test {
// Sets up expectations to allow the video renderer to initialize.
void SetRendererExpectations() {
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_),
SaveArg<5>(&ended_cb_),
PostCallback<1>(PIPELINE_OK)));
@@ -187,6 +187,7 @@ class PipelineTest : public ::testing::Test {
}
void StartPipeline() {
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
pipeline_->Start(
demuxer_.get(), scoped_renderer_.Pass(),
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
@@ -199,7 +200,9 @@ class PipelineTest : public ::testing::Test {
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnDurationChange,
base::Unretained(&callbacks_)),
- base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this)));
+ base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this)),
+ base::Bind(&PipelineTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
}
// Sets up expectations on the callback and initializes the pipeline. Called
@@ -296,6 +299,7 @@ class PipelineTest : public ::testing::Test {
MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&,
const AddTextTrackDoneCB&));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
void DoOnAddTextTrack(const TextTrackConfig& config,
const AddTextTrackDoneCB& done_cb) {
@@ -857,13 +861,13 @@ class PipelineTeardownTest : public PipelineTest {
if (state == kInitRenderer) {
if (stop_or_error == kStop) {
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _))
.WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
PostCallback<1>(PIPELINE_OK)));
ExpectPipelineStopAndDestroyPipeline();
} else {
status = PIPELINE_ERROR_INITIALIZATION_FAILED;
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _))
.WillOnce(PostCallback<1>(status));
}
@@ -872,7 +876,7 @@ class PipelineTeardownTest : public PipelineTest {
return status;
}
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_),
PostCallback<1>(PIPELINE_OK)));
diff --git a/media/base/renderer.h b/media/base/renderer.h
index 1c7afbd..e3647f7 100644
--- a/media/base/renderer.h
+++ b/media/base/renderer.h
@@ -43,13 +43,17 @@ class MEDIA_EXPORT Renderer {
// be called from any thread.
// - |ended_cb|: Executed when rendering has reached the end of stream.
// - |error_cb|: Executed if any error was encountered after initialization.
- virtual void Initialize(DemuxerStreamProvider* demuxer_stream_provider,
- const PipelineStatusCB& init_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const PaintCB& paint_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) = 0;
+ // - |waiting_for_decryption_key_cb|: Executed whenever the key needed to
+ // decrypt the stream is not available.
+ virtual void Initialize(
+ DemuxerStreamProvider* demuxer_stream_provider,
+ const PipelineStatusCB& init_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) = 0;
// Associates the |cdm_context| with this Renderer for decryption (and
// decoding) of media data, then fires |cdm_attached_cb| with the result.
diff --git a/media/base/video_renderer.h b/media/base/video_renderer.h
index 1e44333..7a764b3 100644
--- a/media/base/video_renderer.h
+++ b/media/base/video_renderer.h
@@ -53,15 +53,20 @@ class MEDIA_EXPORT VideoRenderer {
// |error_cb| is executed if an error was encountered after initialization.
//
// |get_time_cb| is used to query the current media playback time.
- virtual void Initialize(DemuxerStream* stream,
- const PipelineStatusCB& init_cb,
- const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const PaintCB& paint_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const TimeDeltaCB& get_time_cb) = 0;
+ //
+ // |waiting_for_decryption_key_cb| is executed whenever the key needed to
+ // decrypt the stream is not available.
+ virtual void Initialize(
+ DemuxerStream* stream,
+ const PipelineStatusCB& init_cb,
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const TimeDeltaCB& get_time_cb,
+ const base::Closure& waiting_for_decryption_key_cb) = 0;
// Discards any video data and stops reading from |stream|, executing
// |callback| when completed.
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index a7a7201..148daf61 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -692,6 +692,15 @@ void WebMediaPlayerImpl::OnEncryptedMediaInitData(
base::saturated_cast<unsigned int>(init_data.size()));
}
+void WebMediaPlayerImpl::OnWaitingForDecryptionKey() {
+ client_->didBlockPlaybackWaitingForKey();
+
+ // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called
+ // when a key has been successfully added (e.g. OnSessionKeysChange() with
+ // |has_additional_usable_key| = true). http://crbug.com/461903
+ client_->didResumePlaybackBlockedForKey();
+}
+
void WebMediaPlayerImpl::SetCdm(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) {
pipeline_.SetCdm(cdm_context, cdm_attached_cb);
@@ -903,7 +912,8 @@ void WebMediaPlayerImpl::StartPipeline() {
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged),
base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged),
- BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack));
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack),
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey));
}
void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index acfdf97..0dc60db 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -212,6 +212,10 @@ class MEDIA_EXPORT WebMediaPlayerImpl
void OnEncryptedMediaInitData(const std::string& init_data_type,
const std::vector<uint8>& init_data);
+ // Called when a decoder detects that the key needed to decrypt the stream
+ // is not available.
+ void OnWaitingForDecryptionKey();
+
void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb);
// Called when a CDM has been attached to the |pipeline_|.
diff --git a/media/filters/audio_decoder_selector_unittest.cc b/media/filters/audio_decoder_selector_unittest.cc
index 36f7ca64..2bb1f6d 100644
--- a/media/filters/audio_decoder_selector_unittest.cc
+++ b/media/filters/audio_decoder_selector_unittest.cc
@@ -135,7 +135,8 @@ class AudioDecoderSelectorTest : public ::testing::Test {
base::Unretained(this)),
base::Bind(&AudioDecoderSelectorTest::MockOnDecoderSelected,
base::Unretained(this)),
- base::Bind(&AudioDecoderSelectorTest::OnDecoderOutput));
+ base::Bind(&AudioDecoderSelectorTest::OnDecoderOutput),
+ base::Bind(&AudioDecoderSelectorTest::OnWaitingForDecryptionKey));
message_loop_.RunUntilIdle();
}
@@ -151,6 +152,10 @@ class AudioDecoderSelectorTest : public ::testing::Test {
NOTREACHED();
}
+ static void OnWaitingForDecryptionKey() {
+ NOTREACHED();
+ }
+
// Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since
// |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|.
scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc
index f026acd..555a411 100644
--- a/media/filters/decoder_selector.cc
+++ b/media/filters/decoder_selector.cc
@@ -75,13 +75,15 @@ void DecoderSelector<StreamType>::SelectDecoder(
DemuxerStream* stream,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
const SelectDecoderCB& select_decoder_cb,
- const typename Decoder::OutputCB& output_cb) {
+ const typename Decoder::OutputCB& output_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
DVLOG(2) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(stream);
DCHECK(select_decoder_cb_.is_null());
set_decryptor_ready_cb_ = set_decryptor_ready_cb;
+ waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
// Make sure |select_decoder_cb| runs on a different execution stack.
select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb);
@@ -107,7 +109,7 @@ void DecoderSelector<StreamType>::SelectDecoder(
}
decoder_.reset(new typename StreamTraits::DecryptingDecoderType(
- task_runner_, set_decryptor_ready_cb_));
+ task_runner_, set_decryptor_ready_cb_, waiting_for_decryption_key_cb_));
DecoderStreamTraits<StreamType>::InitializeDecoder(
decoder_.get(), input_stream_,
@@ -130,8 +132,8 @@ void DecoderSelector<StreamType>::DecryptingDecoderInitDone(
decoder_.reset();
- decrypted_stream_.reset(
- new DecryptingDemuxerStream(task_runner_, set_decryptor_ready_cb_));
+ decrypted_stream_.reset(new DecryptingDemuxerStream(
+ task_runner_, set_decryptor_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 d13eb9b..59c90f5 100644
--- a/media/filters/decoder_selector.h
+++ b/media/filters/decoder_selector.h
@@ -70,7 +70,8 @@ class MEDIA_EXPORT DecoderSelector {
void SelectDecoder(DemuxerStream* stream,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
const SelectDecoderCB& select_decoder_cb,
- const typename Decoder::OutputCB& output_cb);
+ const typename Decoder::OutputCB& output_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
private:
void DecryptingDecoderInitDone(PipelineStatus status);
@@ -86,6 +87,7 @@ class MEDIA_EXPORT DecoderSelector {
SetDecryptorReadyCB set_decryptor_ready_cb_;
SelectDecoderCB select_decoder_cb_;
typename Decoder::OutputCB output_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
scoped_ptr<Decoder> decoder_;
scoped_ptr<DecryptingDemuxerStream> decrypted_stream_;
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index f9fa8b2..3a366d8 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -83,7 +83,8 @@ void DecoderStream<StreamType>::Initialize(
DemuxerStream* stream,
const InitCB& init_cb,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const StatisticsCB& statistics_cb) {
+ const StatisticsCB& statistics_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
FUNCTION_DVLOG(2);
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, STATE_UNINITIALIZED);
@@ -92,6 +93,7 @@ void DecoderStream<StreamType>::Initialize(
statistics_cb_ = statistics_cb;
init_cb_ = init_cb;
+ waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
stream_ = stream;
state_ = STATE_INITIALIZING;
@@ -212,7 +214,8 @@ void DecoderStream<StreamType>::SelectDecoder(
base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
weak_factory_.GetWeakPtr()),
base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr()),
+ waiting_for_decryption_key_cb_);
}
template <DemuxerStream::Type StreamType>
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h
index b8a0d04..3c0e23e 100644
--- a/media/filters/decoder_stream.h
+++ b/media/filters/decoder_stream.h
@@ -61,7 +61,8 @@ class MEDIA_EXPORT DecoderStream {
void Initialize(DemuxerStream* stream,
const InitCB& init_cb,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const StatisticsCB& statistics_cb);
+ const StatisticsCB& statistics_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
// Reads a decoded Output and returns it via the |read_cb|. Note that
// |read_cb| is always called asynchronously. This method should only be
@@ -170,6 +171,7 @@ class MEDIA_EXPORT DecoderStream {
StatisticsCB statistics_cb_;
InitCB init_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
ReadCB read_cb_;
base::Closure reset_cb_;
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc
index 0ca20f7..3425d0c2 100644
--- a/media/filters/decrypting_audio_decoder.cc
+++ b/media/filters/decrypting_audio_decoder.cc
@@ -34,13 +34,16 @@ static inline bool IsOutOfSync(const base::TimeDelta& timestamp_1,
DecryptingAudioDecoder::DecryptingAudioDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb)
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb)
: task_runner_(task_runner),
state_(kUninitialized),
+ waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb),
set_decryptor_ready_cb_(set_decryptor_ready_cb),
decryptor_(NULL),
key_added_while_decode_pending_(false),
- weak_factory_(this) {}
+ weak_factory_(this) {
+}
std::string DecryptingAudioDecoder::GetDisplayName() const {
return "DecryptingAudioDecoder";
@@ -288,6 +291,7 @@ void DecryptingAudioDecoder::DeliverFrame(
}
state_ = kWaitingForKey;
+ waiting_for_decryption_key_cb_.Run();
return;
}
diff --git a/media/filters/decrypting_audio_decoder.h b/media/filters/decrypting_audio_decoder.h
index 67da6c0..30b0a63 100644
--- a/media/filters/decrypting_audio_decoder.h
+++ b/media/filters/decrypting_audio_decoder.h
@@ -32,7 +32,8 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder {
public:
DecryptingAudioDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb);
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
~DecryptingAudioDecoder() override;
// AudioDecoder implementation.
@@ -96,6 +97,7 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder {
OutputCB output_cb_;
DecodeCB decode_cb_;
base::Closure reset_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
// The current decoder configuration.
AudioDecoderConfig config_;
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc
index 49df3ce..1f8395b 100644
--- a/media/filters/decrypting_audio_decoder_unittest.cc
+++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -63,7 +63,9 @@ class DecryptingAudioDecoderTest : public testing::Test {
message_loop_.message_loop_proxy(),
base::Bind(
&DecryptingAudioDecoderTest::RequestDecryptorNotification,
- base::Unretained(this)))),
+ base::Unretained(this)),
+ base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)))),
decryptor_(new StrictMock<MockDecryptor>()),
num_decrypt_and_decode_calls_(0),
num_frames_in_decryptor_(0),
@@ -204,6 +206,7 @@ class DecryptingAudioDecoderTest : public testing::Test {
EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
.WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
Decryptor::AudioFrames()));
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey());
decoder_->Decode(encrypted_buffer_,
base::Bind(&DecryptingAudioDecoderTest::DecodeDone,
base::Unretained(this)));
@@ -252,6 +255,8 @@ class DecryptingAudioDecoderTest : public testing::Test {
MOCK_METHOD1(DecryptorSet, void(bool));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
+
base::MessageLoop message_loop_;
scoped_ptr<DecryptingAudioDecoder> decoder_;
scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc
index 601fd46..7a6f43c 100644
--- a/media/filters/decrypting_demuxer_stream.cc
+++ b/media/filters/decrypting_demuxer_stream.cc
@@ -30,14 +30,17 @@ static bool IsStreamValidAndEncrypted(DemuxerStream* stream) {
DecryptingDemuxerStream::DecryptingDemuxerStream(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb)
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb)
: task_runner_(task_runner),
state_(kUninitialized),
+ waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb),
demuxer_stream_(NULL),
set_decryptor_ready_cb_(set_decryptor_ready_cb),
decryptor_(NULL),
key_added_while_decrypt_pending_(false),
- weak_factory_(this) {}
+ weak_factory_(this) {
+}
void DecryptingDemuxerStream::Initialize(DemuxerStream* stream,
const PipelineStatusCB& status_cb) {
@@ -311,6 +314,7 @@ void DecryptingDemuxerStream::DeliverBuffer(
}
state_ = kWaitingForKey;
+ waiting_for_decryption_key_cb_.Run();
return;
}
diff --git a/media/filters/decrypting_demuxer_stream.h b/media/filters/decrypting_demuxer_stream.h
index f66f9ab..e8d8222 100644
--- a/media/filters/decrypting_demuxer_stream.h
+++ b/media/filters/decrypting_demuxer_stream.h
@@ -30,7 +30,8 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream {
public:
DecryptingDemuxerStream(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb);
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
// Cancels all pending operations immediately and fires all pending callbacks.
~DecryptingDemuxerStream() override;
@@ -104,6 +105,7 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream {
PipelineStatusCB init_cb_;
ReadCB read_cb_;
base::Closure reset_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
// Pointer to the input demuxer stream that will feed us encrypted buffers.
DemuxerStream* demuxer_stream_;
diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc
index fa2a36c..3cba1f7 100644
--- a/media/filters/decrypting_demuxer_stream_unittest.cc
+++ b/media/filters/decrypting_demuxer_stream_unittest.cc
@@ -77,7 +77,9 @@ class DecryptingDemuxerStreamTest : public testing::Test {
message_loop_.message_loop_proxy(),
base::Bind(
&DecryptingDemuxerStreamTest::RequestDecryptorNotification,
- base::Unretained(this)))),
+ base::Unretained(this)),
+ base::Bind(&DecryptingDemuxerStreamTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)))),
decryptor_(new StrictMock<MockDecryptor>()),
is_decryptor_set_(false),
input_audio_stream_(
@@ -225,6 +227,7 @@ class DecryptingDemuxerStreamTest : public testing::Test {
EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _))
.WillRepeatedly(RunCallback<2>(Decryptor::kNoKey,
scoped_refptr<DecoderBuffer>()));
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey());
demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady,
base::Unretained(this)));
message_loop_.RunUntilIdle();
@@ -260,6 +263,8 @@ class DecryptingDemuxerStreamTest : public testing::Test {
MOCK_METHOD1(DecryptorSet, void(bool));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
+
base::MessageLoop message_loop_;
scoped_ptr<DecryptingDemuxerStream> demuxer_stream_;
scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc
index f4aa375..d9bba50 100644
--- a/media/filters/decrypting_video_decoder.cc
+++ b/media/filters/decrypting_video_decoder.cc
@@ -23,14 +23,17 @@ const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder";
DecryptingVideoDecoder::DecryptingVideoDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb)
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb)
: task_runner_(task_runner),
state_(kUninitialized),
+ waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb),
set_decryptor_ready_cb_(set_decryptor_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;
@@ -270,6 +273,7 @@ void DecryptingVideoDecoder::DeliverFrame(
}
state_ = kWaitingForKey;
+ waiting_for_decryption_key_cb_.Run();
return;
}
diff --git a/media/filters/decrypting_video_decoder.h b/media/filters/decrypting_video_decoder.h
index 8e40502..a2a9528 100644
--- a/media/filters/decrypting_video_decoder.h
+++ b/media/filters/decrypting_video_decoder.h
@@ -28,7 +28,8 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder {
public:
DecryptingVideoDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const SetDecryptorReadyCB& set_decryptor_ready_cb);
+ const SetDecryptorReadyCB& set_decryptor_ready_cb,
+ const base::Closure& waiting_for_decryption_key_cb);
~DecryptingVideoDecoder() override;
// VideoDecoder implementation.
@@ -88,6 +89,7 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder {
OutputCB output_cb_;
DecodeCB decode_cb_;
base::Closure reset_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
VideoDecoderConfig config_;
diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc
index 11dc52a..285bab6 100644
--- a/media/filters/decrypting_video_decoder_unittest.cc
+++ b/media/filters/decrypting_video_decoder_unittest.cc
@@ -57,7 +57,9 @@ class DecryptingVideoDecoderTest : public testing::Test {
message_loop_.message_loop_proxy(),
base::Bind(
&DecryptingVideoDecoderTest::RequestDecryptorNotification,
- base::Unretained(this)))),
+ base::Unretained(this)),
+ base::Bind(&DecryptingVideoDecoderTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)))),
decryptor_(new StrictMock<MockDecryptor>()),
num_decrypt_and_decode_calls_(0),
num_frames_in_decryptor_(0),
@@ -179,6 +181,7 @@ class DecryptingVideoDecoderTest : public testing::Test {
void EnterWaitingForKeyState() {
EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _))
.WillRepeatedly(RunCallback<1>(Decryptor::kNoKey, null_video_frame_));
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey());
decoder_->Decode(encrypted_buffer_,
base::Bind(&DecryptingVideoDecoderTest::DecodeDone,
base::Unretained(this)));
@@ -227,6 +230,8 @@ class DecryptingVideoDecoderTest : public testing::Test {
MOCK_METHOD1(DecryptorSet, void(bool));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
+
base::MessageLoop message_loop_;
scoped_ptr<DecryptingVideoDecoder> decoder_;
scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
@@ -263,6 +268,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);
InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(),
DECODER_ERROR_NOT_SUPPORTED);
@@ -333,7 +339,7 @@ TEST_F(DecryptingVideoDecoderTest, KeyAdded_DuringWaitingForKey) {
// Test the case where the a key is added when the decryptor is in
// kPendingDecode state.
-TEST_F(DecryptingVideoDecoderTest, KeyAdded_DruingPendingDecode) {
+TEST_F(DecryptingVideoDecoderTest, KeyAdded_DuringPendingDecode) {
Initialize();
EnterPendingDecodeState();
diff --git a/media/filters/video_decoder_selector_unittest.cc b/media/filters/video_decoder_selector_unittest.cc
index f2dabdf..86f4c0e 100644
--- a/media/filters/video_decoder_selector_unittest.cc
+++ b/media/filters/video_decoder_selector_unittest.cc
@@ -131,6 +131,8 @@ class VideoDecoderSelectorTest : public ::testing::Test {
base::Bind(&VideoDecoderSelectorTest::MockOnDecoderSelected,
base::Unretained(this)),
base::Bind(&VideoDecoderSelectorTest::FrameReady,
+ base::Unretained(this)),
+ base::Bind(&VideoDecoderSelectorTest::OnWaitingForDecryptionKey,
base::Unretained(this)));
message_loop_.RunUntilIdle();
}
@@ -147,6 +149,10 @@ class VideoDecoderSelectorTest : public ::testing::Test {
NOTREACHED();
}
+ void OnWaitingForDecryptionKey() {
+ NOTREACHED();
+ }
+
// Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since
// |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|.
scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc
index f71c07f..a9f3b60 100644
--- a/media/filters/video_frame_stream_unittest.cc
+++ b/media/filters/video_frame_stream_unittest.cc
@@ -125,6 +125,7 @@ class VideoFrameStreamTest
MOCK_METHOD1(OnNewSpliceBuffer, void(base::TimeDelta));
MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
MOCK_METHOD1(DecryptorSet, void(bool));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
void OnStatistics(const PipelineStatistics& statistics) {
num_decoded_bytes_unreported_ -= statistics.video_bytes_decoded;
@@ -155,7 +156,8 @@ class VideoFrameStreamTest
base::Unretained(this)),
base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback,
base::Unretained(this)),
- base::Bind(&VideoFrameStreamTest::OnStatistics,
+ base::Bind(&VideoFrameStreamTest::OnStatistics, base::Unretained(this)),
+ base::Bind(&VideoFrameStreamTest::OnWaitingForDecryptionKey,
base::Unretained(this)));
message_loop_.RunUntilIdle();
}
@@ -276,6 +278,8 @@ class VideoFrameStreamTest
break;
case DECRYPTOR_NO_KEY:
+ if (GetParam().is_encrypted)
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey());
ExpectDecryptorNotification();
has_no_key_ = true;
ReadOneFrame();
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc
index 3bde3b2..e4a1332 100644
--- a/media/mojo/services/mojo_renderer_impl.cc
+++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -33,7 +33,8 @@ MojoRendererImpl::~MojoRendererImpl() {
// Connection to |remote_media_renderer_| will error-out here.
}
-// TODO(xhwang): Support |paint_cb| if needed.
+// TODO(xhwang): Support |paint_cb| and |waiting_for_decryption_key_cb|,
+// if needed.
void MojoRendererImpl::Initialize(
DemuxerStreamProvider* demuxer_stream_provider,
const PipelineStatusCB& init_cb,
@@ -41,7 +42,8 @@ void MojoRendererImpl::Initialize(
const BufferingStateCB& buffering_state_cb,
const PaintCB& /* paint_cb */,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) {
+ const PipelineStatusCB& error_cb,
+ const base::Closure& /* waiting_for_decryption_key_cb */) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(demuxer_stream_provider);
diff --git a/media/mojo/services/mojo_renderer_impl.h b/media/mojo/services/mojo_renderer_impl.h
index d1ddc31..338bcb8 100644
--- a/media/mojo/services/mojo_renderer_impl.h
+++ b/media/mojo/services/mojo_renderer_impl.h
@@ -39,7 +39,8 @@ class MojoRendererImpl : public Renderer, public mojo::MediaRendererClient {
const BufferingStateCB& buffering_state_cb,
const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) override;
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) override;
void SetCdm(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) override;
void Flush(const base::Closure& flush_cb) override;
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index a737aa3..d4d2c9a 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -120,7 +120,8 @@ void MojoRendererService::OnStreamReady(const mojo::Closure& callback) {
base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
base::Bind(&PaintNothing),
base::Bind(&MojoRendererService::OnRendererEnded, weak_this_),
- base::Bind(&MojoRendererService::OnError, weak_this_));
+ base::Bind(&MojoRendererService::OnError, weak_this_),
+ base::Bind(base::DoNothing));
}
void MojoRendererService::OnRendererInitializeDone(
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc
index 56f3da7..74ef1d2 100644
--- a/media/renderers/audio_renderer_impl.cc
+++ b/media/renderers/audio_renderer_impl.cc
@@ -257,7 +257,8 @@ void AudioRendererImpl::Initialize(
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) {
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(stream);
@@ -317,7 +318,7 @@ void AudioRendererImpl::Initialize(
audio_buffer_stream_->Initialize(
stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
weak_factory_.GetWeakPtr()),
- set_decryptor_ready_cb, statistics_cb);
+ set_decryptor_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 af7251a..1972c87 100644
--- a/media/renderers/audio_renderer_impl.h
+++ b/media/renderers/audio_renderer_impl.h
@@ -80,7 +80,8 @@ class MEDIA_EXPORT AudioRendererImpl
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) override;
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) override;
TimeSource* GetTimeSource() override;
void Flush(const base::Closure& callback) override;
void StartPlaying() override;
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc
index b5035c6..98782c9 100644
--- a/media/renderers/audio_renderer_impl_unittest.cc
+++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -113,8 +113,10 @@ class AudioRendererImplTest : public ::testing::Test {
MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&));
MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
MOCK_METHOD1(OnError, void(PipelineStatus));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) {
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
renderer_->Initialize(
&demuxer_stream_, pipeline_status_cb, SetDecryptorReadyCB(),
base::Bind(&AudioRendererImplTest::OnStatistics,
@@ -122,7 +124,9 @@ class AudioRendererImplTest : public ::testing::Test {
base::Bind(&AudioRendererImplTest::OnBufferingStateChange,
base::Unretained(this)),
base::Bind(&AudioRendererImplTest::OnEnded, base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnError, base::Unretained(this)));
+ base::Bind(&AudioRendererImplTest::OnError, base::Unretained(this)),
+ base::Bind(&AudioRendererImplTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
}
void Initialize() {
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index 74e09d7..9367185 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -56,13 +56,15 @@ RendererImpl::~RendererImpl() {
base::ResetAndReturn(&flush_cb_).Run();
}
-void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider,
- const PipelineStatusCB& init_cb,
- const StatisticsCB& statistics_cb,
- const BufferingStateCB& buffering_state_cb,
- const PaintCB& paint_cb,
- const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) {
+void RendererImpl::Initialize(
+ DemuxerStreamProvider* demuxer_stream_provider,
+ const PipelineStatusCB& init_cb,
+ const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, STATE_UNINITIALIZED);
@@ -82,6 +84,7 @@ void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider,
ended_cb_ = ended_cb;
error_cb_ = error_cb;
init_cb_ = init_cb;
+ waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
state_ = STATE_INITIALIZING;
InitializeAudioRenderer();
@@ -258,7 +261,8 @@ void RendererImpl::InitializeAudioRenderer() {
base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_,
&audio_buffering_state_),
base::Bind(&RendererImpl::OnAudioRendererEnded, weak_this_),
- base::Bind(&RendererImpl::OnError, weak_this_));
+ base::Bind(&RendererImpl::OnError, weak_this_),
+ waiting_for_decryption_key_cb_);
}
void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
@@ -307,7 +311,8 @@ void RendererImpl::InitializeVideoRenderer() {
base::Bind(&RendererImpl::OnVideoRendererEnded, weak_this_),
base::Bind(&RendererImpl::OnError, weak_this_),
base::Bind(&RendererImpl::GetMediaTimeForSyncingVideo,
- base::Unretained(this)));
+ base::Unretained(this)),
+ waiting_for_decryption_key_cb_);
}
void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h
index 68a2f7e..befa95c1 100644
--- a/media/renderers/renderer_impl.h
+++ b/media/renderers/renderer_impl.h
@@ -49,7 +49,8 @@ class MEDIA_EXPORT RendererImpl : public Renderer {
const BufferingStateCB& buffering_state_cb,
const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb) final;
+ const PipelineStatusCB& error_cb,
+ const base::Closure& waiting_for_decryption_key_cb) final;
void SetCdm(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) final;
void Flush(const base::Closure& flush_cb) final;
@@ -133,6 +134,7 @@ class MEDIA_EXPORT RendererImpl : public Renderer {
PipelineStatusCB error_cb_;
BufferingStateCB buffering_state_cb_;
PaintCB paint_cb_;
+ base::Closure waiting_for_decryption_key_cb_;
// Temporary callback used for Initialize() and Flush().
PipelineStatusCB init_cb_;
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc
index 8f738b0..30bad2fe 100644
--- a/media/renderers/renderer_impl_unittest.cc
+++ b/media/renderers/renderer_impl_unittest.cc
@@ -50,6 +50,7 @@ class RendererImplTest : public ::testing::Test {
MOCK_METHOD1(OnUpdateStatistics, void(const PipelineStatistics&));
MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
MOCK_METHOD1(OnVideoFramePaint, void(const scoped_refptr<VideoFrame>&));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void());
private:
DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
@@ -88,7 +89,7 @@ class RendererImplTest : public ::testing::Test {
// Sets up expectations to allow the audio renderer to initialize.
void SetAudioRendererInitializeExpectations(PipelineStatus status) {
EXPECT_CALL(*audio_renderer_,
- Initialize(audio_stream_.get(), _, _, _, _, _, _))
+ Initialize(audio_stream_.get(), _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_),
SaveArg<5>(&audio_ended_cb_),
SaveArg<6>(&audio_error_cb_), RunCallback<1>(status)));
@@ -97,13 +98,14 @@ class RendererImplTest : public ::testing::Test {
// Sets up expectations to allow the video renderer to initialize.
void SetVideoRendererInitializeExpectations(PipelineStatus status) {
EXPECT_CALL(*video_renderer_,
- Initialize(video_stream_.get(), _, _, _, _, _, _, _, _))
+ Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&video_buffering_state_cb_),
SaveArg<6>(&video_ended_cb_), RunCallback<1>(status)));
}
void InitializeAndExpect(PipelineStatus start_status) {
EXPECT_CALL(callbacks_, OnInitialize(start_status));
+ EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0);
if (start_status == PIPELINE_OK && audio_stream_) {
EXPECT_CALL(*audio_renderer_, GetTimeSource())
@@ -121,7 +123,9 @@ class RendererImplTest : public ::testing::Test {
base::Bind(&CallbackHelper::OnVideoFramePaint,
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)));
+ base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnWaitingForDecryptionKey,
+ base::Unretained(&callbacks_)));
base::RunLoop().RunUntilIdle();
}
@@ -433,7 +437,7 @@ TEST_F(RendererImplTest, ErrorDuringInitialize) {
// Force an audio error to occur during video renderer initialization.
EXPECT_CALL(*video_renderer_,
- Initialize(video_stream_.get(), _, _, _, _, _, _, _, _))
+ Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE),
SaveArg<4>(&video_buffering_state_cb_),
SaveArg<6>(&video_ended_cb_),
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc
index 5e2819d..0ad19e4 100644
--- a/media/renderers/video_renderer_impl.cc
+++ b/media/renderers/video_renderer_impl.cc
@@ -109,7 +109,8 @@ void VideoRendererImpl::Initialize(
const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
- const TimeDeltaCB& get_time_cb) {
+ const TimeDeltaCB& get_time_cb,
+ const base::Closure& waiting_for_decryption_key_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
base::AutoLock auto_lock(lock_);
DCHECK(stream);
@@ -139,7 +140,7 @@ void VideoRendererImpl::Initialize(
video_frame_stream_->Initialize(
stream, base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized,
weak_factory_.GetWeakPtr()),
- set_decryptor_ready_cb, statistics_cb);
+ set_decryptor_ready_cb, statistics_cb, waiting_for_decryption_key_cb);
}
void VideoRendererImpl::CreateVideoThread() {
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h
index 69cf140..eec8b15 100644
--- a/media/renderers/video_renderer_impl.h
+++ b/media/renderers/video_renderer_impl.h
@@ -60,7 +60,8 @@ class MEDIA_EXPORT VideoRendererImpl
const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
- const TimeDeltaCB& get_time_cb) override;
+ const TimeDeltaCB& get_time_cb,
+ const base::Closure& waiting_for_decryption_key_cb) override;
void Flush(const base::Closure& callback) override;
void StartPlayingFrom(base::TimeDelta timestamp) override;
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc
index c771ad4..d9cad51 100644
--- a/media/renderers/video_renderer_impl_unittest.cc
+++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -94,6 +94,7 @@ class VideoRendererImplTest : public ::testing::Test {
demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE);
EXPECT_CALL(*decoder_, Initialize(_, _, _, _)).WillOnce(
DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(decoder_status)));
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
renderer_->Initialize(
&demuxer_stream_, status_cb, media::SetDecryptorReadyCB(),
base::Bind(&VideoRendererImplTest::OnStatisticsUpdate,
@@ -102,7 +103,9 @@ class VideoRendererImplTest : public ::testing::Test {
base::Unretained(&mock_cb_)),
base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)),
ended_event_.GetClosure(), error_event_.GetPipelineStatusCB(),
- base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)));
+ base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)),
+ base::Bind(&VideoRendererImplTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
}
void StartPlayingFrom(int milliseconds) {
@@ -289,6 +292,8 @@ class VideoRendererImplTest : public ::testing::Test {
void OnStatisticsUpdate(const PipelineStatistics& stats) {}
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
+
base::MessageLoop message_loop_;
// Used to protect |time_|.
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index c2e23f8..55bba58 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -659,6 +659,10 @@ class PipelineIntegrationTest : public PipelineIntegrationTestHost {
.WillRepeatedly(SaveArg<0>(&metadata_));
EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH))
.Times(AtMost(1));
+
+ // Encrypted content not used, so this is never called.
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
+
demuxer_ = source->GetDemuxer().Pass();
pipeline_->Start(
demuxer_.get(), CreateRenderer(),
@@ -673,7 +677,9 @@ class PipelineIntegrationTest : public PipelineIntegrationTestHost {
base::Bind(&PipelineIntegrationTest::OnVideoFramePaint,
base::Unretained(this)),
base::Closure(), base::Bind(&PipelineIntegrationTest::OnAddTextTrack,
- base::Unretained(this)));
+ base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(PIPELINE_OK, pipeline_status_);
}
@@ -694,6 +700,10 @@ class PipelineIntegrationTest : public PipelineIntegrationTestHost {
.Times(AtMost(1));
EXPECT_CALL(*this, DecryptorAttached(true));
+ // Encrypted content used but keys provided in advance, so this is
+ // never called.
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
+
demuxer_ = source->GetDemuxer().Pass();
pipeline_->SetCdm(encrypted_media->GetCdmContext(),
@@ -713,7 +723,9 @@ class PipelineIntegrationTest : public PipelineIntegrationTestHost {
base::Bind(&PipelineIntegrationTest::OnVideoFramePaint,
base::Unretained(this)),
base::Closure(), base::Bind(&PipelineIntegrationTest::OnAddTextTrack,
- base::Unretained(this)));
+ base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTest::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
source->set_encrypted_media_init_data_cb(
base::Bind(&FakeEncryptedMedia::OnEncryptedMediaInitData,
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index d40b0dc..e122d9a 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -121,6 +121,10 @@ PipelineStatus PipelineIntegrationTestBase::Start(const std::string& filename,
base::Unretained(this)));
}
+ // Should never be called as the required decryption keys for the encrypted
+ // media files are provided in advance.
+ EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
+
pipeline_->Start(
demuxer_.get(), CreateRenderer(),
base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
@@ -134,7 +138,9 @@ PipelineStatus PipelineIntegrationTestBase::Start(const std::string& filename,
base::Bind(&PipelineIntegrationTestBase::OnVideoFramePaint,
base::Unretained(this)),
base::Closure(), base::Bind(&PipelineIntegrationTestBase::OnAddTextTrack,
- base::Unretained(this)));
+ base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTestBase::OnWaitingForDecryptionKey,
+ base::Unretained(this)));
message_loop_.Run();
return pipeline_status_;
}
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index de6c0e0..716e27c 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -140,6 +140,7 @@ class PipelineIntegrationTestBase {
MOCK_METHOD2(OnAddTextTrack,
void(const TextTrackConfig& config,
const AddTextTrackDoneCB& done_cb));
+ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
};
} // namespace media
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index afd5d0b..60eb45c 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -149,7 +149,8 @@ void InitPipeline(
base::Bind(&OnBufferingStateChanged),
paint_cb,
base::Bind(&DoNothing),
- base::Bind(&OnAddTextTrack));
+ base::Bind(&OnAddTextTrack),
+ base::Bind(&DoNothing));
// Wait until the pipeline is fully initialized.
event.Wait();