Loading media/jni/android_media_MediaCodec.cpp +56 −16 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> #include <binder/MemoryHeapBase.h> #include <binder/MemoryDealer.h> #include <cutils/compiler.h> Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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() { Loading Loading @@ -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()); Loading @@ -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, Loading @@ -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; } Loading Loading @@ -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 */); } Loading Loading @@ -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) { Loading media/jni/android_media_MediaCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -181,6 +183,7 @@ private: sp<MediaCodec> mCodec; AString mNameAtCreation; bool mGraphicOutput{false}; bool mHasCryptoOrDescrambler{false}; std::once_flag mReleaseFlag; sp<AMessage> mCallbackNotification; Loading media/jni/android_media_MediaCodecLinearBlock.h +7 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -56,8 +58,8 @@ struct JMediaCodecLinearBlock { } sp<hardware::HidlMemory> toHidlMemory() { if (mMemory) { return mMemory; if (mHidlMemory) { return mHidlMemory; } return nullptr; } Loading Loading
media/jni/android_media_MediaCodec.cpp +56 −16 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> #include <binder/MemoryHeapBase.h> #include <binder/MemoryDealer.h> #include <cutils/compiler.h> Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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() { Loading Loading @@ -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()); Loading @@ -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, Loading @@ -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; } Loading Loading @@ -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 */); } Loading Loading @@ -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) { Loading
media/jni/android_media_MediaCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -181,6 +183,7 @@ private: sp<MediaCodec> mCodec; AString mNameAtCreation; bool mGraphicOutput{false}; bool mHasCryptoOrDescrambler{false}; std::once_flag mReleaseFlag; sp<AMessage> mCallbackNotification; Loading
media/jni/android_media_MediaCodecLinearBlock.h +7 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -56,8 +58,8 @@ struct JMediaCodecLinearBlock { } sp<hardware::HidlMemory> toHidlMemory() { if (mMemory) { return mMemory; if (mHidlMemory) { return mHidlMemory; } return nullptr; } Loading