/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "CCodecConfig"

#include <initializer_list>

#include <cutils/properties.h>
#include <log/log.h>
#include <utils/NativeHandle.h>

#include <android-base/properties.h>

#include <C2Component.h>
#include <C2Param.h>
#include <util/C2InterfaceHelper.h>

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

#include "CCodecConfig.h"
#include "Codec2Mapper.h"

#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0   /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
#define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS -1 /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
// names of properties that can be used to override the default DRC settings
#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
#define PROP_DRC_OVERRIDE_ENC_LEVEL  "aac_drc_enc_target_level"
#define PROP_DRC_OVERRIDE_EFFECT     "ro.aac_drc_effect_type"

namespace android {

// CCodecConfig

namespace {

void C2ValueToMessageItem(const C2Value &value, AMessage::ItemData &item) {
    int32_t int32Value;
    uint32_t uint32Value;
    int64_t int64Value;
    uint64_t uint64Value;
    float floatValue;
    if (value.get(&int32Value)) {
        item.set(int32Value);
    } else if (value.get(&uint32Value) && uint32Value <= uint32_t(INT32_MAX)) {
        // SDK does not support unsigned values
        item.set((int32_t)uint32Value);
    } else if (value.get(&int64Value)) {
        item.set(int64Value);
    } else if (value.get(&uint64Value) && uint64Value <= uint64_t(INT64_MAX)) {
        // SDK does not support unsigned values
        item.set((int64_t)uint64Value);
    } else if (value.get(&floatValue)) {
        item.set(floatValue);
    }
}

/**
 * mapping between SDK and Codec 2.0 configurations.
 */
struct ConfigMapper {
    /**
     * Value mapper (C2Value => C2Value)
     */
    typedef std::function<C2Value(C2Value)> Mapper;

    /// shorthand
    typedef CCodecConfig::Domain Domain;

    ConfigMapper(std::string mediaKey, C2String c2struct, C2String c2field)
        : mDomain(Domain::ALL), mMediaKey(mediaKey), mStruct(c2struct), mField(c2field) { }

    /// Limits this parameter to the given domain
    ConfigMapper &limitTo(uint32_t domain) {
        C2_CHECK(domain & Domain::GUARD_BIT);
        mDomain = Domain(mDomain & domain);
        return *this;
    }

    /// Adds SDK => Codec 2.0 mapper (should not be in the SDK format)
    ConfigMapper &withMapper(Mapper mapper) {
        C2_CHECK(!mMapper);
        C2_CHECK(!mReverse);
        mMapper = mapper;
        return *this;
    }

    /// Adds SDK <=> Codec 2.0 value mappers
    ConfigMapper &withMappers(Mapper mapper, Mapper reverse) {
        C2_CHECK(!mMapper);
        C2_CHECK(!mReverse);
        mMapper = mapper;
        mReverse = reverse;
        return *this;
    }

    /// Adds SDK <=> Codec 2.0 value mappers based on C2Mapper
    template<typename C2Type, typename SdkType=int32_t>
    ConfigMapper &withC2Mappers() {
        C2_CHECK(!mMapper);
        C2_CHECK(!mReverse);
        mMapper = [](C2Value v) -> C2Value {
            SdkType sdkValue;
            C2Type c2Value;
            if (v.get(&sdkValue) && C2Mapper::map(sdkValue, &c2Value)) {
                return c2Value;
            }
            return C2Value();
        };
        mReverse = [](C2Value v) -> C2Value {
            SdkType sdkValue;
            C2Type c2Value;
            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<C2Type>::type;
            if (v.get((C2ValueType*)&c2Value) && C2Mapper::map(c2Value, &sdkValue)) {
                return sdkValue;
            }
            return C2Value();
        };
        return *this;
    }

    /// Maps from SDK values in an AMessage to a suitable C2Value.
    C2Value mapFromMessage(const AMessage::ItemData &item) const {
        C2Value value;
        int32_t int32Value;
        int64_t int64Value;
        float floatValue;
        double doubleValue;
        if (item.find(&int32Value)) {
            value = int32Value;
        } else if (item.find(&int64Value)) {
            value = int64Value;
        } else if (item.find(&floatValue)) {
            value = floatValue;
        } else if (item.find(&doubleValue)) {
            value = (float)doubleValue;
        }
        if (value.type() != C2Value::NO_INIT && mMapper) {
            value = mMapper(value);
        }
        return value;
    }

    /// Maps from a C2Value to an SDK value in an AMessage.
    AMessage::ItemData mapToMessage(C2Value value) const {
        AMessage::ItemData item;
        if (value.type() != C2Value::NO_INIT && mReverse) {
            value = mReverse(value);
        }
        C2ValueToMessageItem(value, item);
        return item;
    }

    Domain domain() const { return mDomain; }
    std::string mediaKey() const { return mMediaKey; }
    std::string path() const { return mField.size() ? mStruct + '.' + mField : mStruct; }
    Mapper mapper() const { return mMapper; }
    Mapper reverse() const { return mReverse; }

private:
    Domain mDomain;         ///< parameter domain (mask) containing port, kind and config domains
    std::string mMediaKey;  ///< SDK key
    C2String mStruct;       ///< Codec 2.0 struct name
    C2String mField;        ///< Codec 2.0 field name
    Mapper mMapper;         ///< optional SDK => Codec 2.0 value mapper
    Mapper mReverse;        ///< optional Codec 2.0 => SDK value mapper
};

template <typename PORT, typename STREAM>
AString QueryMediaTypeImpl(
        const std::shared_ptr<Codec2Client::Configurable> &configurable) {
    AString mediaType;
    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2err = configurable->query(
            {}, { PORT::PARAM_TYPE, STREAM::PARAM_TYPE }, C2_DONT_BLOCK, &queried);
    if (c2err != C2_OK && queried.size() == 0) {
        ALOGD("Query media type failed => %s", asString(c2err));
    } else {
        PORT *portMediaType =
            PORT::From(queried[0].get());
        if (portMediaType) {
            mediaType = AString(
                    portMediaType->m.value,
                    strnlen(portMediaType->m.value, portMediaType->flexCount()));
        } else {
            STREAM *streamMediaType = STREAM::From(queried[0].get());
            if (streamMediaType) {
                mediaType = AString(
                        streamMediaType->m.value,
                        strnlen(streamMediaType->m.value, streamMediaType->flexCount()));
            }
        }
        ALOGD("read media type: %s", mediaType.c_str());
    }
    return mediaType;
}

AString QueryMediaType(
        bool input, const std::shared_ptr<Codec2Client::Configurable> &configurable) {
    typedef C2PortMediaTypeSetting P;
    typedef C2StreamMediaTypeSetting S;
    if (input) {
        return QueryMediaTypeImpl<P::input, S::input>(configurable);
    } else {
        return QueryMediaTypeImpl<P::output, S::output>(configurable);
    }
}

}  // namespace

/**
 * Set of standard parameters used by CCodec that are exposed to MediaCodec.
 */
struct StandardParams {
    typedef CCodecConfig::Domain Domain;

    // standard (MediaCodec) params are keyed by media format key
    typedef std::string SdkKey;

    /// used to return reference to no config mappers in getConfigMappersForSdkKey
    static const std::vector<ConfigMapper> NO_MAPPERS;

    /// Returns Codec 2.0 equivalent parameters for an SDK format key.
    const std::vector<ConfigMapper> &getConfigMappersForSdkKey(std::string key) const {
        auto it = mConfigMappers.find(key);
        if (it == mConfigMappers.end()) {
            if (mComplained.count(key) == 0) {
                ALOGD("no c2 equivalents for %s", key.c_str());
                mComplained.insert(key);
            }
            return NO_MAPPERS;
        }
        ALOGV("found %zu eqs for %s", it->second.size(), key.c_str());
        return it->second;
    }

    /**
     * Adds a SDK <=> Codec 2.0 parameter mapping. Multiple Codec 2.0 parameters may map to a
     * single SDK key, in which case they shall be ordered from least authoritative to most
     * authoritative. When constructing SDK formats, the last mapped Codec 2.0 parameter that
     * is supported by the component will determine the exposed value. (TODO: perhaps restrict this
     * by domain.)
     */
    void add(const ConfigMapper &cm) {
        auto it = mConfigMappers.find(cm.mediaKey());
        ALOGV("%c%c%c%c %c%c%c %04x %9s %s => %s",
              ((cm.domain() & Domain::IS_INPUT) ? 'I' : ' '),
              ((cm.domain() & Domain::IS_OUTPUT) ? 'O' : ' '),
              ((cm.domain() & Domain::IS_CODED) ? 'C' : ' '),
              ((cm.domain() & Domain::IS_RAW) ? 'R' : ' '),
              ((cm.domain() & Domain::IS_CONFIG) ? 'c' : ' '),
              ((cm.domain() & Domain::IS_PARAM) ? 'p' : ' '),
              ((cm.domain() & Domain::IS_READ) ? 'r' : ' '),
              cm.domain(),
              it == mConfigMappers.end() ? "adding" : "extending",
              cm.mediaKey().c_str(), cm.path().c_str());
        if (it == mConfigMappers.end()) {
            std::vector<ConfigMapper> eqs = { cm };
            mConfigMappers.emplace(cm.mediaKey(), eqs);
        } else {
            it->second.push_back(cm);
        }
    }

    // Updates or adds a mapper for a "sdkkey"
    void updateConfigMappersForKey(const SdkKey& key,
            const std::vector<ConfigMapper>& vec_cm) {
        mConfigMappers.insert_or_assign(key, vec_cm);
    }

