diff options
| author | 2020-05-18 19:54:35 +0000 | |
|---|---|---|
| committer | 2020-05-18 19:54:35 +0000 | |
| commit | 33db90860f14bc1df32345a19b59ba1dc8c73cd7 (patch) | |
| tree | 6e7d531106ebe47c092191bb02e61edd5d0b757b | |
| parent | 6ee52bdc337b604c44823e9950d652787b3146f5 (diff) | |
| parent | f7069cea0adb71674511cf18c6a5fc9612513f1e (diff) | |
Merge "media: fix encrypted buffer handling" into rvc-dev
| -rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 72 | ||||
| -rw-r--r-- | media/jni/android_media_MediaCodec.h | 3 | ||||
| -rw-r--r-- | media/jni/android_media_MediaCodecLinearBlock.h | 12 |
3 files changed, 66 insertions, 21 deletions
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 331477f72aa4..43cb25f03fb0 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -43,7 +43,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> -#include <binder/MemoryHeapBase.h> +#include <binder/MemoryDealer.h> #include <cutils/compiler.h> @@ -306,6 +306,7 @@ status_t JMediaCodec::configure( CHECK(format->findString("mime", &mime)); mGraphicOutput = (mime.startsWithIgnoreCase("video/") || mime.startsWithIgnoreCase("image/")) && !(flags & CONFIGURE_FLAG_ENCODE); + mHasCryptoOrDescrambler = (crypto != nullptr) || (descrambler != nullptr); return mCodec->configure( format, mSurfaceTextureClient, crypto, descrambler, flags); @@ -1603,14 +1604,13 @@ struct NativeCryptoInfo { ScopedLocalRef<jobject> patternObj{ env, env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID)}; - CryptoPlugin::Pattern pattern; if (patternObj.get() == nullptr) { - pattern.mEncryptBlocks = 0; - pattern.mSkipBlocks = 0; + mPattern.mEncryptBlocks = 0; + mPattern.mSkipBlocks = 0; } else { - pattern.mEncryptBlocks = env->GetIntField( + mPattern.mEncryptBlocks = env->GetIntField( patternObj.get(), gFields.patternEncryptBlocksID); - pattern.mSkipBlocks = env->GetIntField( + mPattern.mSkipBlocks = env->GetIntField( patternObj.get(), gFields.patternSkipBlocksID); } @@ -1679,6 +1679,18 @@ struct NativeCryptoInfo { mIv = env->GetByteArrayElements(mIvObj.get(), nullptr); } } + + } + + explicit NativeCryptoInfo(jint size) + : mIvObj{nullptr, nullptr}, + mKeyObj{nullptr, nullptr}, + mMode{CryptoPlugin::kMode_Unencrypted}, + mPattern{0, 0} { + mSubSamples = new CryptoPlugin::SubSample[1]; + mNumSubSamples = 1; + mSubSamples[0].mNumBytesOfClearData = size; + mSubSamples[0].mNumBytesOfEncryptedData = 0; } ~NativeCryptoInfo() { @@ -2128,10 +2140,13 @@ static void android_media_MediaCodec_native_queueLinearBlock( if (env->GetBooleanField(bufferObj, gLinearBlockInfo.validId)) { JMediaCodecLinearBlock *context = (JMediaCodecLinearBlock *)env->GetLongField(bufferObj, gLinearBlockInfo.contextId); - if (cryptoInfoObj != nullptr) { + if (codec->hasCryptoOrDescrambler()) { memory = context->toHidlMemory(); + // TODO: copy if memory is null + offset += context->mHidlMemoryOffset; } else { buffer = context->toC2Buffer(offset, size); + // TODO: copy if buffer is null } } env->MonitorExit(lock.get()); @@ -2141,13 +2156,19 @@ static void android_media_MediaCodec_native_queueLinearBlock( } AString errorDetailMsg; - if (cryptoInfoObj != nullptr) { + if (codec->hasCryptoOrDescrambler()) { if (!memory) { + ALOGI("queueLinearBlock: no ashmem memory for encrypted content"); throwExceptionAsNecessary(env, BAD_VALUE); return; } - - NativeCryptoInfo cryptoInfo{env, cryptoInfoObj}; + NativeCryptoInfo cryptoInfo = [env, cryptoInfoObj, size]{ + if (cryptoInfoObj == nullptr) { + return NativeCryptoInfo{size}; + } else { + return NativeCryptoInfo{env, cryptoInfoObj}; + } + }(); err = codec->queueEncryptedLinearBlock( index, memory, @@ -2162,6 +2183,7 @@ static void android_media_MediaCodec_native_queueLinearBlock( &errorDetailMsg); } else { if (!buffer) { + ALOGI("queueLinearBlock: no C2Buffer found"); throwExceptionAsNecessary(env, BAD_VALUE); return; } @@ -2955,13 +2977,13 @@ static jobject android_media_MediaCodec_LinearBlock_native_map( context->mLegacyBuffer->size(), true, // readOnly true /* clearBuffer */); - } else if (context->mHeap) { + } else if (context->mMemory) { return CreateByteBuffer( env, - static_cast<uint8_t *>(context->mHeap->getBase()) + context->mHeap->getOffset(), - context->mHeap->getSize(), + context->mMemory->unsecurePointer(), + context->mMemory->size(), 0, - context->mHeap->getSize(), + context->mMemory->size(), false, // readOnly true /* clearBuffer */); } @@ -3011,8 +3033,26 @@ static void android_media_MediaCodec_LinearBlock_native_obtain( } } if (hasSecure && !hasNonSecure) { - context->mHeap = new MemoryHeapBase(capacity); - context->mMemory = hardware::fromHeap(context->mHeap); + constexpr size_t kInitialDealerCapacity = 1048576; // 1MB + thread_local sp<MemoryDealer> sDealer = new MemoryDealer( + kInitialDealerCapacity, "JNI(1MB)"); + context->mMemory = sDealer->allocate(capacity); + if (context->mMemory == nullptr) { + size_t newDealerCapacity = sDealer->getMemoryHeap()->getSize() * 2; + while (capacity * 2 > newDealerCapacity) { + newDealerCapacity *= 2; + } + ALOGI("LinearBlock.native_obtain: " + "Dealer capacity increasing from %zuMB to %zuMB", + sDealer->getMemoryHeap()->getSize() / 1048576, + newDealerCapacity / 1048576); + sDealer = new MemoryDealer( + newDealerCapacity, + AStringPrintf("JNI(%zuMB)", newDealerCapacity).c_str()); + context->mMemory = sDealer->allocate(capacity); + } + context->mHidlMemory = hardware::fromHeap(context->mMemory->getMemory( + &context->mHidlMemoryOffset, &context->mHidlMemorySize)); } else { context->mBlock = MediaCodec::FetchLinearBlock(capacity, names); if (!context->mBlock) { diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index 400ce1bc98e7..5c34341a86a1 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -162,6 +162,8 @@ struct JMediaCodec : public AHandler { void selectAudioPresentation(const int32_t presentationId, const int32_t programId); + bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; } + protected: virtual ~JMediaCodec(); @@ -181,6 +183,7 @@ private: sp<MediaCodec> mCodec; AString mNameAtCreation; bool mGraphicOutput{false}; + bool mHasCryptoOrDescrambler{false}; std::once_flag mReleaseFlag; sp<AMessage> mCallbackNotification; diff --git a/media/jni/android_media_MediaCodecLinearBlock.h b/media/jni/android_media_MediaCodecLinearBlock.h index 08438340d803..8f1d2fa35d70 100644 --- a/media/jni/android_media_MediaCodecLinearBlock.h +++ b/media/jni/android_media_MediaCodecLinearBlock.h @@ -31,8 +31,10 @@ struct JMediaCodecLinearBlock { std::shared_ptr<C2LinearBlock> mBlock; std::shared_ptr<C2WriteView> mReadWriteMapping; - sp<IMemoryHeap> mHeap; - sp<hardware::HidlMemory> mMemory; + sp<IMemory> mMemory; + sp<hardware::HidlMemory> mHidlMemory; + ssize_t mHidlMemoryOffset; + size_t mHidlMemorySize; sp<MediaCodecBuffer> mLegacyBuffer; @@ -56,8 +58,8 @@ struct JMediaCodecLinearBlock { } sp<hardware::HidlMemory> toHidlMemory() { - if (mMemory) { - return mMemory; + if (mHidlMemory) { + return mHidlMemory; } return nullptr; } @@ -65,4 +67,4 @@ struct JMediaCodecLinearBlock { } // namespace android -#endif // _ANDROID_MEDIA_MEDIACODECLINEARBLOCK_H_
\ No newline at end of file +#endif // _ANDROID_MEDIA_MEDIACODECLINEARBLOCK_H_ |