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

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

Issue 1344133002: MediaCodecPlayer implementation - stage 7 (DRM) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-drm-prepare
Patch Set: Repost SetMediaCryptoReadyCB on UI thread, further cleanup Created 5 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
Index: media/base/android/media_codec_decoder.cc
diff --git a/media/base/android/media_codec_decoder.cc b/media/base/android/media_codec_decoder.cc
index fd8d84ecc60787c1eced4114010f086dd985e1e3..d3893e518a1634adab8ff3cec6f40650b5a1a9c0 100644
--- a/media/base/android/media_codec_decoder.cc
+++ b/media/base/android/media_codec_decoder.cc
@@ -37,6 +37,7 @@ MediaCodecDecoder::MediaCodecDecoder(
const base::Closure& starvation_cb,
const base::Closure& decoder_drained_cb,
const base::Closure& stop_done_cb,
+ const base::Closure& key_required_cb,
const base::Closure& error_cb,
const char* decoder_thread_name)
: media_task_runner_(media_task_runner),
@@ -48,10 +49,12 @@ MediaCodecDecoder::MediaCodecDecoder(
starvation_cb_(starvation_cb),
decoder_drained_cb_(decoder_drained_cb),
stop_done_cb_(stop_done_cb),
+ key_required_cb_(key_required_cb),
error_cb_(error_cb),
state_(kStopped),
is_prepared_(false),
eos_enqueued_(false),
+ key_request_posted_(false),
completed_(false),
last_frame_posted_(false),
is_data_request_in_progress_(false),
@@ -179,14 +182,12 @@ void MediaCodecDecoder::SetPrerollTimestamp(base::TimeDelta preroll_timestamp) {
preroll_timestamp_ = preroll_timestamp;
}
-base::android::ScopedJavaLocalRef<jobject> MediaCodecDecoder::GetMediaCrypto() {
- base::android::ScopedJavaLocalRef<jobject> media_crypto;
+void MediaCodecDecoder::SetNeedsReconfigure() {
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ DVLOG(1) << class_name() << "::" << __FUNCTION__;
- // TODO(timav): implement DRM.
- // drm_bridge_ is not implemented
- // if (drm_bridge_)
- // media_crypto = drm_bridge_->GetMediaCrypto();
- return media_crypto;
+ needs_reconfigure_ = true;
}
void MediaCodecDecoder::Prefetch(const base::Closure& prefetch_done_cb) {
@@ -202,7 +203,8 @@ void MediaCodecDecoder::Prefetch(const base::Closure& prefetch_done_cb) {
PrefetchNextChunk();
}
-MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() {
+MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure(
+ jobject media_crypto) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
DVLOG(1) << class_name() << "::" << __FUNCTION__;
@@ -233,7 +235,7 @@ MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() {
au_info = au_queue_.GetInfo();
}
- MediaCodecDecoder::ConfigStatus result = ConfigureInternal();
+ MediaCodecDecoder::ConfigStatus result = ConfigureInternal(media_crypto);
#ifndef NDEBUG
// We check and reset |verify_next_frame_is_key_| on Decoder thread.
@@ -401,6 +403,8 @@ void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) {
SetState(kStopped);
completed_ = (eos_encountered && !drain_decoder_);
+ key_request_posted_ = false;
+
// If the stream is completed during preroll we need to report it since
// another stream might be running and the player waits for two callbacks.
if (completed_ && !preroll_done_cb_.is_null()) {
@@ -498,6 +502,8 @@ void MediaCodecDecoder::DoEmergencyStop() {
decoder_thread_.Stop(); // synchronous
SetState(kStopped);
+
+ key_request_posted_ = false;
}
void MediaCodecDecoder::CheckLastFrame(bool eos_encountered,
@@ -618,6 +624,12 @@ bool MediaCodecDecoder::EnqueueInputBuffer() {
return true; // Nothing to do
}
+ if (key_request_posted_) {
+ DVLOG(1) << class_name() << "::" << __FUNCTION__
+ << ": key_request_posted, returning";
+ return true; // Nothing to do
+ }
+
// Keep the number pending video frames low, ideally maintaining
// the same audio and video duration after stop request
if (NumDelayedRenderTasks() > 1) {
@@ -695,17 +707,54 @@ bool MediaCodecDecoder::EnqueueInputBuffer() {
DCHECK(unit);
- DVLOG(2) << class_name() << "::" << __FUNCTION__
- << ": QueueInputBuffer pts:" << unit->timestamp;
+ if (unit->key_id.empty() || unit->iv.empty()) {
+ DVLOG(2) << class_name() << "::" << __FUNCTION__
+ << ": QueueInputBuffer pts:" << unit->timestamp;
- status = media_codec_bridge_->QueueInputBuffer(
- index, &unit->data[0], unit->data.size(), unit->timestamp);
+ status = media_codec_bridge_->QueueInputBuffer(
+ index, &unit->data[0], unit->data.size(), unit->timestamp);
+ } else {
+ DVLOG(2) << class_name() << "::" << __FUNCTION__
+ << ": QueueSecureInputBuffer pts:" << unit->timestamp
+ << " key_id size:" << unit->key_id.size()
+ << " iv size:" << unit->iv.size()
+ << " subsamples size:" << unit->subsamples.size();
- if (status == MEDIA_CODEC_ERROR) {
- DVLOG(0) << class_name() << "::" << __FUNCTION__
- << ": MEDIA_CODEC_ERROR: QueueInputBuffer failed";
- media_task_runner_->PostTask(FROM_HERE, internal_error_cb_);
- return false;
+ status = media_codec_bridge_->QueueSecureInputBuffer(
+ index, &unit->data[0], unit->data.size(),
+ reinterpret_cast<const uint8_t*>(&unit->key_id[0]), unit->key_id.size(),
+ reinterpret_cast<const uint8_t*>(&unit->iv[0]), unit->iv.size(),
+ unit->subsamples.empty() ? nullptr : &unit->subsamples[0],
+ unit->subsamples.size(), unit->timestamp);
+ }
+
+ switch (status) {
+ case MEDIA_CODEC_OK:
+ break;
+
+ case MEDIA_CODEC_ERROR:
+ DVLOG(0) << class_name() << "::" << __FUNCTION__
+ << ": MEDIA_CODEC_ERROR: QueueInputBuffer failed";
+ media_task_runner_->PostTask(FROM_HERE, internal_error_cb_);
+ return false;
+
+ case MEDIA_CODEC_NO_KEY:
+ DVLOG(1) << class_name() << "::" << __FUNCTION__
+ << ": MEDIA_CODEC_NO_KEY";
+ media_task_runner_->PostTask(FROM_HERE, key_required_cb_);
+
+ // In response to the |key_required_cb_| the player will request to stop
+ // decoder. We need to keep running to properly perform the stop, but
+ // prevent enqueuing the same frame over and over again so we won't
+ // generate more |key_required_cb_|.
+ key_request_posted_ = true;
+ return true;
+
+ default:
+ NOTREACHED() << class_name() << "::" << __FUNCTION__
+ << ": unexpected error code " << status;
+ media_task_runner_->PostTask(FROM_HERE, internal_error_cb_);
+ return false;
}
// Have successfully queued input buffer, go to next access unit.

Powered by Google App Engine
This is Rietveld 408576698