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

Unified Diff: media/base/android/media_decoder_job.cc

Issue 23545029: EME: Handle NO_KEY and resume playback after key is added. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase only Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/android/media_decoder_job.h ('k') | media/base/android/media_drm_bridge.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/android/media_decoder_job.cc
diff --git a/media/base/android/media_decoder_job.cc b/media/base/android/media_decoder_job.cc
index 3230e2360900bcf23a361cf2fe61fcf4fac684a3..33b48302b0ec8f7dc447318efe424f9bf5a7a157 100644
--- a/media/base/android/media_decoder_job.cc
+++ b/media/base/android/media_decoder_job.cc
@@ -29,6 +29,7 @@ MediaDecoderJob::MediaDecoderJob(
weak_this_(this),
request_data_cb_(request_data_cb),
access_unit_index_(0),
+ input_buf_index_(-1),
stop_decode_pending_(false),
destroy_pending_(false) {
}
@@ -36,6 +37,7 @@ MediaDecoderJob::MediaDecoderJob(
MediaDecoderJob::~MediaDecoderJob() {}
void MediaDecoderJob::OnDataReceived(const DemuxerData& data) {
+ DVLOG(1) << __FUNCTION__ << ": " << data.access_units.size() << " units";
DCHECK(ui_loop_->BelongsToCurrentThread());
DCHECK(!on_data_received_cb_.is_null());
@@ -132,44 +134,59 @@ void MediaDecoderJob::Release() {
delete this;
}
-MediaCodecStatus MediaDecoderJob::QueueInputBuffer(
- const AccessUnit& unit) {
- base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
- kMediaCodecTimeoutInMilliseconds);
- int input_buf_index = 0;
- MediaCodecStatus status =
- media_codec_bridge_->DequeueInputBuffer(timeout, &input_buf_index);
- if (status != MEDIA_CODEC_OK)
- return status;
+MediaCodecStatus MediaDecoderJob::QueueInputBuffer(const AccessUnit& unit) {
+ DVLOG(1) << __FUNCTION__;
+ DCHECK(decoder_loop_->BelongsToCurrentThread());
+
+ int input_buf_index = input_buf_index_;
+ input_buf_index_ = -1;
+
+ // TODO(xhwang): Hide DequeueInputBuffer() and the index in MediaCodecBridge.
+ if (input_buf_index == -1) {
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
+ kMediaCodecTimeoutInMilliseconds);
+ MediaCodecStatus status =
+ media_codec_bridge_->DequeueInputBuffer(timeout, &input_buf_index);
+ if (status != MEDIA_CODEC_OK) {
+ DVLOG(1) << "DequeueInputBuffer fails: " << status;
+ return status;
+ }
+ }
// TODO(qinmin): skip frames if video is falling far behind.
DCHECK_GE(input_buf_index, 0);
if (unit.end_of_stream || unit.data.empty()) {
- media_codec_bridge_->QueueEOS(input_buf_index);
+ media_codec_bridge_->QueueEOS(input_buf_index_);
return MEDIA_CODEC_INPUT_END_OF_STREAM;
}
if (unit.key_id.empty()) {
- media_codec_bridge_->QueueInputBuffer(
+ return media_codec_bridge_->QueueInputBuffer(
input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp);
- return MEDIA_CODEC_OK;
}
if (unit.iv.empty() || unit.subsamples.empty()) {
- LOG(ERROR) << "The access unit doesn't have iv or subsamples while it "
+ DVLOG(1) << "The access unit doesn't have iv or subsamples while it "
<< "has key IDs!";
return MEDIA_CODEC_ERROR;
}
- media_codec_bridge_->QueueSecureInputBuffer(
+ MediaCodecStatus status = media_codec_bridge_->QueueSecureInputBuffer(
input_buf_index, &unit.data[0], unit.data.size(),
reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(),
reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(),
&unit.subsamples[0], unit.subsamples.size(), unit.timestamp);
- return MEDIA_CODEC_OK;
+
+ // In case of MEDIA_CODEC_NO_KEY, we must reuse the |input_buf_index_|.
+ // Otherwise MediaDrm will report errors.
+ if (status == MEDIA_CODEC_NO_KEY)
+ input_buf_index_ = input_buf_index;
+
+ return status;
}
void MediaDecoderJob::RequestData(const base::Closure& done_cb) {
+ DVLOG(1) << __FUNCTION__;
DCHECK(ui_loop_->BelongsToCurrentThread());
DCHECK(on_data_received_cb_.is_null());
@@ -201,6 +218,9 @@ void MediaDecoderJob::DecodeInternal(
const base::TimeDelta& start_presentation_timestamp,
bool needs_flush,
const MediaDecoderJob::DecoderCallback& callback) {
+ DVLOG(1) << __FUNCTION__;
+ DCHECK(decoder_loop_->BelongsToCurrentThread());
+
if (needs_flush) {
DVLOG(1) << "DecodeInternal needs flush.";
input_eos_encountered_ = false;
@@ -259,7 +279,7 @@ void MediaDecoderJob::DecodeInternal(
// TODO(acolwell): Change to > since the else will never run for audio.
if (time_to_render >= base::TimeDelta()) {
- base::MessageLoop::current()->PostDelayedTask(
+ decoder_loop_->PostDelayedTask(
FROM_HERE,
base::Bind(&MediaDecoderJob::ReleaseOutputBuffer,
weak_this_.GetWeakPtr(), buffer_index, size,
@@ -289,8 +309,9 @@ void MediaDecoderJob::OnDecodeCompleted(
DCHECK(!decode_cb_.is_null());
if (status != MEDIA_CODEC_ERROR &&
- status != MEDIA_CODEC_ENQUEUE_INPUT_AGAIN_LATER &&
+ status != MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER &&
status != MEDIA_CODEC_INPUT_END_OF_STREAM &&
+ status != MEDIA_CODEC_NO_KEY &&
status != MEDIA_CODEC_STOPPED) {
access_unit_index_++;
}
« no previous file with comments | « media/base/android/media_decoder_job.h ('k') | media/base/android/media_drm_bridge.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698