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

Commit 094ddf5c authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7233012 from 927ae78a to sc-release

Change-Id: Ib7a4a8dae3234adc3463f0213d3e0aa2ec940b76
parents ff378867 927ae78a
Loading
Loading
Loading
Loading
+98 −7
Original line number Diff line number Diff line
@@ -642,7 +642,8 @@ public:
     * \retval C2_REFUSED   no permission to complete the allocation
     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
     * \retval C2_OMITTED   this allocator does not support 1D allocations
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during allocation
     *                      (unexpected)
     */
    virtual c2_status_t newLinearAllocation(
            uint32_t capacity __unused, C2MemoryUsage usage __unused,
@@ -666,7 +667,8 @@ public:
     * \retval C2_REFUSED   no permission to recreate the allocation
     * \retval C2_BAD_VALUE invalid handle (caller error)
     * \retval C2_OMITTED   this allocator does not support 1D allocations
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during allocation
     *                      (unexpected)
     */
    virtual c2_status_t priorLinearAllocation(
            const C2Handle *handle __unused,
@@ -699,7 +701,8 @@ public:
     * \retval C2_REFUSED   no permission to complete the allocation
     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error)
     * \retval C2_OMITTED   this allocator does not support 2D allocations
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during allocation
     *                      (unexpected)
     */
    virtual c2_status_t newGraphicAllocation(
            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
@@ -724,7 +727,8 @@ public:
     * \retval C2_REFUSED   no permission to recreate the allocation
     * \retval C2_BAD_VALUE invalid handle (caller error)
     * \retval C2_OMITTED   this allocator does not support 2D allocations
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during recreation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during recreation
     *                      (unexpected)
     */
    virtual c2_status_t priorGraphicAllocation(
            const C2Handle *handle __unused,
@@ -908,7 +912,8 @@ public:
     * \retval C2_REFUSED   no permission to complete any required allocation
     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
     * \retval C2_OMITTED   this pool does not support linear blocks
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during operation
     *                      (unexpected)
     */
    virtual c2_status_t fetchLinearBlock(
            uint32_t capacity __unused, C2MemoryUsage usage __unused,
@@ -937,7 +942,8 @@ public:
     * \retval C2_REFUSED   no permission to complete any required allocation
     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
     * \retval C2_OMITTED   this pool does not support circular blocks
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during operation
     *                      (unexpected)
     */
    virtual c2_status_t fetchCircularBlock(
            uint32_t capacity __unused, C2MemoryUsage usage __unused,
@@ -969,7 +975,8 @@ public:
     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
     *                      error)
     * \retval C2_OMITTED   this pool does not support 2D blocks
     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during operation
     *                      (unexpected)
     */
    virtual c2_status_t fetchGraphicBlock(
            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
@@ -980,6 +987,90 @@ public:
    }

    virtual ~C2BlockPool() = default;

    /**
     * Blocking fetch for linear block. Obtains a linear writable block of given |capacity|
     * and |usage|. If a block can be successfully obtained, the block is stored in |block|,
     * |fence| is set to a null-fence and C2_OK is returned.
     *
     * If a block cannot be temporarily obtained, |block| is set to nullptr, a waitable fence
     * is stored into |fence| and C2_BLOCKING is returned.
     *
     * Otherwise, |block| is set to nullptr and |fence| is set to a null-fence. The waitable
     * fence is signalled when the temporary restriction on fetch is lifted.
     * e.g. more memory is available to fetch because some meomory or prior blocks were released.
     *
     * \param capacity the size of requested block.
     * \param usage    the memory usage info for the requested block. Returned blocks will be
     *                 optimized for this usage, but may be used with any usage. One exception:
     *                 protected blocks/buffers can only be used in a protected scenario.
     * \param block    pointer to where the obtained block shall be stored on success. nullptr will
     *                 be stored here on failure
     * \param fence    pointer to where the fence shall be stored on C2_BLOCKING error.
     *
     * \retval C2_OK        the operation was successful
     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
     * \retval C2_TIMED_OUT the operation timed out
     * \retval C2_BLOCKING  the operation is blocked
     * \retval C2_REFUSED   no permission to complete any required allocation
     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
     * \retval C2_OMITTED   this pool does not support linear blocks nor fence.
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during operation
     *                      (unexpected)
     */
    virtual c2_status_t fetchLinearBlock(
            uint32_t capacity __unused, C2MemoryUsage usage __unused,
            std::shared_ptr<C2LinearBlock> *block /* nonnull */,
            C2Fence *fence /* nonnull */) {
        *block = nullptr;
        (void) fence;
        return C2_OMITTED;
    }

    /**
     * Blocking fetch for 2D graphic block. Obtains a 2D graphic writable block of given |capacity|
     * and |usage|. If a block can be successfully obtained, the block is stored in |block|,
     * |fence| is set to a null-fence and C2_OK is returned.
     *
     * If a block cannot be temporarily obtained, |block| is set to nullptr, a waitable fence
     * is stored into |fence| and C2_BLOCKING is returned.
     *
     * Otherwise, |block| is set to nullptr and |fence| is set to a null-fence. The waitable
     * fence is signalled when the temporary restriction on fetch is lifted.
     * e.g. more memory is available to fetch because some meomory or prior blocks were released.
     *
     * \param width  the width of requested block (the obtained block could be slightly larger, e.g.
     *               to accommodate any system-required alignment)
     * \param height the height of requested block (the obtained block could be slightly larger,
     *               e.g. to accommodate any system-required alignment)
     * \param format the pixel format of requested block. This could be a vendor specific format.
     * \param usage  the memory usage info for the requested block. Returned blocks will be
     *               optimized for this usage, but may be used with any usage. One exception:
     *               protected blocks/buffers can only be used in a protected scenario.
     * \param block  pointer to where the obtained block shall be stored on success. nullptr
     *               will be stored here on failure
     * \param fence  pointer to where the fence shall be stored on C2_BLOCKING error.
     *
     * \retval C2_OK        the operation was successful
     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
     * \retval C2_TIMED_OUT the operation timed out
     * \retval C2_BLOCKING  the operation is blocked
     * \retval C2_REFUSED   no permission to complete any required allocation
     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
     *                      error)
     * \retval C2_OMITTED   this pool does not support 2D blocks
     * \retval C2_CORRUPTED some unknown, unrecoverable error occurred during operation
     *                      (unexpected)
     */
    virtual c2_status_t fetchGraphicBlock(
            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
            C2MemoryUsage usage __unused,
            std::shared_ptr<C2GraphicBlock> *block /* nonnull */,
            C2Fence *fence /* nonnull */) {
        *block = nullptr;
        (void) fence;
        return C2_OMITTED;
    }
protected:
    C2BlockPool() = default;
};
+35 −1
Original line number Diff line number Diff line
@@ -33,12 +33,14 @@
#include <OMX_IndexExt.h>

#include <android/fdsan.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <utils/Thread.h>

#include "utils/Codec2Mapper.h"
#include "C2OMXNode.h"

namespace android {
@@ -71,6 +73,23 @@ public:
        jobs->cond.broadcast();
    }

    void setDataspace(android_dataspace dataspace) {
        Mutexed<Jobs>::Locked jobs(mJobs);
        ColorUtils::convertDataSpaceToV0(dataspace);
        jobs->configUpdate.emplace_back(new C2StreamDataSpaceInfo::input(0u, dataspace));
        int32_t standard;
        int32_t transfer;
        int32_t range;
        ColorUtils::getColorConfigFromDataSpace(dataspace, &range, &standard, &transfer);
        std::unique_ptr<C2StreamColorAspectsInfo::input> colorAspects =
            std::make_unique<C2StreamColorAspectsInfo::input>(0u);
        if (C2Mapper::map(standard, &colorAspects->primaries, &colorAspects->matrix)
                && C2Mapper::map(transfer, &colorAspects->transfer)
                && C2Mapper::map(range, &colorAspects->range)) {
            jobs->configUpdate.push_back(std::move(colorAspects));
        }
    }

protected:
    bool threadLoop() override {
        constexpr nsecs_t kIntervalNs = nsecs_t(10) * 1000 * 1000;  // 10ms
@@ -102,6 +121,9 @@ protected:
                    uniqueFds.push_back(std::move(queue.workList.front().fd1));
                    queue.workList.pop_front();
                }
                for (const std::unique_ptr<C2Param> &param : jobs->configUpdate) {
                    items.front()->input.configUpdate.emplace_back(C2Param::Copy(*param));
                }

                jobs.unlock();
                for (int fenceFd : fenceFds) {
@@ -119,6 +141,7 @@ protected:
                queued = true;
            }
            if (queued) {
                jobs->configUpdate.clear();
                return true;
            }
            if (i == 0) {
@@ -161,6 +184,7 @@ private:
        std::map<std::weak_ptr<Codec2Client::Component>,
                 Queue,
                 std::owner_less<std::weak_ptr<Codec2Client::Component>>> queues;
        std::vector<std::unique_ptr<C2Param>> configUpdate;
        Condition cond;
    };
    Mutexed<Jobs> mJobs;
@@ -172,6 +196,9 @@ C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
      mQueueThread(new QueueThread) {
    android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
    mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);

    Mutexed<android_dataspace>::Locked ds(mDataspace);
    *ds = HAL_DATASPACE_UNKNOWN;
}

status_t C2OMXNode::freeNode() {
@@ -461,8 +488,11 @@ status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
    android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
    uint32_t pixelFormat = msg.u.event_data.data3;

    // TODO: set dataspace on component to see if it impacts color aspects
    ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
    mQueueThread->setDataspace(dataSpace);

    Mutexed<android_dataspace>::Locked ds(mDataspace);
    *ds = dataSpace;
    return OK;
}

@@ -495,4 +525,8 @@ void C2OMXNode::onInputBufferDone(c2_cntr64_t index) {
    (void)mBufferSource->onInputBufferEmptied(bufferId, -1);
}

android_dataspace C2OMXNode::getDataspace() {
    return *mDataspace.lock();
}

}  // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -93,6 +93,11 @@ struct C2OMXNode : public BnOMXNode {
     */
    void onInputBufferDone(c2_cntr64_t index);

    /**
     * Returns dataspace information from GraphicBufferSource.
     */
    android_dataspace getDataspace();

private:
    std::weak_ptr<Codec2Client::Component> mComp;
    sp<IOMXBufferSource> mBufferSource;
@@ -101,6 +106,7 @@ private:
    uint32_t mWidth;
    uint32_t mHeight;
    uint64_t mUsage;
    Mutexed<android_dataspace> mDataspace;

    // WORKAROUND: timestamp adjustment

+40 −2
Original line number Diff line number Diff line
@@ -211,8 +211,6 @@ public:
                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
                &usage, sizeof(usage));

        // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
        // communicate that directly to the component.
        mSource->configure(
                mOmxNode, static_cast<hardware::graphics::common::V1_0::Dataspace>(mDataSpace));
        return OK;
