summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/codec.cpp29
-rw-r--r--include/media/stagefright/MediaCodec.h13
-rw-r--r--media/libmedia/ICrypto.cpp11
-rw-r--r--media/libstagefright/MediaCodec.cpp89
4 files changed, 113 insertions, 29 deletions
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index 5cbfbfe..ece3c09 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -296,15 +296,28 @@ static int decode(
if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) {
CHECK(decryptInputBuffers);
- bufferFlags |= MediaCodec::BUFFER_FLAG_ENCRYPTED;
- }
+ CryptoPlugin::SubSample ss;
+ ss.mNumBytesOfClearData = 0;
+ ss.mNumBytesOfEncryptedData = buffer->size();
- err = state->mCodec->queueInputBuffer(
- index,
- 0 /* offset */,
- buffer->size(),
- timeUs,
- bufferFlags);
+ err = state->mCodec->queueSecureInputBuffer(
+ index,
+ 0 /* offset */,
+ &ss,
+ 1 /* numSubSamples */,
+ NULL /* key */,
+ NULL /* iv */,
+ CryptoPlugin::kMode_AES_WV,
+ timeUs,
+ bufferFlags);
+ } else {
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ buffer->size(),
+ timeUs,
+ bufferFlags);
+ }
CHECK_EQ(err, (status_t)OK);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 0b0d511..107699e 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -19,6 +19,7 @@
#define MEDIA_CODEC_H_
#include <gui/ISurfaceTexture.h>
+#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/AHandler.h>
#include <utils/Vector.h>
@@ -40,7 +41,6 @@ struct MediaCodec : public AHandler {
BUFFER_FLAG_SYNCFRAME = 1,
BUFFER_FLAG_CODECCONFIG = 2,
BUFFER_FLAG_EOS = 4,
- BUFFER_FLAG_ENCRYPTED = 8,
};
static sp<MediaCodec> CreateByType(
@@ -74,6 +74,17 @@ struct MediaCodec : public AHandler {
int64_t presentationTimeUs,
uint32_t flags);
+ status_t queueSecureInputBuffer(
+ size_t index,
+ size_t offset,
+ const CryptoPlugin::SubSample *subSamples,
+ size_t numSubSamples,
+ const uint8_t key[16],
+ const uint8_t iv[16],
+ CryptoPlugin::Mode mode,
+ int64_t presentationTimeUs,
+ uint32_t flags);
+
status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
status_t dequeueOutputBuffer(
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 1fe6bed..e6bea1f 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -97,6 +97,17 @@ struct BpCrypto : public BpInterface<ICrypto> {
data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
data.writeInt32(secure);
data.writeInt32(mode);
+
+ static const uint8_t kDummy[16] = { 0 };
+
+ if (key == NULL) {
+ key = kDummy;
+ }
+
+ if (iv == NULL) {
+ iv = kDummy;
+ }
+
data.write(key, 16);
data.write(iv, 16);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ced8368..a382f1c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -191,6 +191,31 @@ status_t MediaCodec::queueInputBuffer(
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::queueSecureInputBuffer(
+ size_t index,
+ size_t offset,
+ const CryptoPlugin::SubSample *subSamples,
+ size_t numSubSamples,
+ const uint8_t key[16],
+ const uint8_t iv[16],
+ CryptoPlugin::Mode mode,
+ int64_t presentationTimeUs,
+ uint32_t flags) {
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ msg->setSize("index", index);
+ msg->setSize("offset", offset);
+ msg->setPointer("subSamples", (void *)subSamples);
+ msg->setSize("numSubSamples", numSubSamples);
+ msg->setPointer("key", (void *)key);
+ msg->setPointer("iv", (void *)iv);
+ msg->setInt32("mode", mode);
+ msg->setInt64("timeUs", presentationTimeUs);
+ msg->setInt32("flags", flags);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
msg->setInt64("timeoutUs", timeoutUs);
@@ -1149,10 +1174,51 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
uint32_t flags;
CHECK(msg->findSize("index", &index));
CHECK(msg->findSize("offset", &offset));
- CHECK(msg->findSize("size", &size));
CHECK(msg->findInt64("timeUs", &timeUs));
CHECK(msg->findInt32("flags", (int32_t *)&flags));
+ const CryptoPlugin::SubSample *subSamples;
+ size_t numSubSamples;
+ const uint8_t *key;
+ const uint8_t *iv;
+ CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
+
+ // We allow the simpler queueInputBuffer API to be used even in
+ // secure mode, by fabricating a single unencrypted subSample.
+ CryptoPlugin::SubSample ss;
+
+ if (msg->findSize("size", &size)) {
+ if (mCrypto != NULL) {
+ ss.mNumBytesOfClearData = size;
+ ss.mNumBytesOfEncryptedData = 0;
+
+ subSamples = &ss;
+ numSubSamples = 1;
+ key = NULL;
+ iv = NULL;
+ }
+ } else {
+ if (mCrypto == NULL) {
+ return -EINVAL;
+ }
+
+ CHECK(msg->findPointer("subSamples", (void **)&subSamples));
+ CHECK(msg->findSize("numSubSamples", &numSubSamples));
+ CHECK(msg->findPointer("key", (void **)&key));
+ CHECK(msg->findPointer("iv", (void **)&iv));
+
+ int32_t tmp;
+ CHECK(msg->findInt32("mode", &tmp));
+
+ mode = (CryptoPlugin::Mode)tmp;
+
+ size = 0;
+ for (size_t i = 0; i < numSubSamples; ++i) {
+ size += subSamples[i].mNumBytesOfClearData;
+ size += subSamples[i].mNumBytesOfEncryptedData;
+ }
+ }
+
if (index >= mPortBuffers[kPortIndexInput].size()) {
return -ERANGE;
}
@@ -1187,29 +1253,14 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
return -ERANGE;
}
- uint8_t key[16];
- uint8_t iv[16];
-
- CryptoPlugin::Mode mode;
- CryptoPlugin::SubSample ss;
- if (flags & BUFFER_FLAG_ENCRYPTED) {
- mode = CryptoPlugin::kMode_AES_WV;
- ss.mNumBytesOfClearData = 0;
- ss.mNumBytesOfEncryptedData = size;
- } else {
- mode = CryptoPlugin::kMode_Unencrypted;
- ss.mNumBytesOfClearData = size;
- ss.mNumBytesOfEncryptedData = 0;
- }
-
status_t err = mCrypto->decrypt(
(mFlags & kFlagIsSecure) != 0,
key,
iv,
mode,
info->mEncryptedData->base() + offset,
- &ss,
- 1 /* numSubSamples */,
+ subSamples,
+ numSubSamples,
info->mData->base());
if (err != OK) {
@@ -1217,8 +1268,6 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
}
info->mData->setRange(0, size);
- } else if (flags & BUFFER_FLAG_ENCRYPTED) {
- return -EINVAL;
}
reply->setBuffer("buffer", info->mData);