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

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: Renamed a variable 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
« no previous file with comments | « media/base/android/media_codec_decoder.h ('k') | media/base/android/media_codec_decoder_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..808aa761a55b551c7260eee8118833e2c03515fb 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& waiting_for_decryption_key_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),
+ waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb),
error_cb_(error_cb),
state_(kStopped),
is_prepared_(false),
eos_enqueued_(false),
+ missing_key_reported_(false),
completed_(false),
last_frame_posted_(false),
is_data_request_in_progress_(false),
@@ -91,6 +94,7 @@ void MediaCodecDecoder::Flush() {
is_incoming_data_invalid_ = true;
eos_enqueued_ = false;
+ missing_key_reported_ = false;
completed_ = false;
drain_decoder_ = false;
au_queue_.Flush();
@@ -179,14 +183,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 +204,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 +236,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 +404,8 @@ void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) {
SetState(kStopped);
completed_ = (eos_encountered && !drain_decoder_);
+ missing_key_reported_ = 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 +503,8 @@ void MediaCodecDecoder::DoEmergencyStop() {
decoder_thread_.Stop(); // synchronous
SetState(kStopped);
+
+ missing_key_reported_ = false;
}
void MediaCodecDecoder::CheckLastFrame(bool eos_encountered,
@@ -614,7 +621,13 @@ bool MediaCodecDecoder::EnqueueInputBuffer() {
if (eos_enqueued_) {
DVLOG(1) << class_name() << "::" << __FUNCTION__
- << ": eos_enqueued, returning";
+ << ": EOS enqueued, returning";
+ return true; // Nothing to do
+ }
+
+ if (missing_key_reported_) {
+ DVLOG(1) << class_name() << "::" << __FUNCTION__
+ << ": NO KEY reported, returning";
return true; // Nothing to do
}
@@ -694,18 +707,56 @@ bool MediaCodecDecoder::EnqueueInputBuffer() {
}
DCHECK(unit);
+ DCHECK(!unit->data.empty());
- 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, waiting_for_decryption_key_cb_);
+
+ // In response to the |waiting_for_decryption_key_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 |waiting_for_decryption_key_cb_|.
+ missing_key_reported_ = 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.
« no previous file with comments | « media/base/android/media_codec_decoder.h ('k') | media/base/android/media_codec_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698