/*
 * 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 <cutils/properties.h>
#include <log/log.h>

#include <C2Component.h>
#include <C2Param.h>
#include <util/C2InterfaceHelper.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);
        }
    }

    /**
     * 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 std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
            for (const ConfigMapper &cm : el.second) {
                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) { }

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::OUTPUT));
    // 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;
            }
            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));

    // 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::CODED)
        .withMappers(negate, negate));
    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
        .limitTo(D::VIDEO & 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 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)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));

    // 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(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
                     C2_PARAMKEY_SECURE_MODE, "value"));

    add(ConfigMapper(KEY_PREPEND_HEADERS_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_HEADERS_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));

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

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

    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));

    add(ConfigMapper(KEY_PCM_ENCODING,  C2_PARAMKEY_PCM_ENCODING,       "value")
        .limitTo(D::AUDIO)
        .withMappers([](C2Value v) -> C2Value {
            int32_t value;
            C2Config::pcm_encoding_t to;
            if (v.get(&value) && C2Mapper::map(value, &to)) {
                return to;
            }
            return C2Value();
        }, [](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_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();
        }));

    // 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 | D::READ))
        .withMappers([](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;
        },[](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value)) {
              return value;
            }
            else {
              return C2Value();
            }
        }));

    // 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_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(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("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;
        }));

    /* still to do
    constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";

       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 C2StreamColorAspectsInfo::output(0u), C2_PARAMKEY_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);
        }
    }

    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) {
                mVendorParamIndices.insert_or_assign(key, desc->index());
            }
        }
    }

    return OK;
}

status_t CCodecConfig::subscribeToConfigUpdate(
        const std::shared_ptr<Codec2Client::Configurable> &configurable,
        const std::vector<C2Param::Index> &indices,
        c2_blocking_t blocking) {
    mSubscribedIndices.insert(indices.begin(), indices.end());
    // TODO: enable this when components no longer crash on this config
    if (mSubscribedIndices.size() != mSubscribedIndicesSize && false) {
        std::vector<uint32_t> indices;
        for (C2Param::Index ix : mSubscribedIndices) {
            indices.push_back(ix);
        }
        std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
            C2SubscribedParamIndicesTuning::AllocUnique(indices);
        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();
    }
    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) {
            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);
        }
    }

    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 std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
        for (const ConfigMapper &cm : el.second) {
            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(el.first.c_str(), item);
        }
    }

    bool input = (portDomain & Domain::IS_INPUT);
    std::vector<std::string> vendorKeys;
    for (const std::pair<std::string, ReflectedParamUpdater::Value> &entry : reflected) {
        auto it = mVendorParamIndices.find(entry.first);
        if (it == mVendorParamIndices.end()) {
            continue;
        }
        if (mSubscribedIndices.count(it->second) == 0) {
            continue;
        }
        // For vendor parameters, we only care about direction
        if ((input && !it->second.forInput())
                || (!input && !it->second.forOutput())) {
            continue;
        }
        const ReflectedParamUpdater::Value &value = entry.second;
        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", entry.first.c_str());
            continue;
        }
        msg->setItem(entry.first.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));
        }
    }

    { // convert color info
        C2Color::primaries_t primaries;
        C2Color::matrix_t 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);
            }
        }

        // 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->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"));
                msg->setBuffer(KEY_HDR_STATIC_INFO, ABuffer::CreateAsCopy(&meta, sizeof(meta)));
            } else {
                ALOGD("found invalid HDR static metadata %s", msg->debugString(8).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);
            }
        }
    }

    {   // 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);
            }
        }
    }

    // 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("filtered %s to %s", params->debugString(4).c_str(),
            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 {
    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 std::pair<std::string, C2Param::Index> &entry : mVendorParamIndices) {
        mSubscribedIndices.insert(entry.second);
    }
    return subscribeToConfigUpdate(configurable, {}, blocking);
}

}  // namespace android
