Android 13 - Media框架(22)- ACodecBufferChannel

这一节我们将了解 ACodecBufferChannel 中的 buffer 传输机制

status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
   
    std::shared_ptr<const std::vector<const BufferInfo>> array(
            std::atomic_load(&mInputBuffers));
    BufferInfoIterator it = findClientBuffer(array, buffer);
    if (it == array->end()) {
   
        return -ENOENT;
    }
    if (it->mClientBuffer != it->mCodecBuffer) {
   
        // Copy metadata from client to codec buffer.
        it->mCodecBuffer->meta()->clear();
        int64_t timeUs;
        CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs));
        it->mCodecBuffer->meta()->setInt64("timeUs", timeUs);
        int32_t eos;
        if (it->mClientBuffer->meta()->findInt32("eos", &eos)) {
   
            it->mCodecBuffer->meta()->setInt32("eos", eos);
        }
        int32_t csd;
        if (it->mClientBuffer->meta()->findInt32("csd", &csd)) {
   
            it->mCodecBuffer->meta()->setInt32("csd", csd);
        }
    }
    ALOGV("queueInputBuffer #%d", it->mBufferId);
    sp<AMessage> msg = mInputBufferFilled->dup();
    msg->setObject("buffer", it->mCodecBuffer);
    msg->setInt32("buffer-id", it->mBufferId);
    msg->post();
    return OK;
}

status_t ACodecBufferChannel::queueSecureInputBuffer(
        const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
        const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
        AString *errorDetailMsg) {
   
    if (!hasCryptoOrDescrambler() || mDealer == nullptr) {
   
        return -ENOSYS;
    }
    std::shared_ptr<const std::vector<const BufferInfo>> array(
            std::atomic_load(&mInputBuffers));
    BufferInfoIterator it = findClientBuffer(array, buffer);
    if (it == array->end()) {
   
        return -ENOENT;
    }

    native_handle_t *secureHandle = NULL;
    if (secure) {
   
        sp<SecureBuffer> secureData =
                static_cast<SecureBuffer *>(it->mCodecBuffer.get());
        if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
   
            return BAD_VALUE;
        }
        secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
    }
    ssize_t result = -1;
    ssize_t codecDataOffset = 0;
    if (numSubSamples == 1
            && subSamples[0].mNumBytesOfClearData == 0
            && subSamples[0].mNumBytesOfEncryptedData == 0) {
   
        // We don't need to go through crypto or descrambler if the input is empty.
        result = 0;
    } else if (mCrypto != NULL) {
   
        hardware::drm::V1_0::DestinationBuffer destination;
        if (secure) {
   
            destination.type = DrmBufferType::NATIVE_HANDLE;
            destination.secureMemory = hidl_handle(secureHandle);
        } else {
   
            destination.type = DrmBufferType::SHARED_MEMORY;
            IMemoryToSharedBuffer(
                    mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory);
        }

        hardware::drm::V1_0::SharedBuffer source;
        IMemoryToSharedBuffer(it->mSharedEncryptedBuffer, mHeapSeqNum, &source);

        result = mCrypto->decrypt(key, iv, mode, pattern,
                source, it->mClientBuffer->offset(),
                subSamples, numSubSamples, destination, errorDetailMsg);

        if (result < 0) {
   
            return result;
        }

        if (destination.type == DrmBufferType::SHARED_MEMORY) {
   
            memcpy(it->mCodecBuffer->base(), mDecryptDestination->unsecurePointer(), result);
        }
    } else {
   
        // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
        // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
        hidl_vec<SubSample> hidlSubSamples;
        hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);

        ssize_t offset;
        size_t size;
        it->mSharedEncryptedBuffer->getMemory(&offset, &size);
        hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
   
                .heapBase = *mHidlMemory,
                .offset = (uint64_t) offset,
                .size = size
        };

        DestinationBuffer dstBuffer;
        if (secure) {
   
            dstBuffer.type = BufferType::NATIVE_HANDLE;
            dstBuffer.secureMemory = hidl_handle(secureHandle);
        } else {
   
            dstBuffer.type = BufferType::SHARED_MEMORY;
            dstBuffer.nonsecureMemory = srcBuffer;
        }

        Status status = Status::OK;
        hidl_string detailedError;
        ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;

        if (key != NULL) {
   
            sctrl = (ScramblingControl)key[0];
            // Adjust for the PES offset
            codecDataOffset = key[2] | (key[3] << 8);
        }

        auto returnVoid = mDescrambler->descramble(
                sctrl,
                hidlSubSamples,
                srcBuffer,
                0,
                dstBuffer,
                0,
                [&status, &result, &detailedError] (
                        Status _status, uint32_t _bytesWritten,
                        const hidl_string& _detailedError) {
   
                    status = _status;
                    result = (ssize_t)_bytesWritten;
                    detailedError = _detailedError;
                });

        if (!returnVoid.isOk() || status != Status::OK || result < 0) {
   
            ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
                    returnVoid.description().c_str(), status, result);
            return UNKNOWN_ERROR;
        }

        if (result < codecDataOffset) {
   
            ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
            return BAD_VALUE;
        }

        ALOGV("descramble succeeded, %zd bytes", result);

        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
   
            memcpy(it->mCodecBuffer->base(),
                    (uint8_t*)it->mSharedEncryptedBuffer->unsecurePointer(),
                    result);
        }
    }

    it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset);

    // Copy metadata from client to codec buffer.
    it->mCodecBuffer->meta()->clear();
    int64_t timeUs;
    CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs));
    it->mCodecBuffer->meta()->setInt64("timeUs", timeUs);
    int32_t eos;
    if (it->mClientBuffer->meta()->findInt32("eos", &eos)) {
   
        it->mCodecBuffer->meta()->setInt32("eos", eos);
    }
    int32_t csd;
    if (it->mClientBuffer->meta()->findInt32("csd", &csd)) {
   
        it->mCodecBuffer->meta()->setInt32("csd", csd);
    }

    ALOGV("queueSecureInputBuffer #%d", it->mBufferId);
    sp<AMessage> msg = mInputBufferFilled->dup();
    msg->setObject("buffer", it->mCodecBuffer);
    msg->setInt32("buffer-id", it->mBufferId);
    msg->post();
    return OK;
}

相关推荐

  1. Android 13 - Media框架22)- ACodecBufferChannel

    2023-12-11 01:32:01       25 阅读
  2. Android 13 - Media框架22)- ACodec(四)

    2023-12-11 01:32:01       84 阅读
  3. Android 13 - Media框架22)- MediaCodec(三)

    2023-12-11 01:32:01       38 阅读
  4. Android 13 - Media框架20)- ACodec(二)

    2023-12-11 01:32:01       30 阅读
  5. Android 13 - Media框架21)- ACodec(三)

    2023-12-11 01:32:01       34 阅读
  6. Android 13 - Media框架25)- OMXNodeInstance(二)

    2023-12-11 01:32:01       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-11 01:32:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-11 01:32:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-11 01:32:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-11 01:32:01       18 阅读

热门阅读

  1. LeetCode 2048. 下一个更大的数值平衡数

    2023-12-11 01:32:01       40 阅读
  2. Linux结束程序运行的命令

    2023-12-11 01:32:01       34 阅读
  3. dubbo

    dubbo

    2023-12-11 01:32:01      35 阅读
  4. C++特殊类设计

    2023-12-11 01:32:01       34 阅读
  5. 5.3 函数-递归与求阶乘

    2023-12-11 01:32:01       28 阅读
  6. 人工智能原理复习

    2023-12-11 01:32:01       35 阅读