    /**
     * Returns all paths for a specific domain.
     *
     * \param any maximum domain mask. Returned parameters must match at least one of the domains
     *            in the mask.
     * \param all minimum domain mask. Returned parameters must match all of the domains in the
     *            mask. This is restricted to the bits of the maximum mask.
     */
    std::vector<std::string> getPathsForDomain(
            Domain any, Domain all = Domain::ALL) const {
        std::vector<std::string> res;
        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))) {
                    res.push_back(cm.path());
                }
            }
        }
        return res;
    }

    /**
     * Returns SDK <=> Codec 2.0 mappings.
     *
     * TODO: replace these with better methods as this exposes the inner structure.
     */
    const std::map<SdkKey, std::vector<ConfigMapper>> getKeys() const {
        return mConfigMappers;
    }

private:
    std::map<SdkKey, std::vector<ConfigMapper>> mConfigMappers;
    mutable std::set<std::string> mComplained;
};

const std::vector<ConfigMapper> StandardParams::NO_MAPPERS;


CCodecConfig::CCodecConfig()
    : mInputFormat(new AMessage),
      mOutputFormat(new AMessage),
      mUsingSurface(false),
      mTunneled(false),
      mPushBlankBuffersOnStop(false) { }

void CCodecConfig::initializeStandardParams() {
    typedef Domain D;
    mStandardParams = std::make_shared<StandardParams>();
    std::function<void(const ConfigMapper &)> add =
        [params = mStandardParams](const ConfigMapper &cm) {
            params->add(cm);
    };
    std::function<void(const ConfigMapper &)> deprecated = add;

    // allow int32 or float SDK values and represent them as float
    ConfigMapper::Mapper makeFloat = [](C2Value v) -> C2Value {
        // convert from i32 to float
        int32_t i32Value;
        float fpValue;
        if (v.get(&i32Value)) {
            return (float)i32Value;
        } else if (v.get(&fpValue)) {
            return fpValue;
        }
        return C2Value();
    };

    ConfigMapper::Mapper negate = [](C2Value v) -> C2Value {
        int32_t value;
        if (v.get(&value)) {
            return -value;
        }
        return C2Value();
    };

    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_INPUT_MEDIA_TYPE,    "value")
        .limitTo(D::INPUT & D::READ));
    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_OUTPUT_MEDIA_TYPE,   "value")
        .limitTo(D::OUTPUT & D::READ));

    add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
        .limitTo(D::ENCODER & D::CODED));
    // Some audio decoders require bitrate information to be set
    add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
        .limitTo(D::AUDIO & D::DECODER & D::CODED));
    // we also need to put the bitrate in the max bitrate field
    add(ConfigMapper(KEY_MAX_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
        .limitTo(D::ENCODER & D::READ & D::OUTPUT));
    add(ConfigMapper(PARAMETER_KEY_VIDEO_BITRATE, C2_PARAMKEY_BITRATE, "value")
        .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
    add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
        .limitTo(D::ENCODER & D::CODED)
        .withC2Mappers<C2Config::bitrate_mode_t>());
    // remove when codecs switch to PARAMKEY and new modes
    deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
               .limitTo(D::ENCODER));
    add(ConfigMapper(KEY_FRAME_RATE, C2_PARAMKEY_FRAME_RATE, "value")
        .limitTo(D::VIDEO)
        .withMappers(makeFloat, [](C2Value v) -> C2Value {
            // read back always as int
            float value;
            if (v.get(&value)) {
                return (int32_t) (value + 0.5);
            }
            return C2Value();
        }));

    add(ConfigMapper(KEY_MAX_INPUT_SIZE, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE, "value")
        .limitTo(D::INPUT));

    // remove when codecs switch to PARAMKEY
    deprecated(ConfigMapper(KEY_MAX_INPUT_SIZE, "coded.max-frame-size", "value")
               .limitTo(D::INPUT));

    // large frame params
    add(ConfigMapper(KEY_BUFFER_BATCH_MAX_OUTPUT_SIZE,
            C2_PARAMKEY_OUTPUT_LARGE_FRAME, "max-size")
        .limitTo(D::AUDIO & D::OUTPUT));
    add(ConfigMapper(KEY_BUFFER_BATCH_THRESHOLD_OUTPUT_SIZE,
            C2_PARAMKEY_OUTPUT_LARGE_FRAME, "threshold-size")
        .limitTo(D::AUDIO & D::OUTPUT));

    // Rotation
    // Note: SDK rotation is clock-wise, while C2 rotation is counter-clock-wise
    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
        .limitTo((D::VIDEO | D::IMAGE) & D::CODED)
        .withMappers(negate, negate));
    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
        .withMappers(negate, negate));

    // android 'video-scaling'
    add(ConfigMapper("android._video-scaling", C2_PARAMKEY_SURFACE_SCALING_MODE, "value")
        .limitTo(D::VIDEO & D::DECODER & D::RAW));

    // Color Aspects
    //
    // configure default for decoders
    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));

    // read back default for decoders. This is needed in case the component does not support
    // color aspects. In that case, these values get copied to color-* keys.
    // TRICKY: We read these values at raw port, since that's where we want to read these.
    add(ConfigMapper("default-color-range",     C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper("default-color-transfer",  C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("default-color-primaries", C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ));
    add(ConfigMapper("default-color-matrix",    C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ));

    // read back final for decoder output (also, configure final aspects as well. This should be
    // overwritten based on coded/default values if component supports color aspects, but is used
    // as final values if component does not support aspects at all)
    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::READ));

    // configure transfer request
    add(ConfigMapper("color-transfer-request", C2_PARAMKEY_COLOR_ASPECTS, "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW & D::CONFIG)
        .withC2Mappers<C2Color::transfer_t>());

    // configure source aspects for encoders and read them back on the coded(!) port.
    // This is to ensure muxing the desired aspects into the container.
    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));

    // read back coded aspects for encoders (on the raw port), but also configure
    // desired aspects here.
    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_VUI_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_VUI_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_VUI_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_VUI_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));

    // Dataspace
    add(ConfigMapper("android._dataspace", C2_PARAMKEY_DATA_SPACE, "value")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));

    // HDR
    add(ConfigMapper("smpte2086.red.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.x")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.red.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.y")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.green.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.x")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.green.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.y")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.blue.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.x")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.blue.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.y")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.white.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.x")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.white.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.y")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.max-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.max-luminance")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("smpte2086.min-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.min-luminance")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("cta861.max-cll", C2_PARAMKEY_HDR_STATIC_INFO, "max-cll")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper("cta861.max-fall", C2_PARAMKEY_HDR_STATIC_INFO, "max-fall")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));

    add(ConfigMapper(C2_PARAMKEY_HDR_FORMAT, C2_PARAMKEY_HDR_FORMAT, "value")
        .limitTo((D::VIDEO | D::IMAGE) & D::CODED & D::CONFIG));

    add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
                     C2_PARAMKEY_SECURE_MODE, "value"));

    add(ConfigMapper(KEY_PREPEND_HEADER_TO_SYNC_FRAMES,
                     C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
        .limitTo(D::ENCODER & D::VIDEO)
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value)) {
                return value ? C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC)
                             : C2Value(C2Config::PREPEND_HEADER_TO_NONE);
            }
            return C2Value();
        }, [](C2Value v) -> C2Value {
            C2Config::prepend_header_mode_t value;
            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
            if (v.get((C2ValueType *)&value)) {
                switch (value) {
                    case C2Config::PREPEND_HEADER_TO_NONE:      return 0;
                    case C2Config::PREPEND_HEADER_TO_ALL_SYNC:  return 1;
                    case C2Config::PREPEND_HEADER_ON_CHANGE:    [[fallthrough]];
                    default:                                    return C2Value();
                }
            }
            return C2Value();
        }));
    // remove when codecs switch to PARAMKEY
    deprecated(ConfigMapper(KEY_PREPEND_HEADER_TO_SYNC_FRAMES,
                            "coding.add-csd-to-sync-frames", "value")
               .limitTo(D::ENCODER & D::VIDEO));
    // convert to timestamp base
    add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
        .limitTo(D::VIDEO & D::ENCODER & D::CONFIG)
        .withMapper([](C2Value v) -> C2Value {
            // convert from i32 to float
            int32_t i32Value;
            float fpValue;
            if (v.get(&i32Value)) {
                return int64_t(1000000) * i32Value;
            } else if (v.get(&fpValue)) {
                return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
            }
            return C2Value();
        }));
    // remove when codecs switch to proper coding.gop (add support for calculating gop)
    deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
               .limitTo(D::ENCODER & D::VIDEO));
    add(ConfigMapper(KEY_INTRA_REFRESH_PERIOD, C2_PARAMKEY_INTRA_REFRESH, "period")
        .limitTo(D::VIDEO & D::ENCODER)
        .withMappers(makeFloat, [](C2Value v) -> C2Value {
            // read back always as int
            float value;
            if (v.get(&value)) {
                return (int32_t)value;
            }
            return C2Value();
        }));
    deprecated(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
                     "coding.request-sync", "value")
        .limitTo(D::PARAM & D::ENCODER)
        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
    add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
                     C2_PARAMKEY_REQUEST_SYNC_FRAME, "value")
        .limitTo(D::PARAM & D::ENCODER)
        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));

    add(ConfigMapper(KEY_OPERATING_RATE,   C2_PARAMKEY_OPERATING_RATE,     "value")
        .limitTo(D::PARAM | D::CONFIG) // write-only
        .withMapper(makeFloat));
    // C2 priorities are inverted
    add(ConfigMapper(KEY_PRIORITY,         C2_PARAMKEY_PRIORITY,           "value")
        .withMappers(negate, negate));
    // remove when codecs switch to PARAMKEY
    deprecated(ConfigMapper(KEY_OPERATING_RATE,   "ctrl.operating-rate",     "value")
               .withMapper(makeFloat));
    deprecated(ConfigMapper(KEY_PRIORITY,         "ctrl.priority",           "value"));

    add(ConfigMapper(KEY_WIDTH,         C2_PARAMKEY_PICTURE_SIZE,       "width")
        .limitTo(D::VIDEO | D::IMAGE));
    add(ConfigMapper(KEY_HEIGHT,        C2_PARAMKEY_PICTURE_SIZE,       "height")
        .limitTo(D::VIDEO | D::IMAGE));

    add(ConfigMapper("crop-left",       C2_PARAMKEY_CROP_RECT,       "left")
        .limitTo(D::VIDEO | D::IMAGE));
    add(ConfigMapper("crop-top",        C2_PARAMKEY_CROP_RECT,       "top")
        .limitTo(D::VIDEO | D::IMAGE));
    add(ConfigMapper("crop-width",      C2_PARAMKEY_CROP_RECT,       "width")
        .limitTo(D::VIDEO | D::IMAGE));
    add(ConfigMapper("crop-height",     C2_PARAMKEY_CROP_RECT,       "height")
        .limitTo(D::VIDEO | D::IMAGE));

    add(ConfigMapper(KEY_MAX_WIDTH,     C2_PARAMKEY_MAX_PICTURE_SIZE,    "width")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper(KEY_MAX_HEIGHT,    C2_PARAMKEY_MAX_PICTURE_SIZE,    "height")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));

    add(ConfigMapper("csd-0",           C2_PARAMKEY_INIT_DATA,       "value")
        .limitTo(D::OUTPUT & D::READ));

    deprecated(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO, "value")
        .limitTo(D::VIDEO & D::PARAM & D::INPUT & (D::CONFIG | D::PARAM)));

    deprecated(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO, "value")
        .limitTo(D::VIDEO & D::OUTPUT & D::READ));

    add(ConfigMapper(
            std::string(C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO) + ".type",
            C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO, "type")
        .limitTo(D::VIDEO & D::PARAM & D::INPUT & (D::CONFIG | D::PARAM)));

    add(ConfigMapper(
            std::string(C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO) + ".data",
            C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO, "data")
        .limitTo(D::VIDEO & D::PARAM & D::INPUT & (D::CONFIG | D::PARAM)));

    add(ConfigMapper(
            std::string(C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO) + ".type",
            C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO, "type")
        .limitTo(D::VIDEO & D::OUTPUT & D::READ));

    add(ConfigMapper(
            std::string(C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO) + ".data",
            C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO, "data")
        .limitTo(D::VIDEO & D::OUTPUT & D::READ));

    add(ConfigMapper(C2_PARAMKEY_TEMPORAL_LAYERING, C2_PARAMKEY_TEMPORAL_LAYERING, "")
        .limitTo(D::ENCODER & D::VIDEO & D::OUTPUT));

    // Pixel Format (use local key for actual pixel format as we don't distinguish between
    // SDK layouts for flexible format and we need the actual SDK color format in the media format)
    add(ConfigMapper("android._color-format",  C2_PARAMKEY_PIXEL_FORMAT, "value")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value)) {
                uint32_t result;
                if (C2Mapper::mapPixelFormatFrameworkToCodec(value, &result)) {
                    return result;
                }
            }
            return C2Value();
        }, [](C2Value v) -> C2Value {
            uint32_t value;
            if (v.get(&value)) {
                int32_t result;
                if (C2Mapper::mapPixelFormatCodecToFramework(value, &result)) {
                    return result;
                }
            }
            return C2Value();
        }));

    add(ConfigMapper(KEY_PIXEL_ASPECT_RATIO_WIDTH,  C2_PARAMKEY_PIXEL_ASPECT_RATIO, "width")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
    add(ConfigMapper(KEY_PIXEL_ASPECT_RATIO_HEIGHT, C2_PARAMKEY_PIXEL_ASPECT_RATIO, "height")
        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));

    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CHANNEL_COUNT,       "value")
        .limitTo(D::AUDIO)); // read back to both formats
    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CODED_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO & D::CODED));

    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_SAMPLE_RATE,        "value")
        .limitTo(D::AUDIO)); // read back to both port formats
    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_CODED_SAMPLE_RATE,  "value")
        .limitTo(D::AUDIO & D::CODED));

    auto pcmEncodingMapper = [](C2Value v) -> C2Value {
        int32_t value;
        C2Config::pcm_encoding_t to;
        if (v.get(&value) && C2Mapper::map(value, &to)) {
            return to;
        }
        return C2Value();
    };
    auto pcmEncodingReverse = [](C2Value v) -> C2Value {
        C2Config::pcm_encoding_t value;
        int32_t to;
        using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
        if (v.get((C2ValueType*)&value) && C2Mapper::map(value, &to)) {
            return to;
        }
        return C2Value();
    };
    add(ConfigMapper(KEY_PCM_ENCODING,              C2_PARAMKEY_PCM_ENCODING, "value")
        .limitTo(D::AUDIO)
        .withMappers(pcmEncodingMapper, pcmEncodingReverse));
    add(ConfigMapper("android._codec-pcm-encoding", C2_PARAMKEY_PCM_ENCODING, "value")
        .limitTo(D::AUDIO & D::READ)
        .withMappers(pcmEncodingMapper, pcmEncodingReverse));

    add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
        .limitTo(D::AUDIO & D::CODED)
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value) && value) {
                return C2Config::AAC_PACKAGING_ADTS;
            }
            return C2Value();
        }, [](C2Value v) -> C2Value {
            uint32_t value;
            if (v.get(&value) && value == C2Config::AAC_PACKAGING_ADTS) {
                return (int32_t)1;
            }
            return C2Value();
        }));

    std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
        C2Mapper::GetProfileLevelMapper(mCodingMediaType);

    add(ConfigMapper(KEY_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
        .limitTo(D::CODED)
        .withMappers([mapper](C2Value v) -> C2Value {
            C2Config::profile_t c2 = PROFILE_UNUSED;
            int32_t sdk;
            if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
                return c2;
            }
            return PROFILE_UNUSED;
        }, [mapper](C2Value v) -> C2Value {
            C2Config::profile_t c2;
            int32_t sdk;
            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapProfile(c2, &sdk)) {
                return sdk;
            }
            return C2Value();
        }));

    add(ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
        .limitTo(D::CODED)
        .withMappers([mapper](C2Value v) -> C2Value {
            C2Config::level_t c2 = LEVEL_UNUSED;
            int32_t sdk;
            if (mapper && v.get(&sdk) && mapper->mapLevel(sdk, &c2)) {
                return c2;
            }
            return LEVEL_UNUSED;
        }, [mapper](C2Value v) -> C2Value {
            C2Config::level_t c2;
            int32_t sdk;
            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapLevel(c2, &sdk)) {
                return sdk;
            }
            return C2Value();
        }));

    add(ConfigMapper(KEY_AAC_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
        .limitTo(D::AUDIO & D::ENCODER & (D::CONFIG | D::PARAM))
        .withMapper([mapper](C2Value v) -> C2Value {
            C2Config::profile_t c2 = PROFILE_UNUSED;
            int32_t sdk;
            if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
                return c2;
            }
            return PROFILE_UNUSED;
        }));

    // convert to dBFS and add default
    add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < -1) {
                value = property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
            }
            return float(-0.25 * c2_min(value, 127));
        },[](C2Value v) -> C2Value {
            float value;
            if (v.get(&value)) {
                return (int32_t) (-4. * value);
            }
            return C2Value();
        }));

    // convert to 0-1 (%) and add default
    add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                value = property_get_int32(PROP_DRC_OVERRIDE_CUT, DRC_DEFAULT_MOBILE_DRC_CUT);
            }
            return float(c2_min(value, 127) / 127.);
        },[](C2Value v) -> C2Value {
            float value;
            if (v.get(&value)) {
              return (int32_t) (value * 127. + 0.5);
            }
            else {
              return C2Value();
            }
        }));

    // convert to 0-1 (%) and add default
    add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                value = property_get_int32(PROP_DRC_OVERRIDE_BOOST, DRC_DEFAULT_MOBILE_DRC_BOOST);
            }
            return float(c2_min(value, 127) / 127.);
        },[](C2Value v) -> C2Value {
            float value;
            if (v.get(&value)) {
              return (int32_t) (value * 127. + 0.5);
            }
            else {
              return C2Value();
            }
        }));

    // convert to compression type and add default
    add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM))
        .withMapper([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                value = property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
            }
            return value == 1 ? C2Config::DRC_COMPRESSION_HEAVY : C2Config::DRC_COMPRESSION_LIGHT;
        }));

    // convert to dBFS and add default
    add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                value = property_get_int32(PROP_DRC_OVERRIDE_ENC_LEVEL, DRC_DEFAULT_MOBILE_ENC_LEVEL);
            }
            return float(-0.25 * c2_min(value, 127));
        },[](C2Value v) -> C2Value {
            float value;
            if (v.get(&value)) {
              return (int32_t) (-4. * value);
            }
            else {
              return C2Value();
            }
        }));

    // convert to effect type (these map to SDK values) and add default
    add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < -1 || value > 8) {
                value = property_get_int32(PROP_DRC_OVERRIDE_EFFECT, DRC_DEFAULT_MOBILE_DRC_EFFECT);
                // ensure value is within range
                if (value < -1 || value > 8) {
                    value = DRC_DEFAULT_MOBILE_DRC_EFFECT;
                }
            }
            return value;
        },[](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value)) {
              return  value;
            }
            else {
              return C2Value();
            }
        }));

    // convert to album mode and add default
    add(ConfigMapper(KEY_AAC_DRC_ALBUM_MODE, C2_PARAMKEY_DRC_ALBUM_MODE, "value")
        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0 || value > 1) {
                value = DRC_DEFAULT_MOBILE_DRC_ALBUM;
                // ensure value is within range
                if (value < 0 || value > 1) {
                    value = DRC_DEFAULT_MOBILE_DRC_ALBUM;
                }
            }
            return value;
        },[](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value)) {
              return value;
            }
            else {
              return C2Value();
            }
        }));

    add(ConfigMapper(KEY_AAC_DRC_OUTPUT_LOUDNESS, C2_PARAMKEY_DRC_OUTPUT_LOUDNESS, "value")
        .limitTo(D::OUTPUT & D::DECODER & D::READ)
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < -1) {
                value = DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS;
            }
            return float(-0.25 * c2_min(value, 127));
        },[](C2Value v) -> C2Value {
            float value;
            if (v.get(&value)) {
                return (int32_t) (-4. * value);
            }
            return C2Value();
        }));

    add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO & (D::CONFIG | D::PARAM | D::READ)));

    add(ConfigMapper(KEY_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO & (D::CONFIG | D::PARAM | D::READ)));

    add(ConfigMapper(KEY_CHANNEL_MASK, C2_PARAMKEY_CHANNEL_MASK, "value")
        .limitTo(D::AUDIO & D::DECODER & D::READ));

    add(ConfigMapper(KEY_CHANNEL_MASK, C2_PARAMKEY_CHANNEL_MASK, "value")
        .limitTo(D::AUDIO & D::ENCODER & D::CONFIG));

    add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
        .limitTo(D::AUDIO & D::ENCODER & (D::CONFIG | D::PARAM | D::READ))
        .withMapper([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                return C2Config::AAC_SBR_AUTO;
            }
            switch (value) {
                case 0: return C2Config::AAC_SBR_OFF;
                case 1: return C2Config::AAC_SBR_SINGLE_RATE;
                case 2: return C2Config::AAC_SBR_DUAL_RATE;
                default: return C2Config::AAC_SBR_AUTO + 1; // invalid value
            }
        }));

    add(ConfigMapper("android._encoding-quality-level", C2_PARAMKEY_ENCODING_QUALITY_LEVEL, "value")
        .limitTo(D::ENCODER & (D::CONFIG | D::PARAM)));
    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value")
        .limitTo(D::ENCODER & (D::CONFIG | D::PARAM)));
    add(ConfigMapper(KEY_FLAC_COMPRESSION_LEVEL, C2_PARAMKEY_COMPLEXITY, "value")
        .limitTo(D::AUDIO & D::ENCODER));
    add(ConfigMapper(KEY_COMPLEXITY, C2_PARAMKEY_COMPLEXITY, "value")
        .limitTo(D::ENCODER & (D::CONFIG | D::PARAM)));

    add(ConfigMapper(KEY_GRID_COLUMNS, C2_PARAMKEY_TILE_LAYOUT, "columns")
        .limitTo(D::IMAGE));
    add(ConfigMapper(KEY_GRID_ROWS, C2_PARAMKEY_TILE_LAYOUT, "rows")
        .limitTo(D::IMAGE));
    add(ConfigMapper(KEY_TILE_WIDTH, C2_PARAMKEY_TILE_LAYOUT, "tile.width")
        .limitTo(D::IMAGE));
    add(ConfigMapper(KEY_TILE_HEIGHT, C2_PARAMKEY_TILE_LAYOUT, "tile.height")
        .limitTo(D::IMAGE));

    add(ConfigMapper(KEY_LATENCY, C2_PARAMKEY_PIPELINE_DELAY_REQUEST, "value")
        .limitTo(D::VIDEO & D::ENCODER));

    add(ConfigMapper(C2_PARAMKEY_INPUT_TIME_STRETCH, C2_PARAMKEY_INPUT_TIME_STRETCH, "value"));

    add(ConfigMapper(KEY_LOW_LATENCY, C2_PARAMKEY_LOW_LATENCY_MODE, "value")
        .limitTo(D::DECODER & (D::CONFIG | D::PARAM))
        .withMapper([](C2Value v) -> C2Value {
            int32_t value = 0;
            (void)v.get(&value);
            return value == 0 ? C2_FALSE : C2_TRUE;
        }));

    add(ConfigMapper("android._trigger-tunnel-peek", C2_PARAMKEY_TUNNEL_START_RENDER, "value")
        .limitTo(D::PARAM & D::VIDEO & D::DECODER)
        .withMapper([](C2Value v) -> C2Value {
            int32_t value = 0;
            (void)v.get(&value);
            return value == 0 ? C2_FALSE : C2_TRUE;
        }));

    add(ConfigMapper("android._tunnel-peek-set-legacy", C2_PARAMKEY_TUNNEL_PEEK_MODE, "value")
        .limitTo(D::PARAM & D::VIDEO & D::DECODER)
        .withMapper([](C2Value v) -> C2Value {
          int32_t value = 0;
          (void)v.get(&value);
          return value == 0
              ? C2Value(C2PlatformConfig::SPECIFIED_PEEK)
              : C2Value(C2PlatformConfig::UNSPECIFIED_PEEK);
        }));

    add(ConfigMapper(KEY_VIDEO_QP_AVERAGE, C2_PARAMKEY_AVERAGE_QP, "value")
        .limitTo(D::ENCODER & D::VIDEO & D::READ));

    add(ConfigMapper(KEY_PICTURE_TYPE, C2_PARAMKEY_PICTURE_TYPE, "value")
        .limitTo(D::ENCODER & D::VIDEO & D::READ)
        .withMappers([](C2Value v) -> C2Value {
            int32_t sdk;
            C2Config::picture_type_t c2;
            if (v.get(&sdk) && C2Mapper::map(sdk, &c2)) {
                return C2Value(c2);
            }
            return C2Value();
        }, [](C2Value v) -> C2Value {
            C2Config::picture_type_t c2;
            int32_t sdk = PICTURE_TYPE_UNKNOWN;
            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
            if (v.get((C2ValueType*)&c2) && C2Mapper::map(c2, &sdk)) {
                return sdk;
            }
            return C2Value();
        }));

    /* still to do
       not yet used by MediaCodec, but defined as MediaFormat
    KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
    KEY_OUTPUT_REORDER_DEPTH
    */
}