@@ -411,6 +409,10 @@ public:
        mNode->onInputBufferDone(index);
    }

    android_dataspace getDataspace() override {
        return mNode->getDataspace();
    }

private:
    sp<HGraphicBufferSource> mSource;
    sp<C2OMXNode> mNode;
@@ -1612,6 +1614,7 @@ void CCodec::start() {
        outputFormat = config->mOutputFormat = config->mOutputFormat->dup();
        if (config->mInputSurface) {
            err2 = config->mInputSurface->start();
            config->mInputSurfaceDataspace = config->mInputSurface->getDataspace();
        }
        buffersBoundToCodec = config->mBuffersBoundToCodec;
    }
@@ -1699,6 +1702,7 @@ void CCodec::stop() {
        if (config->mInputSurface) {
            config->mInputSurface->disconnect();
            config->mInputSurface = nullptr;
            config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN;
        }
    }
    {
@@ -1748,6 +1752,7 @@ void CCodec::initiateRelease(bool sendCallback /* = true */) {
        if (config->mInputSurface) {
            config->mInputSurface->disconnect();
            config->mInputSurface = nullptr;
            config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN;
        }
    }

@@ -2001,6 +2006,39 @@ void CCodec::signalRequestIDRFrame() {
    config->setParameters(comp, params, C2_MAY_BLOCK);
}

status_t CCodec::querySupportedParameters(std::vector<std::string> *names) {
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    return config->querySupportedParameters(names);
}

status_t CCodec::describeParameter(
        const std::string &name, CodecParameterDescriptor *desc) {
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    return config->describe(name, desc);
}

status_t CCodec::subscribeToParameters(const std::vector<std::string> &names) {
    std::shared_ptr<Codec2Client::Component> comp = mState.lock()->comp;
    if (!comp) {
        return INVALID_OPERATION;
    }
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    return config->subscribeToVendorConfigUpdate(comp, names);
}

status_t CCodec::unsubscribeFromParameters(const std::vector<std::string> &names) {
    std::shared_ptr<Codec2Client::Component> comp = mState.lock()->comp;
    if (!comp) {
        return INVALID_OPERATION;
    }
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    return config->unsubscribeFromVendorConfigUpdate(comp, names);
}

void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
    if (!workItems.empty()) {
        Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+114 −18
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <C2Param.h>
#include <util/C2InterfaceHelper.h>

#include <media/stagefright/CodecBase.h>
#include <media/stagefright/MediaCodecConstants.h>

#include "CCodecConfig.h"
@@ -290,8 +291,8 @@ struct StandardParams {
    std::vector<std::string> getPathsForDomain(
            Domain any, Domain all = Domain::ALL) const {
        std::vector<std::string> res;
        for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
            for (const ConfigMapper &cm : el.second) {
        for (const auto &[key, mappers] : mConfigMappers) {
            for (const ConfigMapper &cm : mappers) {
                ALOGV("filtering %s %x %x %x %x", cm.path().c_str(), cm.domain(), any,
                        (cm.domain() & any), (cm.domain() & any & all));
                if ((cm.domain() & any) && ((cm.domain() & any & all) == (any & all))) {
@@ -1061,7 +1062,7 @@ status_t CCodecConfig::initialize(
            std::vector<std::string> keys;
            mParamUpdater->getKeysForParamIndex(desc->index(), &keys);
            for (const std::string &key : keys) {
                mVendorParamIndices.insert_or_assign(key, desc->index());
                mVendorParams.insert_or_assign(key, desc);
            }
        }
    }
@@ -1128,6 +1129,12 @@ bool CCodecConfig::updateConfiguration(
            insertion.first->second = std::move(p);
        }
    }
    if (mInputSurface
            && (domain & mOutputDomain)
            && mInputSurfaceDataspace != mInputSurface->getDataspace()) {
        changed = true;
        mInputSurfaceDataspace = mInputSurface->getDataspace();
    }

    ALOGV("updated configuration has %zu params (%s)", mCurrentConfig.size(),
            changed ? "CHANGED" : "no change");
@@ -1193,8 +1200,8 @@ sp<AMessage> CCodecConfig::getFormatForDomain(
        const ReflectedParamUpdater::Dict &reflected,
        Domain portDomain) const {
    sp<AMessage> msg = new AMessage;
    for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
        for (const ConfigMapper &cm : el.second) {
    for (const auto &[key, mappers] : mStandardParams->getKeys()) {
        for (const ConfigMapper &cm : mappers) {
            if ((cm.domain() & portDomain) == 0 // input-output-coded-raw
                || (cm.domain() & mDomain) != mDomain // component domain + kind (these must match)
                || (cm.domain() & IS_READ) == 0) {
@@ -1218,26 +1225,26 @@ sp<AMessage> CCodecConfig::getFormatForDomain(
                ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
                continue;
            }
            msg->setItem(el.first.c_str(), item);
            msg->setItem(key.c_str(), item);
        }
    }

    bool input = (portDomain & Domain::IS_INPUT);
    std::vector<std::string> vendorKeys;
    for (const std::pair<std::string, ReflectedParamUpdater::Value> &entry : reflected) {
        auto it = mVendorParamIndices.find(entry.first);
        if (it == mVendorParamIndices.end()) {
    for (const auto &[key, value] : reflected) {
        auto it = mVendorParams.find(key);
        if (it == mVendorParams.end()) {
            continue;
        }
        if (mSubscribedIndices.count(it->second) == 0) {
        C2Param::Index index = it->second->index();
        if (mSubscribedIndices.count(index) == 0) {
            continue;
        }
        // For vendor parameters, we only care about direction
        if ((input && !it->second.forInput())
                || (!input && !it->second.forOutput())) {
        if ((input && !index.forInput())
                || (!input && !index.forOutput())) {
            continue;
        }
        const ReflectedParamUpdater::Value &value = entry.second;
        C2Value c2Value;
        sp<ABuffer> bufValue;
        AString strValue;
@@ -1249,10 +1256,10 @@ sp<AMessage> CCodecConfig::getFormatForDomain(
        } else if (value.find(&strValue)) {
            item.set(strValue);
        } else {
            ALOGD("unexpected untyped query value for key: %s", entry.first.c_str());
            ALOGD("unexpected untyped query value for key: %s", key.c_str());
            continue;
        }
        msg->setItem(entry.first.c_str(), item);
        msg->setItem(key.c_str(), item);
    }

    { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
@@ -1356,7 +1363,6 @@ sp<AMessage> CCodecConfig::getFormatForDomain(
            msg->removeEntryAt(msg->findEntryByName("color-matrix"));
        }


        // calculate dataspace for raw graphic buffers if not specified by component, or if
        // using surface with unspecified aspects (as those must be defaulted which may change
        // the dataspace)
@@ -1394,6 +1400,23 @@ sp<AMessage> CCodecConfig::getFormatForDomain(
            }
        }

        if (mInputSurface) {
            android_dataspace dataspace = mInputSurface->getDataspace();
            ColorUtils::convertDataSpaceToV0(dataspace);
            int32_t standard;
            ColorUtils::getColorConfigFromDataSpace(dataspace, &range, &standard, &transfer);
            if (range != 0) {
                msg->setInt32(KEY_COLOR_RANGE, range);
            }
            if (standard != 0) {
                msg->setInt32(KEY_COLOR_STANDARD, standard);
            }
            if (transfer != 0) {
                msg->setInt32(KEY_COLOR_TRANSFER, transfer);
            }
            msg->setInt32("android._dataspace", dataspace);
        }

        // HDR static info

        C2HdrStaticMetadataStruct hdr;
@@ -1811,8 +1834,81 @@ const C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const
status_t CCodecConfig::subscribeToAllVendorParams(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        c2_blocking_t blocking) {
    for (const std::pair<std::string, C2Param::Index> &entry : mVendorParamIndices) {
        mSubscribedIndices.insert(entry.second);
    for (const auto &[path, desc] : mVendorParams) {
        mSubscribedIndices.insert(desc->index());
    }
    return subscribeToConfigUpdate(configurable, {}, blocking);
}

status_t CCodecConfig::querySupportedParameters(std::vector<std::string> *names) {
    if (!names) {
        return BAD_VALUE;
    }
    names->clear();
    // TODO: expand to standard params
    for (const auto &[key, desc] : mVendorParams) {
        names->push_back(key);
    }
    return OK;
}

status_t CCodecConfig::describe(const std::string &name, CodecParameterDescriptor *desc) {
    if (!desc) {
        return BAD_VALUE;
    }
    // TODO: expand to standard params
    desc->name = name;
    switch (mParamUpdater->getTypeForKey(name)) {
        case C2FieldDescriptor::INT32:
        case C2FieldDescriptor::UINT32:
        case C2FieldDescriptor::CNTR32:
            desc->type = AMessage::kTypeInt32;
            return OK;
        case C2FieldDescriptor::INT64:
        case C2FieldDescriptor::UINT64:
        case C2FieldDescriptor::CNTR64:
            desc->type = AMessage::kTypeInt64;
            return OK;
        case C2FieldDescriptor::FLOAT:
            desc->type = AMessage::kTypeFloat;
            return OK;
        case C2FieldDescriptor::STRING:
            desc->type = AMessage::kTypeString;
            return OK;
        case C2FieldDescriptor::BLOB:
            desc->type = AMessage::kTypeBuffer;
            return OK;
        default:
            return NAME_NOT_FOUND;
    }
}

status_t CCodecConfig::subscribeToVendorConfigUpdate(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        const std::vector<std::string> &names,
        c2_blocking_t blocking) {
    for (const std::string &name : names) {
        auto it = mVendorParams.find(name);
        if (it == mVendorParams.end()) {
            ALOGD("%s is not a recognized vendor parameter; ignored.", name.c_str());
            continue;
        }
        mSubscribedIndices.insert(it->second->index());
    }
    return subscribeToConfigUpdate(configurable, {}, blocking);
}

status_t CCodecConfig::unsubscribeFromVendorConfigUpdate(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        const std::vector<std::string> &names,
        c2_blocking_t blocking) {
    for (const std::string &name : names) {
        auto it = mVendorParams.find(name);
        if (it == mVendorParams.end()) {
            ALOGD("%s is not a recognized vendor parameter; ignored.", name.c_str());
            continue;
        }
        mSubscribedIndices.erase(it->second->index());
    }
    return subscribeToConfigUpdate(configurable, {}, blocking);
}
Loading