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

Commit b63d314d authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "MediaCodec: add methods to query/subscribe vendor parameters"

parents f787fd49 874ad38f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -1965,6 +1965,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);
+91 −17
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);
            }
        }
    }
@@ -1199,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) {
@@ -1224,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;
@@ -1255,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
@@ -1833,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);
}
+38 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
namespace android {

struct AMessage;
struct CodecParameterDescriptor;
class NativeHandle;
struct StandardParams;

@@ -138,8 +139,8 @@ struct CCodecConfig {
    /// For now support a validation function.
    std::map<C2Param::Index, LocalParamValidator> mLocalParams;

    /// Vendor field name -> index map.
    std::map<std::string, C2Param::Index> mVendorParamIndices;
    /// Vendor field name -> desc map.
    std::map<std::string, std::shared_ptr<C2ParamDescriptor>> mVendorParams;

    std::set<std::string> mLastConfig;

@@ -327,6 +328,41 @@ struct CCodecConfig {
        return Watcher<T>(index, this);
    }

    /**
     * Queries supported parameters and put the keys to |names|.
     * TODO: currently this method queries vendor parameter keys only.
     *
     * \return OK if successful.
     *         BAD_VALUE if |names| is nullptr.
     */
    status_t querySupportedParameters(std::vector<std::string> *names);

    /**
     * Describe the parameter with |name|, filling the information into |desc|
     * TODO: currently this method works only for vendor parameters.
     *
     * \return OK if successful.
     *         BAD_VALUE if |desc| is nullptr.
     *         NAME_NOT_FOUND if |name| is not a recognized parameter name.
     */
    status_t describe(const std::string &name, CodecParameterDescriptor *desc);

    /**
     * Find corresponding indices for |names| and subscribe to them.
     */
    status_t subscribeToVendorConfigUpdate(
            const std::shared_ptr<Codec2Client::Configurable> &configurable,
            const std::vector<std::string> &names,
            c2_blocking_t blocking = C2_DONT_BLOCK);

    /**
     * Find corresponding indices for |names| and unsubscribe from them.
     */
    status_t unsubscribeFromVendorConfigUpdate(
            const std::shared_ptr<Codec2Client::Configurable> &configurable,
            const std::vector<std::string> &names,
            c2_blocking_t blocking = C2_DONT_BLOCK);

private:

    /// initializes the standard MediaCodec to Codec 2.0 params mapping
+14 −0
Original line number Diff line number Diff line
@@ -288,6 +288,20 @@ void ReflectedParamUpdater::getKeysForParamIndex(
    }
}

C2FieldDescriptor::type_t ReflectedParamUpdater::getTypeForKey(
        const std::string &key) const {
    auto it = mMap.find(key);
    if (it == mMap.end()) {
        return C2FieldDescriptor::type_t(~0);
    }

    if (it->second.fieldDesc) {
        return it->second.fieldDesc->type();
    }
    // whole param is exposed as a blob
    return C2FieldDescriptor::BLOB;
}

void ReflectedParamUpdater::updateParamsFromMessage(
        const Dict &params,
        std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const {
+8 −0
Original line number Diff line number Diff line
@@ -175,6 +175,14 @@ public:
            const C2Param::Index &index,
            std::vector<std::string> *keys /* nonnull */) const;

    /**
     * Get field type for the given name
     *
     * \param key[in]   field name
     * \return type of the field, or type_t(~0) if not found.
     */
    C2FieldDescriptor::type_t getTypeForKey(const std::string &name) const;

    /**
     * Update C2Param objects from field name and value in AMessage object.
     *
Loading