status_t CCodecConfig::initialize(
        const std::shared_ptr<C2ParamReflector> &reflector,
        const std::shared_ptr<Codec2Client::Configurable> &configurable) {
    C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
    C2ComponentKindSetting kind(C2Component::KIND_OTHER);

    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2err = configurable->query({ &domain, &kind }, {}, C2_DONT_BLOCK, &queried);
    if (c2err != C2_OK) {
        ALOGD("Query domain & kind failed => %s", asString(c2err));
        // TEMP: determine kind from component name
        if (kind.value == C2Component::KIND_OTHER) {
            if (configurable->getName().find("encoder") != std::string::npos) {
                kind.value = C2Component::KIND_ENCODER;
            } else if (configurable->getName().find("decoder") != std::string::npos) {
                kind.value = C2Component::KIND_DECODER;
            }
        }

        // TEMP: determine domain from media type (port (preferred) or stream #0)
        if (domain.value == C2Component::DOMAIN_OTHER) {
            AString mediaType = QueryMediaType(true /* input */, configurable);
            if (mediaType.startsWith("audio/")) {
                domain.value = C2Component::DOMAIN_AUDIO;
            } else if (mediaType.startsWith("video/")) {
                domain.value = C2Component::DOMAIN_VIDEO;
            } else if (mediaType.startsWith("image/")) {
                domain.value = C2Component::DOMAIN_IMAGE;
            }
        }
    }

    mDomain = (domain.value == C2Component::DOMAIN_VIDEO ? Domain::IS_VIDEO :
               domain.value == C2Component::DOMAIN_IMAGE ? Domain::IS_IMAGE :
               domain.value == C2Component::DOMAIN_AUDIO ? Domain::IS_AUDIO : Domain::OTHER_DOMAIN)
            | (kind.value == C2Component::KIND_DECODER ? Domain::IS_DECODER :
               kind.value == C2Component::KIND_ENCODER ? Domain::IS_ENCODER : Domain::OTHER_KIND);

    mInputDomain = Domain(((mDomain & IS_DECODER) ? IS_CODED : IS_RAW) | IS_INPUT);
    mOutputDomain = Domain(((mDomain & IS_ENCODER) ? IS_CODED : IS_RAW) | IS_OUTPUT);

    ALOGV("domain is %#x (%u %u)", mDomain, domain.value, kind.value);

    std::vector<C2Param::Index> paramIndices;
    switch (kind.value) {
    case C2Component::KIND_DECODER:
        mCodingMediaType = QueryMediaType(true /* input */, configurable).c_str();
        break;
    case C2Component::KIND_ENCODER:
        mCodingMediaType = QueryMediaType(false /* input */, configurable).c_str();
        break;
    default:
        mCodingMediaType = "";
    }

    c2err = configurable->querySupportedParams(&mParamDescs);
    if (c2err != C2_OK) {
        ALOGD("Query supported params failed after returning %zu values => %s",
                mParamDescs.size(), asString(c2err));
        return UNKNOWN_ERROR;
    }
    for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
        mSupportedIndices.emplace(desc->index());
    }

    mReflector = reflector;
    if (mReflector == nullptr) {
        ALOGE("Null param reflector");
        return UNKNOWN_ERROR;
    }

    // enumerate all fields
    mParamUpdater = std::make_shared<ReflectedParamUpdater>();
    mParamUpdater->clear();
    mParamUpdater->supportWholeParam(
            C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
    mParamUpdater->addParamDesc(mReflector, mParamDescs);

    // TEMP: add some standard fields even if not reflected
    if (kind.value == C2Component::KIND_ENCODER) {
        mParamUpdater->addStandardParam<C2StreamInitDataInfo::output>(C2_PARAMKEY_INIT_DATA);
    }
    if (domain.value == C2Component::DOMAIN_IMAGE || domain.value == C2Component::DOMAIN_VIDEO) {
        if (kind.value != C2Component::KIND_ENCODER) {
            addLocalParam<C2StreamPictureSizeInfo::output>(C2_PARAMKEY_PICTURE_SIZE);
            addLocalParam<C2StreamCropRectInfo::output>(C2_PARAMKEY_CROP_RECT);
            addLocalParam(
                    new C2StreamPixelAspectRatioInfo::output(0u, 1u, 1u),
                    C2_PARAMKEY_PIXEL_ASPECT_RATIO);
            addLocalParam(new C2StreamRotationInfo::output(0u, 0), C2_PARAMKEY_ROTATION);
            addLocalParam(
                    new C2StreamColorAspectsTuning::output(0u),
                    C2_PARAMKEY_DEFAULT_COLOR_ASPECTS);
            addLocalParam<C2StreamDataSpaceInfo::output>(C2_PARAMKEY_DATA_SPACE);
            addLocalParam<C2StreamHdrStaticInfo::output>(C2_PARAMKEY_HDR_STATIC_INFO);
            addLocalParam(
                    new C2StreamSurfaceScalingInfo::output(0u, VIDEO_SCALING_MODE_SCALE_TO_FIT),
                    C2_PARAMKEY_SURFACE_SCALING_MODE);
        } else {
            addLocalParam(new C2StreamColorAspectsInfo::input(0u), C2_PARAMKEY_COLOR_ASPECTS);

            if (domain.value == C2Component::DOMAIN_VIDEO) {
                addLocalParam(new C2AndroidStreamAverageBlockQuantizationInfo::output(0u, 0),
                              C2_PARAMKEY_AVERAGE_QP);
                addLocalParam(new C2StreamPictureTypeInfo::output(0u, 0),
                              C2_PARAMKEY_PICTURE_TYPE);
            }
        }
    }

    initializeStandardParams();

    // subscribe to all supported standard (exposed) params
    // TODO: limit this to params that are actually in the domain
    std::vector<std::string> formatKeys = mStandardParams->getPathsForDomain(Domain(1 << 30));
    std::vector<C2Param::Index> indices;
    mParamUpdater->getParamIndicesForKeys(formatKeys, &indices);
    mSubscribedIndices.insert(indices.begin(), indices.end());

    // also subscribe to some non-SDK standard parameters
    // for number of input/output buffers
    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::input::PARAM_TYPE);
    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::output::PARAM_TYPE);
    mSubscribedIndices.emplace(C2ActualPipelineDelayTuning::PARAM_TYPE);
    mSubscribedIndices.emplace(C2PortActualDelayTuning::input::PARAM_TYPE);
    mSubscribedIndices.emplace(C2PortActualDelayTuning::output::PARAM_TYPE);
    // for output buffer array allocation
    mSubscribedIndices.emplace(C2StreamMaxBufferSizeInfo::output::PARAM_TYPE);
    // init data (CSD)
    mSubscribedIndices.emplace(C2StreamInitDataInfo::output::PARAM_TYPE);

    for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
        if (desc->index().isVendor()) {
            std::vector<std::string> keys;
            mParamUpdater->getKeysForParamIndex(desc->index(), &keys);
            for (const std::string &key : keys) {
                mVendorParams.insert_or_assign(key, desc);
            }
        }
    }

    // Parameters that are not subscribed initially, but can be subscribed
    // upon explicit request.
    static const std::initializer_list<C2Param::Index> kOptionalParams = {
        C2AndroidStreamAverageBlockQuantizationInfo::output::PARAM_TYPE,
        C2StreamPictureTypeInfo::output::PARAM_TYPE,
    };
    for (const C2Param::Index &index : kOptionalParams) {
        mSubscribedIndices.erase(index);
    }
    subscribeToConfigUpdate(configurable, {}, C2_MAY_BLOCK);

    return OK;
}

