/*
 * 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 <C2Debug.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_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 {

/**
 * 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;
        int32_t int32Value;
        uint32_t uint32Value;
        int64_t int64Value;
        uint64_t uint64Value;
        float floatValue;
        if (value.type() != C2Value::NO_INIT && mReverse) {
            value = mReverse(value);
        }
        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);
        }
        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::Component> &component) {
    AString mediaType;
    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2err = component->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::Component> &component) {
    typedef C2PortMediaTypeSetting P;
    typedef C2StreamMediaTypeSetting S;
    if (input) {
        return QueryMediaTypeImpl<P::input, S::input>(component);
    } else {
        return QueryMediaTypeImpl<P::output, S::output>(component);
    }
}

}  // 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()) {
            ALOGD("no c2 equivalents for %s", key.c_str());
            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;
};

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)
        .withMapper([](C2Value v) -> C2Value {
            int32_t value;
            C2Config::bitrate_mode_t mode;
            if (v.get(&value) && C2Mapper::map(value, &mode)) {
                return mode;
            }
            return C2Value();
        }));
    // 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));
    // SDK rotation is 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)
    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_VUI_COLOR_ASPECTS,   "range")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::range_t>());
    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_VUI_COLOR_ASPECTS,   "transfer")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW & D::READ)
        .withC2Mappers<C2Color::transfer_t>());
    add(ConfigMapper("color-primaries",     C2_PARAMKEY_VUI_COLOR_ASPECTS,   "primaries")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW & D::READ));
    add(ConfigMapper("color-matrix",        C2_PARAMKEY_VUI_COLOR_ASPECTS,   "matrix")
        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW & D::READ));

    // 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("prepend-sps-pps-to-idr-frames",
                     C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
        .limitTo(D::ENCODER & D::VIDEO)
        .withMapper([](C2Value v) -> C2Value {
            int32_t value;
            if (v.get(&value) && value) {
                return C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC);
            } else {
                return C2Value(C2Config::PREPEND_HEADER_TO_NONE);
            }
        }));
    // remove when codecs switch to PARAMKEY
    deprecated(ConfigMapper("prepend-sps-pps-to-idr-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")
        .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();
        }));
    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
    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"));
    // 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(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)) {
                switch (value) {
                    case COLOR_FormatSurface:
                        return (uint32_t)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
                    case COLOR_FormatYUV420Flexible:
                        return (uint32_t)HAL_PIXEL_FORMAT_YCBCR_420_888;
                    case COLOR_FormatYUV420Planar:
                    case COLOR_FormatYUV420SemiPlanar:
                    case COLOR_FormatYUV420PackedPlanar:
                    case COLOR_FormatYUV420PackedSemiPlanar:
                        return (uint32_t)HAL_PIXEL_FORMAT_YV12;
                    default:
                        // TODO: support some sort of passthrough
                        break;
                }
            }
            return C2Value();
        }, [](C2Value v) -> C2Value {
            uint32_t value;
            if (v.get(&value)) {
                switch (value) {
                    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
                        return COLOR_FormatSurface;
                    case HAL_PIXEL_FORMAT_YV12:
                    case HAL_PIXEL_FORMAT_YCBCR_420_888:
                        return COLOR_FormatYUV420Flexible;
                    default:
                        // TODO: support some sort of passthrough
                        break;
                }
            }
            return C2Value();
        }));

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

    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")
        .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;
        }));

    add(ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
        .withMapper([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;
        }));

    // 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)
        .withMapper([](C2Value v) -> C2Value {
            int32_t value;
            if (!v.get(&value) || value < 0) {
                value = property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
            }
            return float(-0.25 * c2_min(value, 127));
        }));

    // 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)
        .withMapper([](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.);
        }));

    // 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)
        .withMapper([](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.);
        }));

    // 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)
        .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)
        .withMapper([](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));
        }));

    // 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)
        .withMapper([](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;
        }));

    add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO));

    add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
        .limitTo(D::AUDIO & D::ENCODER & D::CONFIG)
        .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"));
    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));

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

    /* still to do

    // not yet supported in Codec 2.0
    constexpr char KEY_AUDIO_SESSION_ID[] = "audio-session-id";  // we actually used "audio-hw-sync"

    constexpr char KEY_CAPTURE_RATE[] = "capture-rate";
    constexpr char KEY_CHANNEL_MASK[] = "channel-mask";
    constexpr char KEY_COLOR_RANGE[] = "color-range";
    constexpr char KEY_COLOR_STANDARD[] = "color-standard";
    constexpr char KEY_COLOR_TRANSFER[] = "color-transfer";
    constexpr char KEY_HDR_STATIC_INFO[] = "hdr-static-info";
    constexpr char KEY_OUTPUT_REORDER_DEPTH[] = "output-reorder-depth"; // not yet used
    constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
    constexpr char KEY_TEMPORAL_LAYERING[] = "ts-schema";
    */
}

status_t CCodecConfig::initialize(
        const std::shared_ptr<Codec2Client> &client,
        const std::shared_ptr<Codec2Client::Component> &component) {
    C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
    C2ComponentKindSetting kind(C2Component::KIND_OTHER);

    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2err = component->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 (component->getName().find("encoder") != std::string::npos) {
                kind.value = C2Component::KIND_ENCODER;
            } else if (component->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 */, component);
            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 */, component).c_str();
        break;
    case C2Component::KIND_ENCODER:
        mCodingMediaType = QueryMediaType(false /* input */, component).c_str();
        break;
    default:
        mCodingMediaType = "";
    }

    c2err = component->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 = client->getParamReflector();
    if (mReflector == nullptr) {
        ALOGE("Failed to get 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);

    return OK;
}

status_t CCodecConfig::subscribeToConfigUpdate(
        const std::shared_ptr<Codec2Client::Component> &component,
        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 = component->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::Component> &component) {
    // query all subscribed parameters
    std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
    std::vector<std::unique_ptr<C2Param>> queried;
    c2_status_t c2Err = component->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);
    ALOGD("c2 config is %s", reflected.debugString().c_str());

    bool changed = false;
    if (domain & mInputDomain) {
        sp<AMessage> oldFormat = mInputFormat;
        mInputFormat = mInputFormat->dup(); // trigger format changed
        mInputFormat->extend(getSdkFormatForDomain(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(getSdkFormatForDomain(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::getSdkFormatForDomain(
        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);
        }
    }

    { // 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
        // TODO: apply platform default to decoder output

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

    {   // 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())) {
            if ((cm.domain() & configDomain) && (cm.domain() & /* component */ 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::Component> component,
        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 = component->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::Component> component,
        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(component, indices, blocking);

    std::vector<std::unique_ptr<C2SettingResult>> failures;
    c2_status_t err = component->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 = component->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();
    }
}

}  // namespace android
