| Index: media/base/android/media_source_player.cc
|
| diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc
|
| index 8306ad969b1a5eed27c7ba584c2db7322ad98260..2be0d8b23471441f19d157987d0b09aa6f072c1f 100644
|
| --- a/media/base/android/media_source_player.cc
|
| +++ b/media/base/android/media_source_player.cc
|
| @@ -20,7 +20,6 @@
|
| #include "media/base/android/media_player_manager.h"
|
| #include "media/base/android/video_decoder_job.h"
|
|
|
| -
|
| namespace media {
|
|
|
| MediaSourcePlayer::MediaSourcePlayer(
|
| @@ -42,6 +41,7 @@ MediaSourcePlayer::MediaSourcePlayer(
|
| drm_bridge_(NULL),
|
| cdm_registration_id_(0),
|
| is_waiting_for_key_(false),
|
| + key_added_while_decode_pending_(false),
|
| is_waiting_for_audio_decoder_(false),
|
| is_waiting_for_video_decoder_(false),
|
| prerolling_(true),
|
| @@ -223,10 +223,11 @@ void MediaSourcePlayer::StartInternal() {
|
| if (pending_event_ != NO_EVENT_PENDING)
|
| return;
|
|
|
| - // When we start, we'll have new demuxed data coming in. This new data could
|
| - // be clear (not encrypted) or encrypted with different keys. So
|
| - // |is_waiting_for_key_| condition may not be true anymore.
|
| + // When we start, we could have new demuxed data coming in. This new data
|
| + // could be clear (not encrypted) or encrypted with different keys. So key
|
| + // related info should all be cleared.
|
| is_waiting_for_key_ = false;
|
| + key_added_while_decode_pending_ = false;
|
| AttachListener(NULL);
|
|
|
| SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
|
| @@ -502,10 +503,25 @@ void MediaSourcePlayer::MediaDecoderCallback(
|
| }
|
|
|
| if (status == MEDIA_CODEC_NO_KEY) {
|
| - is_waiting_for_key_ = true;
|
| + if (key_added_while_decode_pending_) {
|
| + DVLOG(2) << __FUNCTION__ << ": Key was added during decoding.";
|
| + ResumePlaybackAfterKeyAdded();
|
| + } else {
|
| + is_waiting_for_key_ = true;
|
| + }
|
| return;
|
| }
|
|
|
| + // If |key_added_while_decode_pending_| is true and both audio and video
|
| + // decoding succeeded, we should clear |key_added_while_decode_pending_| here.
|
| + // But that would add more complexity into this function. If we don't clear it
|
| + // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when
|
| + // we don't really have a new key. This should rarely happen and the
|
| + // performance impact should be pretty small.
|
| + // TODO(qinmin/xhwang): This class is complicated because we handle both audio
|
| + // and video in one file. If we separate them, we should be able to remove a
|
| + // lot of duplication.
|
| +
|
| // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
|
| // in the middle of a seek or stop event and needs to wait for the IPCs to
|
| // come.
|
| @@ -755,10 +771,30 @@ void MediaSourcePlayer::RetryDecoderCreation(bool audio, bool video) {
|
|
|
| void MediaSourcePlayer::OnKeyAdded() {
|
| DVLOG(1) << __FUNCTION__;
|
| - if (!is_waiting_for_key_)
|
| +
|
| + if (is_waiting_for_key_) {
|
| + ResumePlaybackAfterKeyAdded();
|
| return;
|
| + }
|
| +
|
| + if ((audio_decoder_job_->is_content_encrypted() &&
|
| + audio_decoder_job_->is_decoding()) ||
|
| + (video_decoder_job_->is_content_encrypted() &&
|
| + video_decoder_job_->is_decoding())) {
|
| + DVLOG(1) << __FUNCTION__ << ": " << "Key added during pending decode.";
|
| + key_added_while_decode_pending_ = true;
|
| + }
|
| +}
|
| +
|
| +void MediaSourcePlayer::ResumePlaybackAfterKeyAdded() {
|
| + DVLOG(1) << __FUNCTION__;
|
| + DCHECK(is_waiting_for_key_ || key_added_while_decode_pending_);
|
|
|
| is_waiting_for_key_ = false;
|
| + key_added_while_decode_pending_ = false;
|
| +
|
| + // StartInternal() will trigger a prefetch, where in most cases we'll just
|
| + // use previously received data.
|
| if (playing_)
|
| StartInternal();
|
| }
|
|
|