status_t CCodecConfig::subscribeToConfigUpdate(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        const std::vector<C2Param::Index> &indices,
        c2_blocking_t blocking) {
    static const int32_t kProductFirstApiLevel =
        base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
    static const int32_t kBoardApiLevel =
        base::GetIntProperty<int32_t>("ro.board.first_api_level", 0);
    static const int32_t kFirstApiLevel =
        (kBoardApiLevel != 0) ? kBoardApiLevel : kProductFirstApiLevel;
    mSubscribedIndices.insert(indices.begin(), indices.end());
    if (mSubscribedIndices.size() != mSubscribedIndicesSize
            && kFirstApiLevel >= __ANDROID_API_T__) {
        std::vector<uint32_t> indicesVector;
        for (C2Param::Index ix : mSubscribedIndices) {
            indicesVector.push_back(ix);
        }
        std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
            C2SubscribedParamIndicesTuning::AllocUnique(indicesVector);
        std::vector<std::unique_ptr<C2SettingResult>> results;
        c2_status_t c2Err = configurable->config({ subscribeTuning.get() }, blocking, &results);
        if (c2Err != C2_OK && c2Err != C2_BAD_INDEX) {
            ALOGD("Failed to subscribe to parameters => %s", asString(c2Err));
            // TODO: error
        }
        ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
        mSubscribedIndicesSize = mSubscribedIndices.size();
    }
#if defined(LOG_NDEBUG) && !LOG_NDEBUG
    ALOGV("subscribed to %zu params:", mSubscribedIndices.size());
    std::stringstream ss;
    for (const C2Param::Index &index : mSubscribedIndices) {
        ss << index << " ";
        if (ss.str().length() > 70) {
            ALOGV("%s", ss.str().c_str());
            std::stringstream().swap(ss);
        }
    }
    if (!ss.str().empty()) {
        ALOGV("%s", ss.str().c_str());
    }
#endif
    return OK;
}

