Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5eb9c6d authored by Wonsik Kim's avatar Wonsik Kim Committed by Automerger Merge Worker
Browse files

Merge "media: fix encrypted buffer handling" into rvc-dev am: 33db9086

Change-Id: I8da4db8072cafe3f9788777a7a38b7d3e720446d
parents b2b25464 33db9086
Loading
Loading
Loading
Loading
+56 −16
Original line number Diff line number Diff line
@@ -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) {
+3 −0
Original line number Diff line number Diff line
@@ -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;
+7 −5
Original line number Diff line number Diff line
@@ -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;
    }