Loading cmds/stagefright/codec.cpp +21 −8 Original line number Original line Diff line number Diff line Loading @@ -296,15 +296,28 @@ static int decode( if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) { if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) { CHECK(decryptInputBuffers); 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( err = state->mCodec->queueInputBuffer( index, index, 0 /* offset */, 0 /* offset */, buffer->size(), buffer->size(), timeUs, timeUs, bufferFlags); bufferFlags); } CHECK_EQ(err, (status_t)OK); CHECK_EQ(err, (status_t)OK); Loading include/media/stagefright/MediaCodec.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define MEDIA_CODEC_H_ #define MEDIA_CODEC_H_ #include <gui/ISurfaceTexture.h> #include <gui/ISurfaceTexture.h> #include <media/hardware/CryptoAPI.h> #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AHandler.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading @@ -40,7 +41,6 @@ struct MediaCodec : public AHandler { BUFFER_FLAG_SYNCFRAME = 1, BUFFER_FLAG_SYNCFRAME = 1, BUFFER_FLAG_CODECCONFIG = 2, BUFFER_FLAG_CODECCONFIG = 2, BUFFER_FLAG_EOS = 4, BUFFER_FLAG_EOS = 4, BUFFER_FLAG_ENCRYPTED = 8, }; }; static sp<MediaCodec> CreateByType( static sp<MediaCodec> CreateByType( Loading Loading @@ -74,6 +74,17 @@ struct MediaCodec : public AHandler { int64_t presentationTimeUs, int64_t presentationTimeUs, uint32_t flags); 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 dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll); status_t dequeueOutputBuffer( status_t dequeueOutputBuffer( Loading media/libmedia/ICrypto.cpp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,17 @@ struct BpCrypto : public BpInterface<ICrypto> { data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInt32(secure); data.writeInt32(secure); data.writeInt32(mode); 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(key, 16); data.write(iv, 16); data.write(iv, 16); Loading media/libstagefright/MediaCodec.cpp +69 −20 Original line number Original line Diff line number Diff line Loading @@ -191,6 +191,31 @@ status_t MediaCodec::queueInputBuffer( return PostAndAwaitResponse(msg, &response); 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) { status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); msg->setInt64("timeoutUs", timeoutUs); msg->setInt64("timeoutUs", timeoutUs); Loading Loading @@ -1149,10 +1174,51 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { uint32_t flags; uint32_t flags; CHECK(msg->findSize("index", &index)); CHECK(msg->findSize("index", &index)); CHECK(msg->findSize("offset", &offset)); CHECK(msg->findSize("offset", &offset)); CHECK(msg->findSize("size", &size)); CHECK(msg->findInt64("timeUs", &timeUs)); CHECK(msg->findInt64("timeUs", &timeUs)); CHECK(msg->findInt32("flags", (int32_t *)&flags)); 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()) { if (index >= mPortBuffers[kPortIndexInput].size()) { return -ERANGE; return -ERANGE; } } Loading Loading @@ -1187,29 +1253,14 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { return -ERANGE; 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( status_t err = mCrypto->decrypt( (mFlags & kFlagIsSecure) != 0, (mFlags & kFlagIsSecure) != 0, key, key, iv, iv, mode, mode, info->mEncryptedData->base() + offset, info->mEncryptedData->base() + offset, &ss, subSamples, 1 /* numSubSamples */, numSubSamples, info->mData->base()); info->mData->base()); if (err != OK) { if (err != OK) { Loading @@ -1217,8 +1268,6 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { } } info->mData->setRange(0, size); info->mData->setRange(0, size); } else if (flags & BUFFER_FLAG_ENCRYPTED) { return -EINVAL; } } reply->setBuffer("buffer", info->mData); reply->setBuffer("buffer", info->mData); Loading Loading
cmds/stagefright/codec.cpp +21 −8 Original line number Original line Diff line number Diff line Loading @@ -296,15 +296,28 @@ static int decode( if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) { if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) { CHECK(decryptInputBuffers); 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( err = state->mCodec->queueInputBuffer( index, index, 0 /* offset */, 0 /* offset */, buffer->size(), buffer->size(), timeUs, timeUs, bufferFlags); bufferFlags); } CHECK_EQ(err, (status_t)OK); CHECK_EQ(err, (status_t)OK); Loading
include/media/stagefright/MediaCodec.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define MEDIA_CODEC_H_ #define MEDIA_CODEC_H_ #include <gui/ISurfaceTexture.h> #include <gui/ISurfaceTexture.h> #include <media/hardware/CryptoAPI.h> #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AHandler.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading @@ -40,7 +41,6 @@ struct MediaCodec : public AHandler { BUFFER_FLAG_SYNCFRAME = 1, BUFFER_FLAG_SYNCFRAME = 1, BUFFER_FLAG_CODECCONFIG = 2, BUFFER_FLAG_CODECCONFIG = 2, BUFFER_FLAG_EOS = 4, BUFFER_FLAG_EOS = 4, BUFFER_FLAG_ENCRYPTED = 8, }; }; static sp<MediaCodec> CreateByType( static sp<MediaCodec> CreateByType( Loading Loading @@ -74,6 +74,17 @@ struct MediaCodec : public AHandler { int64_t presentationTimeUs, int64_t presentationTimeUs, uint32_t flags); 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 dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll); status_t dequeueOutputBuffer( status_t dequeueOutputBuffer( Loading
media/libmedia/ICrypto.cpp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,17 @@ struct BpCrypto : public BpInterface<ICrypto> { data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInt32(secure); data.writeInt32(secure); data.writeInt32(mode); 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(key, 16); data.write(iv, 16); data.write(iv, 16); Loading
media/libstagefright/MediaCodec.cpp +69 −20 Original line number Original line Diff line number Diff line Loading @@ -191,6 +191,31 @@ status_t MediaCodec::queueInputBuffer( return PostAndAwaitResponse(msg, &response); 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) { status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); msg->setInt64("timeoutUs", timeoutUs); msg->setInt64("timeoutUs", timeoutUs); Loading Loading @@ -1149,10 +1174,51 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { uint32_t flags; uint32_t flags; CHECK(msg->findSize("index", &index)); CHECK(msg->findSize("index", &index)); CHECK(msg->findSize("offset", &offset)); CHECK(msg->findSize("offset", &offset)); CHECK(msg->findSize("size", &size)); CHECK(msg->findInt64("timeUs", &timeUs)); CHECK(msg->findInt64("timeUs", &timeUs)); CHECK(msg->findInt32("flags", (int32_t *)&flags)); 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()) { if (index >= mPortBuffers[kPortIndexInput].size()) { return -ERANGE; return -ERANGE; } } Loading Loading @@ -1187,29 +1253,14 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { return -ERANGE; 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( status_t err = mCrypto->decrypt( (mFlags & kFlagIsSecure) != 0, (mFlags & kFlagIsSecure) != 0, key, key, iv, iv, mode, mode, info->mEncryptedData->base() + offset, info->mEncryptedData->base() + offset, &ss, subSamples, 1 /* numSubSamples */, numSubSamples, info->mData->base()); info->mData->base()); if (err != OK) { if (err != OK) { Loading @@ -1217,8 +1268,6 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { } } info->mData->setRange(0, size); info->mData->setRange(0, size); } else if (flags & BUFFER_FLAG_ENCRYPTED) { return -EINVAL; } } reply->setBuffer("buffer", info->mData); reply->setBuffer("buffer", info->mData); Loading