status_t CCodecConfig::queryConfiguration(
        const std::shared_ptr<Codec2Client::Configurable> &configurable) {
    // query all subscribed parameters
    std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2Err = configurable->query({}, indices, C2_MAY_BLOCK, &queried);
    if (c2Err != OK) {
        ALOGI("query failed after returning %zu values (%s)", queried.size(), asString(c2Err));
        // TODO: error
    }

    updateConfiguration(queried, ALL);
    return OK;
}

bool CCodecConfig::updateConfiguration(
        std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain) {
    ALOGV("updating configuration with %zu params", configUpdate.size());
    bool changed = false;
    for (std::unique_ptr<C2Param> &p : configUpdate) {
        if (p && *p) {
            // Allow unsubscribed vendor parameters to go through --- it may be
            // later handled by the format shaper.
            if (!p->isVendor() && mSubscribedIndices.count(p->index()) == 0) {
                ALOGV("updateConfiguration: skipped unsubscribed param %08x", p->index());
                continue;
            }
            auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
            if (insertion.second || *insertion.first->second != *p) {
                if (mSupportedIndices.count(p->index()) || mLocalParams.count(p->index())) {
                    // only track changes in supported (reflected or local) indices
                    changed = true;
                } else {
                    ALOGV("an unlisted config was %s: %#x",
                            insertion.second ? "added" : "updated", p->index());
                }
            }
            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");
    if (changed) {
        return updateFormats(domain);
    }
    return false;
}

bool CCodecConfig::updateFormats(Domain domain) {
    // get addresses of params in the current config
    std::vector<C2Param*> paramPointers;
    for (const auto &it : mCurrentConfig) {
        paramPointers.push_back(it.second.get());
    }

    ReflectedParamUpdater::Dict reflected = mParamUpdater->getParams(paramPointers);
    std::string config = reflected.debugString();
    std::set<std::string> configLines;
    std::string diff;
    for (size_t start = 0; start != std::string::npos; ) {
        size_t end = config.find('\n', start);
        size_t count = (end == std::string::npos)
                ? std::string::npos
                : end - start + 1;
        std::string line = config.substr(start, count);
        configLines.insert(line);
        if (mLastConfig.count(line) == 0) {
            diff.append(line);
        }
        start = (end == std::string::npos) ? std::string::npos : end + 1;
    }
    if (!diff.empty()) {
        ALOGD("c2 config diff is %s", diff.c_str());
    }
    mLastConfig.swap(configLines);

    bool changed = false;
    if (domain & mInputDomain) {
        sp<AMessage> oldFormat = mInputFormat;
        mInputFormat = mInputFormat->dup(); // trigger format changed
        mInputFormat->extend(getFormatForDomain(reflected, mInputDomain));
        if (mInputFormat->countEntries() != oldFormat->countEntries()
                || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
            changed = true;
        } else {
            mInputFormat = oldFormat; // no change
        }
    }
    if (domain & mOutputDomain) {
        sp<AMessage> oldFormat = mOutputFormat;
        mOutputFormat = mOutputFormat->dup(); // trigger output format changed
        mOutputFormat->extend(getFormatForDomain(reflected, mOutputDomain));
        if (mOutputFormat->countEntries() != oldFormat->countEntries()
                || mOutputFormat->changesFrom(oldFormat)->countEntries() > 0) {
            changed = true;
        } else {
            mOutputFormat = oldFormat; // no change
        }
    }
    ALOGV_IF(changed, "format(s) changed");
    return changed;
}

sp<AMessage> CCodecConfig::getFormatForDomain(
        const ReflectedParamUpdater::Dict &reflected,
        Domain portDomain) const {
    sp<AMessage> msg = new AMessage;
    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) {
                continue;
            }
            auto it = reflected.find(cm.path());
            if (it == reflected.end()) {
                continue;
            }
            C2Value c2Value;
            sp<ABuffer> bufValue;
            AString strValue;
            AMessage::ItemData item;
            if (it->second.find(&c2Value)) {
                item = cm.mapToMessage(c2Value);
            } else if (it->second.find(&bufValue)) {
                item.set(bufValue);
            } else if (it->second.find(&strValue)) {
                item.set(strValue);
            } else {
                ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
                continue;
            }
            msg->setItem(key.c_str(), item);
        }
    }

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

    { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
        int32_t left, top, width, height;
        if (msg->findInt32("crop-left", &left) && msg->findInt32("crop-width", &width)
                && msg->findInt32("crop-top", &top) && msg->findInt32("crop-height", &height)
                && left >= 0 && width >=0 && width <= INT32_MAX - left
                && top >= 0 && height >=0 && height <= INT32_MAX - top) {
            msg->removeEntryAt(msg->findEntryByName("crop-left"));
            msg->removeEntryAt(msg->findEntryByName("crop-top"));
            msg->removeEntryAt(msg->findEntryByName("crop-width"));
            msg->removeEntryAt(msg->findEntryByName("crop-height"));
            msg->setRect("crop", left, top, left + width - 1, top + height - 1);
        } else if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
            msg->setRect("crop", 0, 0, width - 1, height - 1);
        }
    }

    { // convert temporal layering to schema
        sp<ABuffer> tmp;
        if (msg->findBuffer(C2_PARAMKEY_TEMPORAL_LAYERING, &tmp) && tmp != nullptr) {
            C2StreamTemporalLayeringTuning *layering =
                C2StreamTemporalLayeringTuning::From(C2Param::From(tmp->data(), tmp->size()));
            if (layering && layering->m.layerCount > 0
                    && layering->m.bLayerCount < layering->m.layerCount) {
                // check if this is webrtc compatible
                AString mime;
                if (msg->findString(KEY_MIME, &mime) &&
                        mime.equalsIgnoreCase(MIMETYPE_VIDEO_VP8) &&
                        layering->m.bLayerCount == 0 &&
                        (layering->m.layerCount == 1
                                || (layering->m.layerCount == 2
                                        && layering->flexCount() >= 1
                                        && layering->m.bitrateRatios[0] == .6f)
                                || (layering->m.layerCount == 3
                                        && layering->flexCount() >= 2
                                        && layering->m.bitrateRatios[0] == .4f
                                        && layering->m.bitrateRatios[1] == .6f)
                                || (layering->m.layerCount == 4
                                        && layering->flexCount() >= 3
                                        && layering->m.bitrateRatios[0] == .25f
                                        && layering->m.bitrateRatios[1] == .4f
                                        && layering->m.bitrateRatios[2] == .6f))) {
                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
                            "webrtc.vp8.%u-layer", layering->m.layerCount));
                } else if (layering->m.bLayerCount) {
                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
                            "android.generic.%u+%u",
                            layering->m.layerCount - layering->m.bLayerCount,
                            layering->m.bLayerCount));
                } else if (layering->m.bLayerCount) {
                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
                            "android.generic.%u", layering->m.layerCount));
                }
            }
            msg->removeEntryAt(msg->findEntryByName(C2_PARAMKEY_TEMPORAL_LAYERING));
        }
    }

    // Remove KEY_AAC_SBR_MODE from SDK message if it is outside supported range
    // as SDK doesn't have a way to signal default sbr mode based on profile and
    // requires that the key isn't present in format to signal that
    int sbrMode;
    if (msg->findInt32(KEY_AAC_SBR_MODE, &sbrMode) && (sbrMode < 0 || sbrMode > 2)) {
        msg->removeEntryAt(msg->findEntryByName(KEY_AAC_SBR_MODE));
    }

    { // convert color info
        // move default color to color aspect if not read from the component
        int32_t tmp;
        int32_t range;
        if (msg->findInt32("default-color-range", &range)) {
            if (!msg->findInt32(KEY_COLOR_RANGE, &tmp)) {
                msg->setInt32(KEY_COLOR_RANGE, range);
            }
            msg->removeEntryAt(msg->findEntryByName("default-color-range"));
        }
        int32_t transfer;
        if (msg->findInt32("default-color-transfer", &transfer)) {
            if (!msg->findInt32(KEY_COLOR_TRANSFER, &tmp)) {
                msg->setInt32(KEY_COLOR_TRANSFER, transfer);
            }
            msg->removeEntryAt(msg->findEntryByName("default-color-transfer"));
        }
        C2Color::primaries_t primaries;
        if (msg->findInt32("default-color-primaries", (int32_t*)&primaries)) {
            if (!msg->findInt32("color-primaries", &tmp)) {
                msg->setInt32("color-primaries", primaries);
            }
            msg->removeEntryAt(msg->findEntryByName("default-color-primaries"));
        }
        C2Color::matrix_t matrix;
        if (msg->findInt32("default-color-matrix", (int32_t*)&matrix)) {
            if (!msg->findInt32("color-matrix", &tmp)) {
                msg->setInt32("color-matrix", matrix);
            }
            msg->removeEntryAt(msg->findEntryByName("default-color-matrix"));
        }

        if (msg->findInt32("color-primaries", (int32_t*)&primaries)
                && msg->findInt32("color-matrix", (int32_t*)&matrix)) {
            int32_t standard;

            if (C2Mapper::map(primaries, matrix, &standard)) {
                msg->setInt32(KEY_COLOR_STANDARD, standard);
            }

            msg->removeEntryAt(msg->findEntryByName("color-primaries"));
            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)
        if ((portDomain & IS_RAW) && (mDomain & (IS_IMAGE | IS_VIDEO))) {
            android_dataspace dataspace;
            ColorAspects aspects = {
                ColorAspects::RangeUnspecified, ColorAspects::PrimariesUnspecified,
                ColorAspects::TransferUnspecified, ColorAspects::MatrixUnspecified
            };
            ColorUtils::getColorAspectsFromFormat(msg, aspects);
            ColorAspects origAspects = aspects;
            if (mUsingSurface) {
                // get image size (default to HD)
                int32_t width = 1280;
                int32_t height = 720;
                int32_t left, top, right, bottom;
                if (msg->findRect("crop", &left, &top, &right, &bottom)) {
                    width = right - left + 1;
                    height = bottom - top + 1;
                } else {
                    (void)msg->findInt32(KEY_WIDTH, &width);
                    (void)msg->findInt32(KEY_HEIGHT, &height);
                }
                ColorUtils::setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
                ColorUtils::setColorAspectsIntoFormat(aspects, msg);
            }

            if (!msg->findInt32("android._dataspace", (int32_t*)&dataspace)
                    || aspects.mRange != origAspects.mRange
                    || aspects.mPrimaries != origAspects.mPrimaries
                    || aspects.mTransfer != origAspects.mTransfer
                    || aspects.mMatrixCoeffs != origAspects.mMatrixCoeffs) {
                dataspace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
                msg->setInt32("android._dataspace", dataspace);
            }
        }

        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;
        if (msg->findFloat("smpte2086.red.x", &hdr.mastering.red.x)
                && msg->findFloat("smpte2086.red.y", &hdr.mastering.red.y)
                && msg->findFloat("smpte2086.green.x", &hdr.mastering.green.x)
                && msg->findFloat("smpte2086.green.y", &hdr.mastering.green.y)
                && msg->findFloat("smpte2086.blue.x", &hdr.mastering.blue.x)
                && msg->findFloat("smpte2086.blue.y", &hdr.mastering.blue.y)
                && msg->findFloat("smpte2086.white.x", &hdr.mastering.white.x)
                && msg->findFloat("smpte2086.white.y", &hdr.mastering.white.y)
                && msg->findFloat("smpte2086.max-luminance", &hdr.mastering.maxLuminance)
                && msg->findFloat("smpte2086.min-luminance", &hdr.mastering.minLuminance)
                && msg->findFloat("cta861.max-cll", &hdr.maxCll)
                && msg->findFloat("cta861.max-fall", &hdr.maxFall)) {
            if (hdr.mastering.red.x >= 0                && hdr.mastering.red.x <= 1
                    && hdr.mastering.red.y >= 0         && hdr.mastering.red.y <= 1
                    && hdr.mastering.green.x >= 0       && hdr.mastering.green.x <= 1
                    && hdr.mastering.green.y >= 0       && hdr.mastering.green.y <= 1
                    && hdr.mastering.blue.x >= 0        && hdr.mastering.blue.x <= 1
                    && hdr.mastering.blue.y >= 0        && hdr.mastering.blue.y <= 1
                    && hdr.mastering.white.x >= 0       && hdr.mastering.white.x <= 1
                    && hdr.mastering.white.y >= 0       && hdr.mastering.white.y <= 1
                    && hdr.mastering.maxLuminance >= 0  && hdr.mastering.maxLuminance <= 65535
                    && hdr.mastering.minLuminance >= 0  && hdr.mastering.minLuminance <= 6.5535
                    && hdr.maxCll >= 0                  && hdr.maxCll <= 65535
                    && hdr.maxFall >= 0                 && hdr.maxFall <= 65535) {
                HDRStaticInfo meta;
                meta.mID = meta.kType1;
                meta.sType1.mR.x = hdr.mastering.red.x / 0.00002 + 0.5;
                meta.sType1.mR.y = hdr.mastering.red.y / 0.00002 + 0.5;
                meta.sType1.mG.x = hdr.mastering.green.x / 0.00002 + 0.5;
                meta.sType1.mG.y = hdr.mastering.green.y / 0.00002 + 0.5;
                meta.sType1.mB.x = hdr.mastering.blue.x / 0.00002 + 0.5;
                meta.sType1.mB.y = hdr.mastering.blue.y / 0.00002 + 0.5;
                meta.sType1.mW.x = hdr.mastering.white.x / 0.00002 + 0.5;
                meta.sType1.mW.y = hdr.mastering.white.y / 0.00002 + 0.5;
                meta.sType1.mMaxDisplayLuminance = hdr.mastering.maxLuminance + 0.5;
                meta.sType1.mMinDisplayLuminance = hdr.mastering.minLuminance / 0.0001 + 0.5;
                meta.sType1.mMaxContentLightLevel = hdr.maxCll + 0.5;
                meta.sType1.mMaxFrameAverageLightLevel = hdr.maxFall + 0.5;
                msg->setBuffer(KEY_HDR_STATIC_INFO, ABuffer::CreateAsCopy(&meta, sizeof(meta)));
            } else {
                ALOGD("found invalid HDR static metadata %s", msg->debugString(8).c_str());
            }
            msg->removeEntryAt(msg->findEntryByName("smpte2086.red.x"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.red.y"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.green.x"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.green.y"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.x"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.y"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.white.x"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.white.y"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.max-luminance"));
            msg->removeEntryAt(msg->findEntryByName("smpte2086.min-luminance"));
            msg->removeEntryAt(msg->findEntryByName("cta861.max-cll"));
            msg->removeEntryAt(msg->findEntryByName("cta861.max-fall"));
        }

        // HDR dynamic info
        std::string keyPrefix = input ? C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO
                                      : C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO;
        std::string typeKey = keyPrefix + ".type";
        std::string dataKey = keyPrefix + ".data";
        int32_t type;
        sp<ABuffer> data;
        if (msg->findInt32(typeKey.c_str(), &type)
                && msg->findBuffer(dataKey.c_str(), &data)) {
            if (type == HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40) {
                msg->setBuffer(KEY_HDR10_PLUS_INFO, data);
                msg->removeEntryAt(msg->findEntryByName(typeKey.c_str()));
                msg->removeEntryAt(msg->findEntryByName(dataKey.c_str()));
            }
        }
    }

    ALOGV("converted to SDK values as %s", msg->debugString().c_str());
    return msg;
}

