Loading cmds/stagefright/codec.cpp +21 −8 Original line number Diff line number Diff line Loading @@ -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->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); Loading include/media/stagefright/MediaCodec.h +12 −1 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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( Loading Loading @@ -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( Loading media/libmedia/ICrypto.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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); Loading media/libstagefright/MediaCodec.cpp +69 −20 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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); Loading Loading
cmds/stagefright/codec.cpp +21 −8 Original line number Diff line number Diff line Loading @@ -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->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); Loading
include/media/stagefright/MediaCodec.h +12 −1 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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( Loading Loading @@ -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( Loading
media/libmedia/ICrypto.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
media/libstagefright/MediaCodec.cpp +69 −20 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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); Loading