Modular DRM for MediaPlayer
Bug: 34559906
Test: Manual through the test app
Change-Id: I286f9ff199c34563b7b8643de725f8d1534ea06c
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 0a0a8aa..5689e95 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -23,6 +23,7 @@
#include "NuPlayerCCDecoder.h"
#include "NuPlayerDecoder.h"
+#include "NuPlayerDrm.h"
#include "NuPlayerRenderer.h"
#include "NuPlayerSource.h"
@@ -255,6 +256,13 @@
break;
}
+ case kWhatDrmReleaseCrypto:
+ {
+ ALOGV("kWhatDrmReleaseCrypto");
+ onReleaseCrypto(msg);
+ break;
+ }
+
default:
DecoderBase::onMessageReceived(msg);
break;
@@ -312,8 +320,19 @@
// any error signaling will occur.
ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
}
+
+ // Modular DRM
+ void *pCrypto;
+ if (!format->findPointer("crypto", &pCrypto)) {
+ pCrypto = NULL;
+ }
+ sp<ICrypto> crypto = (ICrypto*)pCrypto;
+ ALOGV("onConfigure mCrypto: %p (%d) mIsSecure: %d",
+ crypto.get(), (crypto != NULL ? crypto->getStrongCount() : 0), mIsSecure);
+
err = mCodec->configure(
- format, mSurface, NULL /* crypto */, 0 /* flags */);
+ format, mSurface, crypto, 0 /* flags */);
+
if (err != OK) {
ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
mCodec->release();
@@ -559,6 +578,43 @@
notify->post();
}
+status_t NuPlayer::Decoder::releaseCrypto()
+{
+ ALOGV("releaseCrypto");
+
+ sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
+
+ sp<AMessage> response;
+ status_t status = msg->postAndAwaitResponse(&response);
+ if (status == OK && response != NULL) {
+ CHECK(response->findInt32("status", &status));
+ ALOGV("releaseCrypto ret: %d ", status);
+ } else {
+ ALOGE("releaseCrypto err: %d", status);
+ }
+
+ return status;
+}
+
+void NuPlayer::Decoder::onReleaseCrypto(const sp<AMessage>& msg)
+{
+ status_t status = INVALID_OPERATION;
+ if (mCodec != NULL) {
+ status = mCodec->releaseCrypto();
+ } else {
+ // returning OK if the codec has been already released
+ status = OK;
+ ALOGE("onReleaseCrypto No mCodec. err: %d", status);
+ }
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("status", status);
+
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ response->postReply(replyID);
+}
+
bool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
if (isDiscontinuityPending()) {
return false;
@@ -929,6 +985,10 @@
flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
}
+ // Modular DRM
+ MediaBuffer *mediaBuf = NULL;
+ NuPlayerDrm::CryptoInfo *cryptInfo = NULL;
+
// copy into codec buffer
if (needsCopy) {
if (buffer->size() > codecBuffer->capacity()) {
@@ -936,24 +996,68 @@
mDequeuedInputBuffers.push_back(bufferIx);
return false;
}
- codecBuffer->setRange(0, buffer->size());
- memcpy(codecBuffer->data(), buffer->data(), buffer->size());
- }
- status_t err = mCodec->queueInputBuffer(
- bufferIx,
- codecBuffer->offset(),
- codecBuffer->size(),
- timeUs,
- flags);
+ if (buffer->data() != NULL) {
+ codecBuffer->setRange(0, buffer->size());
+ memcpy(codecBuffer->data(), buffer->data(), buffer->size());
+ } else { // No buffer->data()
+ //Modular DRM
+ mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase();
+ if (mediaBuf != NULL) {
+ codecBuffer->setRange(0, mediaBuf->size());
+ memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
+
+ sp<MetaData> meta_data = mediaBuf->meta_data();
+ cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data);
+
+ // since getMediaBuffer() has incremented the refCount
+ mediaBuf->release();
+ } else { // No mediaBuf
+ ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
+ buffer.get());
+ handleError(UNKNOWN_ERROR);
+ return false;
+ }
+ } // buffer->data()
+ } // needsCopy
+
+ status_t err;
+ AString errorDetailMsg;
+ if (cryptInfo != NULL) {
+ err = mCodec->queueSecureInputBuffer(
+ bufferIx,
+ codecBuffer->offset(),
+ cryptInfo->subSamples,
+ cryptInfo->numSubSamples,
+ cryptInfo->key,
+ cryptInfo->iv,
+ cryptInfo->mode,
+ cryptInfo->pattern,
+ timeUs,
+ flags,
+ &errorDetailMsg);
+ // synchronous call so done with cryptInfo here
+ free(cryptInfo);
+ } else {
+ err = mCodec->queueInputBuffer(
+ bufferIx,
+ codecBuffer->offset(),
+ codecBuffer->size(),
+ timeUs,
+ flags,
+ &errorDetailMsg);
+ } // no cryptInfo
+
if (err != OK) {
- ALOGE("Failed to queue input buffer for %s (err=%d)",
- mComponentName.c_str(), err);
+ ALOGE("onInputBufferFetched: queue%sInputBuffer failed for %s (err=%d, %s)",
+ (cryptInfo != NULL ? "Secure" : ""),
+ mComponentName.c_str(), err, errorDetailMsg.c_str());
handleError(err);
} else {
mInputBufferIsDequeued.editItemAt(bufferIx) = false;
}
- }
+
+ } // buffer != NULL
return true;
}