/// converts an AMessage value to a ParamUpdater value
static void convert(const AMessage::ItemData &from, ReflectedParamUpdater::Value *to) {
    int32_t int32Value;
    int64_t int64Value;
    sp<ABuffer> bufValue;
    AString strValue;
    float floatValue;
    double doubleValue;

    if (from.find(&int32Value)) {
        to->set(int32Value);
    } else if (from.find(&int64Value)) {
        to->set(int64Value);
    } else if (from.find(&bufValue)) {
        to->set(bufValue);
    } else if (from.find(&strValue)) {
        to->set(strValue);
    } else if (from.find(&floatValue)) {
        to->set(C2Value(floatValue));
    } else if (from.find(&doubleValue)) {
        // convert double to float
        to->set(C2Value((float)doubleValue));
    }
    // ignore all other AMessage types
}

/// relaxes Codec 2.0 specific value types to SDK types (mainly removes signedness and counterness
/// from 32/64-bit values.)
static void relaxValues(ReflectedParamUpdater::Value &item) {
    C2Value c2Value;
    int32_t int32Value;
    int64_t int64Value;
    (void)item.find(&c2Value);
    if (c2Value.get(&int32Value) || c2Value.get((uint32_t*)&int32Value)
            || c2Value.get((c2_cntr32_t*)&int32Value)) {
        item.set(int32Value);
    } else if (c2Value.get(&int64Value)
            || c2Value.get((uint64_t*)&int64Value)
            || c2Value.get((c2_cntr64_t*)&int64Value)) {
        item.set(int64Value);
    }
}

ReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
        const sp<AMessage> &params_, Domain configDomain) const {
    // create a modifiable copy of params
    sp<AMessage> params = params_->dup();
    ALOGV("filtering with config domain %x", configDomain);

    // convert some macro parameters to Codec 2.0 specific expressions

    { // make i-frame-interval frame based
        float iFrameInterval;
        if (params->findAsFloat(KEY_I_FRAME_INTERVAL, &iFrameInterval)) {
            float frameRate;
            if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
                params->setInt32("i-frame-period",
                        (frameRate <= 0 || iFrameInterval < 0)
                                 ? -1 /* no sync frames */
                                 : (int32_t)c2_min(iFrameInterval * frameRate + 0.5,
                                                   (float)INT32_MAX));
            }
        }
    }

    if (mDomain == (IS_VIDEO | IS_ENCODER)) {
        // convert capture-rate into input-time-stretch
        float frameRate, captureRate;
        if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
            if (!params->findAsFloat("time-lapse-fps", &captureRate)
                    && !params->findAsFloat(KEY_CAPTURE_RATE, &captureRate)) {
                captureRate = frameRate;
            }
            if (captureRate > 0 && frameRate > 0) {
                params->setFloat(C2_PARAMKEY_INPUT_TIME_STRETCH, captureRate / frameRate);
            }
        }

        // add HDR format for video encoding
        if (configDomain == IS_CONFIG) {
            // don't assume here that transfer is set for HDR, only require it for HLG
            int transfer = 0;
            params->findInt32(KEY_COLOR_TRANSFER, &transfer);

            int profile;
            if (params->findInt32(KEY_PROFILE, &profile)) {
                std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
                    C2Mapper::GetProfileLevelMapper(mCodingMediaType);
                C2Config::hdr_format_t c2 = C2Config::hdr_format_t::UNKNOWN;
                if (mapper && mapper->mapHdrFormat(profile, &c2)) {
                    if (c2 == C2Config::hdr_format_t::HLG &&
                        transfer != COLOR_TRANSFER_HLG) {
                        c2 = C2Config::hdr_format_t::UNKNOWN;
                    }
                    params->setInt32(C2_PARAMKEY_HDR_FORMAT, c2);
                }
            }
        }
    }

    {   // reflect temporal layering into a binary blob
        AString schema;
        if (params->findString(KEY_TEMPORAL_LAYERING, &schema)) {
            unsigned int numLayers = 0;
            unsigned int numBLayers = 0;
            int tags;
            char dummy;
            std::unique_ptr<C2StreamTemporalLayeringTuning::output> layering;
            if (sscanf(schema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
                && numLayers > 0) {
                switch (numLayers) {
                    case 1:
                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
                                {}, 0u, 1u, 0u);
                        break;
                    case 2:
                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
                                { .6f }, 0u, 2u, 0u);
                        break;
                    case 3:
                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
                                { .4f, .6f }, 0u, 3u, 0u);
                        break;
                    default:
                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
                                { .25f, .4f, .6f }, 0u, 4u, 0u);
                        break;
                }
            } else if ((tags = sscanf(schema.c_str(), "android.generic.%u%c%u%c",
                        &numLayers, &dummy, &numBLayers, &dummy))
                && (tags == 1 || (tags == 3 && dummy == '+'))
                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
                layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
                        {}, 0u, numLayers + numBLayers, numBLayers);
            } else {
                ALOGD("Ignoring unsupported ts-schema [%s]", schema.c_str());
            }
            if (layering) {
                params->setBuffer(C2_PARAMKEY_TEMPORAL_LAYERING,
                                  ABuffer::CreateAsCopy(layering.get(), layering->size()));
            }
        }
    }

    { // convert from MediaFormat rect to Codec 2.0 rect
        int32_t offset;
        int32_t end;
        AMessage::ItemData item;
        if (params->findInt32("crop-left", &offset) && params->findInt32("crop-right", &end)
                && offset >= 0 && end >= offset - 1) {
            size_t ix = params->findEntryByName("crop-right");
            params->setEntryNameAt(ix, "crop-width");
            item.set(end - offset + 1);
            params->setEntryAt(ix, item);
        }
        if (params->findInt32("crop-top", &offset) && params->findInt32("crop-bottom", &end)
                && offset >= 0 && end >= offset - 1) {
            size_t ix = params->findEntryByName("crop-bottom");
            params->setEntryNameAt(ix, "crop-height");
            item.set(end - offset + 1);
            params->setEntryAt(ix, item);
        }
    }

    { // convert color info
        int32_t standard;
        if (params->findInt32(KEY_COLOR_STANDARD, &standard)) {
            C2Color::primaries_t primaries;
            C2Color::matrix_t matrix;

            if (C2Mapper::map(standard, &primaries, &matrix)) {
                params->setInt32("color-primaries", primaries);
                params->setInt32("color-matrix", matrix);
            }
        }

        sp<ABuffer> hdrMeta;
        if (params->findBuffer(KEY_HDR_STATIC_INFO, &hdrMeta)
                && hdrMeta->size() == sizeof(HDRStaticInfo)) {
            HDRStaticInfo *meta = (HDRStaticInfo*)hdrMeta->data();
            if (meta->mID == meta->kType1) {
                params->setFloat("smpte2086.red.x", meta->sType1.mR.x * 0.00002);
                params->setFloat("smpte2086.red.y", meta->sType1.mR.y * 0.00002);
                params->setFloat("smpte2086.green.x", meta->sType1.mG.x * 0.00002);
                params->setFloat("smpte2086.green.y", meta->sType1.mG.y * 0.00002);
                params->setFloat("smpte2086.blue.x", meta->sType1.mB.x * 0.00002);
                params->setFloat("smpte2086.blue.y", meta->sType1.mB.y * 0.00002);
                params->setFloat("smpte2086.white.x", meta->sType1.mW.x * 0.00002);
                params->setFloat("smpte2086.white.y", meta->sType1.mW.y * 0.00002);
                params->setFloat("smpte2086.max-luminance", meta->sType1.mMaxDisplayLuminance);
                params->setFloat("smpte2086.min-luminance", meta->sType1.mMinDisplayLuminance * 0.0001);
                params->setFloat("cta861.max-cll", meta->sType1.mMaxContentLightLevel);
                params->setFloat("cta861.max-fall", meta->sType1.mMaxFrameAverageLightLevel);
            }
        }

        sp<ABuffer> hdrDynamicInfo;
        if (params->findBuffer(KEY_HDR10_PLUS_INFO, &hdrDynamicInfo)) {
            for (const std::string &prefix : { C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO,
                                               C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO }) {
                params->setInt32((prefix + ".type").c_str(),
                                 HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
                params->setBuffer((prefix + ".data").c_str(), hdrDynamicInfo);
            }
        }
    }

    // this is to verify that we set proper signedness for standard parameters
    bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
    // this is to allow vendors to use the wrong signedness for standard parameters
    bool beVeryLax = property_get_bool("debug.stagefright.ccodec_lax_type", false);

    ReflectedParamUpdater::Dict filtered;
    for (size_t ix = 0; ix < params->countEntries(); ++ix) {
        AMessage::Type type;
        AString name = params->getEntryNameAt(ix, &type);
        AMessage::ItemData msgItem = params->getEntryAt(ix);
        ReflectedParamUpdater::Value item;
        convert(msgItem, &item); // convert item to param updater item

        if (name.startsWith("vendor.")) {
            // vendor params pass through as is
            filtered.emplace(name.c_str(), item);
            continue;
        }
        // standard parameters may get modified, filtered or duplicated
        for (const ConfigMapper &cm : mStandardParams->getConfigMappersForSdkKey(name.c_str())) {
            // note: we ignore port domain for configuration
            if ((cm.domain() & configDomain)
                    // component domain + kind (these must match)
                    && (cm.domain() & mDomain) == mDomain) {
                // map arithmetic values, pass through string or buffer
                switch (type) {
                    case AMessage::kTypeBuffer:
                    case AMessage::kTypeString:
                        break;
                    case AMessage::kTypeInt32:
                    case AMessage::kTypeInt64:
                    case AMessage::kTypeFloat:
                    case AMessage::kTypeDouble:
                        // for now only map settings with mappers as we are not creating
                        // signed <=> unsigned mappers
                        // TODO: be precise about signed unsigned
                        if (beVeryStrict || cm.mapper()) {
                            item.set(cm.mapFromMessage(params->getEntryAt(ix)));
                            // also allow to relax type strictness
                            if (beVeryLax) {
                                relaxValues(item);
                            }
                        }
                        break;
                    default:
                        continue;
                }
                filtered.emplace(cm.path(), item);
            }
        }
    }
    ALOGV("filter src msg %s", params->debugString(4).c_str());
    ALOGV("filter dst params %s", filtered.debugString(4).c_str());
    return filtered;
}

