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

Commit 3b2847fa authored by Chong Zhang's avatar Chong Zhang
Browse files

MediaCas: add CAS support to MPEG2TSExtractor and MediaCodec

bug: 22804304
Change-Id: I14ec4ffc8c72e283f5cfd742dabaf4ad8bd9d698
parent 1cbdb417
Loading
Loading
Loading
Loading
+47 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <numeric>

#include <android/media/IDescrambler.h>
#include <binder/MemoryDealer.h>
#include <media/openmax/OMX_Core.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -33,7 +34,8 @@
#include "include/SharedMemoryBuffer.h"

namespace android {

using binder::Status;
using MediaDescrambler::DescrambleInfo;
using BufferInfo = ACodecBufferChannel::BufferInfo;
using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;

@@ -92,7 +94,7 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
        const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
        AString *errorDetailMsg) {
    if (mCrypto == nullptr) {
    if (!hasCryptoOrDescrambler()) {
        return -ENOSYS;
    }
    std::shared_ptr<const std::vector<const BufferInfo>> array(
@@ -116,9 +118,47 @@ status_t ACodecBufferChannel::queueSecureInputBuffer(
        destination.mType = ICrypto::kDestinationTypeSharedMemory;
        destination.mSharedMemory = mDecryptDestination;
    }
    ssize_t result = mCrypto->decrypt(key, iv, mode, pattern,

    ssize_t result = -1;
    if (mCrypto != NULL) {
        result = mCrypto->decrypt(key, iv, mode, pattern,
                    it->mSharedEncryptedBuffer, it->mClientBuffer->offset(),
                    subSamples, numSubSamples, destination, errorDetailMsg);
    } else {
        DescrambleInfo descrambleInfo;
        descrambleInfo.dstType = destination.mType ==
                ICrypto::kDestinationTypeSharedMemory ?
                DescrambleInfo::kDestinationTypeVmPointer :
                DescrambleInfo::kDestinationTypeNativeHandle;
        descrambleInfo.scramblingControl = key != NULL ?
                (DescramblerPlugin::ScramblingControl)key[0] :
                DescramblerPlugin::kScrambling_Unscrambled;
        descrambleInfo.numSubSamples = numSubSamples;
        descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples;
        descrambleInfo.srcMem = it->mSharedEncryptedBuffer;
        descrambleInfo.srcOffset = 0;
        descrambleInfo.dstPtr = NULL;
        descrambleInfo.dstOffset = 0;

        int32_t descrambleResult = -1;
        Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult);

        if (status.isOk()) {
            result = descrambleResult;
        }

        if (result < 0) {
            ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd",
                    status.exceptionCode(), status.transactionError(), result);
        } else {
            ALOGV("descramble succeeded, result=%zd", result);
        }

        if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) {
            memcpy(destination.mSharedMemory->pointer(),
                    (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result);
        }
    }

    if (result < 0) {
        return result;
@@ -212,8 +252,7 @@ void ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *arr
}

void ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) {
    bool secure = (mCrypto != nullptr);
    if (secure) {
    if (hasCryptoOrDescrambler()) {
        size_t totalSize = std::accumulate(
                array.begin(), array.end(), 0u,
                [alignment = MemoryDealer::getAllocationAlignment()]
@@ -232,7 +271,7 @@ void ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &ar
    std::vector<const BufferInfo> inputBuffers;
    for (const BufferAndId &elem : array) {
        sp<IMemory> sharedEncryptedBuffer;
        if (secure) {
        if (hasCryptoOrDescrambler()) {
            sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity());
        }
        inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer);
+6 −4
Original line number Diff line number Diff line
@@ -2012,6 +2012,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            }

            mDescrambler = static_cast<IDescrambler *>(descrambler);
            mBufferChannel->setDescrambler(mDescrambler);

            uint32_t flags;
            CHECK(msg->findInt32("flags", (int32_t *)&flags));
@@ -2033,7 +2034,6 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            CHECK(msg->senderAwaitsResponse(&replyID));

            status_t err = OK;
            sp<Surface> surface;

            switch (mState) {
                case CONFIGURED:
@@ -2718,7 +2718,7 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
    CryptoPlugin::Pattern pattern;

    if (msg->findSize("size", &size)) {
        if (mCrypto != NULL) {
        if (hasCryptoOrDescrambler()) {
            ss.mNumBytesOfClearData = size;
            ss.mNumBytesOfEncryptedData = 0;

@@ -2730,7 +2730,9 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
            pattern.mSkipBlocks = 0;
        }
    } else {
        if (mCrypto == NULL) {
        if (!hasCryptoOrDescrambler()) {
            ALOGE("[%s] queuing secure buffer without mCrypto or mDescrambler!",
                    mComponentName.c_str());
            return -EINVAL;
        }

@@ -2779,7 +2781,7 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {

    sp<MediaCodecBuffer> buffer = info->mData;
    status_t err = OK;
    if (mCrypto != NULL) {
    if (hasCryptoOrDescrambler()) {
        AString *errorDetailMsg;
        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));

+16 −3
Original line number Diff line number Diff line
@@ -610,6 +610,22 @@ status_t convertMetaDataToMessage(
    sp<AMessage> msg = new AMessage;
    msg->setString("mime", mime);

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyCas, &type, &data, &size)) {
        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
        msg->setBuffer("cas", buffer);
        memcpy(buffer->data(), data, size);
    }

    if (!strncasecmp("video/scrambled", mime, 15)
            || !strncasecmp("audio/scrambled", mime, 15)) {

        *format = msg;
        return OK;
    }

    int64_t durationUs;
    if (meta->findInt64(kKeyDuration, &durationUs)) {
        msg->setInt64("durationUs", durationUs);
@@ -759,9 +775,6 @@ status_t convertMetaDataToMessage(
        msg->setInt32("frame-rate", fps);
    }

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        // Parse the AVCDecoderConfigurationRecord

+4 −0
Original line number Diff line number Diff line
@@ -126,6 +126,10 @@ private:
    // the caller has given up the reference, so that access is also safe.
    std::shared_ptr<const std::vector<const BufferInfo>> mInputBuffers;
    std::shared_ptr<const std::vector<const BufferInfo>> mOutputBuffers;

    bool hasCryptoOrDescrambler() {
        return mCrypto != NULL || mDescrambler != NULL;
    }
};

}  // namespace android
+7 −1
Original line number Diff line number Diff line
@@ -35,9 +35,10 @@
#include <utils/NativeHandle.h>

#include <system/graphics.h>
#include <android/media/IDescrambler.h>

namespace android {

using namespace media;
class BufferChannelBase;
class BufferProducerWrapper;
class MediaCodecBuffer;
@@ -259,6 +260,10 @@ public:
        mCrypto = crypto;
    }

    inline void setDescrambler(const sp<IDescrambler> &descrambler) {
        mDescrambler = descrambler;
    }

    /**
     * Queue an input buffer into the buffer channel.
     *
@@ -317,6 +322,7 @@ public:
protected:
    std::unique_ptr<CodecBase::BufferCallback> mCallback;
    sp<ICrypto> mCrypto;
    sp<IDescrambler> mDescrambler;
};

}  // namespace android
Loading