diff options
-rw-r--r-- | cmds/stagefright/codec.cpp | 29 | ||||
-rw-r--r-- | include/media/stagefright/MediaCodec.h | 13 | ||||
-rw-r--r-- | media/libmedia/ICrypto.cpp | 11 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 89 |
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); |