status_t CCodecConfig::getConfigUpdateFromSdkParams(
        std::shared_ptr<Codec2Client::Configurable> configurable,
        const sp<AMessage> &sdkParams, Domain configDomain,
        c2_blocking_t blocking,
        std::vector<std::unique_ptr<C2Param>> *configUpdate) const {
    // update the mappers if we know something more of this format.
    // AV1 10b or 8b encoding request.
    AString mime;
    int32_t requestedSdkProfile = -1;
    if ((mDomain == (IS_VIDEO | IS_ENCODER)) &&
            sdkParams->findString(KEY_MIME, &mime) &&
            mime == MIMETYPE_VIDEO_AV1) {

        sdkParams->findInt32(KEY_PROFILE, &requestedSdkProfile);
        bool is10bAv1EncodeRequested = (requestedSdkProfile == AV1ProfileMain10);

        int32_t bitDepth = (is10bAv1EncodeRequested) ? 10 : 8;
        // we always initilze with an 8b mapper. Update this only if needed.
        if (bitDepth != 8) {
            std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
                C2Mapper::GetBitDepthProfileLevelMapper(mCodingMediaType, bitDepth);
            mStandardParams->updateConfigMappersForKey(StandardParams::SdkKey(KEY_PROFILE),
                {
                    ConfigMapper(KEY_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
                    .limitTo(Domain::CODED)
                    .withMappers([mapper](C2Value v) -> C2Value {
                        C2Config::profile_t c2 = PROFILE_UNUSED;
                        int32_t sdk;
                        if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
                            return c2;
                        }
                        return PROFILE_UNUSED;
                        }, [mapper](C2Value v) -> C2Value {
                        C2Config::profile_t c2;
                        int32_t sdk;
                        using C2ValueType =
                            typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
                        if (mapper && v.get((C2ValueType*)&c2) && mapper->mapProfile(c2, &sdk)) {
                            return sdk;
                        }
                        return C2Value();
                })});
            mStandardParams->updateConfigMappersForKey(StandardParams::SdkKey(KEY_LEVEL),
                {
                    ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
                    .limitTo(Domain::CODED)
                    .withMappers([mapper](C2Value v) -> C2Value {
                        C2Config::level_t c2 = LEVEL_UNUSED;
                        int32_t sdk;
                        if (mapper && v.get(&sdk) && mapper->mapLevel(sdk, &c2)) {
                            return c2;
                        }
                        return LEVEL_UNUSED;
                        }, [mapper](C2Value v) -> C2Value {
                        C2Config::level_t c2;
                        int32_t sdk;
                        using C2ValueType =
                            typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
                        if (mapper && v.get((C2ValueType*)&c2) && mapper->mapLevel(c2, &sdk)) {
                            return sdk;
                        }
                        return C2Value();
                })});
        }
    }

    ReflectedParamUpdater::Dict params = getReflectedFormat(sdkParams, configDomain);

    std::vector<C2Param::Index> indices;
    mParamUpdater->getParamIndicesFromMessage(params, &indices);
    if (indices.empty()) {
        ALOGD("no recognized params in: %s", params.debugString().c_str());
        return OK;
    }

    configUpdate->clear();
    std::vector<C2Param::Index> supportedIndices;
    for (C2Param::Index ix : indices) {
        if (mSupportedIndices.count(ix)) {
            supportedIndices.push_back(ix);
        } else if (mLocalParams.count(ix)) {
            // query local parameter here
            auto it = mCurrentConfig.find(ix);
            if (it != mCurrentConfig.end()) {
                configUpdate->emplace_back(C2Param::Copy(*it->second));
            }
        }
    }

    c2_status_t err = configurable->query({ }, supportedIndices, blocking, configUpdate);
    if (err != C2_OK) {
        ALOGD("query failed after returning %zu params => %s", configUpdate->size(), asString(err));
    }

    if (configUpdate->size()) {
        mParamUpdater->updateParamsFromMessage(params, configUpdate);
    }
    return OK;
}

status_t CCodecConfig::setParameters(
        std::shared_ptr<Codec2Client::Configurable> configurable,
        std::vector<std::unique_ptr<C2Param>> &configUpdate,
        c2_blocking_t blocking) {
    status_t result = OK;
    if (configUpdate.empty()) {
        return OK;
    }

    std::vector<C2Param::Index> indices;
    std::vector<C2Param *> paramVector;
    for (const std::unique_ptr<C2Param> &param : configUpdate) {
        if (mSupportedIndices.count(param->index())) {
            // component parameter
            paramVector.push_back(param.get());
            indices.push_back(param->index());
        } else if (mLocalParams.count(param->index())) {
            // handle local parameter here
            LocalParamValidator validator = mLocalParams.find(param->index())->second;
            c2_status_t err = C2_OK;
            std::unique_ptr<C2Param> copy = C2Param::Copy(*param);
            if (validator) {
                err = validator(copy);
            }
            if (err == C2_OK) {
                ALOGV("updated local parameter value for %s",
                        mParamUpdater->getParamName(param->index()).c_str());

                mCurrentConfig[param->index()] = std::move(copy);
            } else {
                ALOGD("failed to set parameter value for %s => %s",
                        mParamUpdater->getParamName(param->index()).c_str(), asString(err));
                result = BAD_VALUE;
            }
        }
    }
    // update subscribed param indices
    subscribeToConfigUpdate(configurable, indices, blocking);

    std::vector<std::unique_ptr<C2SettingResult>> failures;
    c2_status_t err = configurable->config(paramVector, blocking, &failures);
    if (err != C2_OK) {
        ALOGD("config failed => %s", asString(err));
        // This is non-fatal.
    }
    for (const std::unique_ptr<C2SettingResult> &failure : failures) {
        switch (failure->failure) {
            case C2SettingResult::BAD_VALUE:
                ALOGD("Bad parameter value");
                result = BAD_VALUE;
                break;
            default:
                ALOGV("failure = %d", int(failure->failure));
                break;
        }
    }

    // Re-query parameter values in case config could not update them and update the current
    // configuration.
    configUpdate.clear();
    err = configurable->query({}, indices, blocking, &configUpdate);
    if (err != C2_OK) {
        ALOGD("query failed after returning %zu params => %s", configUpdate.size(), asString(err));
    }
    (void)updateConfiguration(configUpdate, ALL);

    // TODO: error value
    return result;
}

const C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const {
    auto it = mCurrentConfig.find(index);
    if (it == mCurrentConfig.end()) {
        return nullptr;
    } else {
        return it->second.get();
    }
}

status_t CCodecConfig::subscribeToAllVendorParams(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        c2_blocking_t blocking) {
    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) {
        if (desc->isVisible()) {
            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);
}

}  // namespace android
