13bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/*
23bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * Copyright (C) 2018 The Android Open Source Project
33bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar *
43bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
53bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * you may not use this file except in compliance with the License.
63bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * You may obtain a copy of the License at
73bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar *
83bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
93bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar *
103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * Unless required by applicable law or agreed to in writing, software
113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * See the License for the specific language governing permissions and
143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * limitations under the License.
153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar */
163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar//#define LOG_NDEBUG 0
183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#define LOG_TAG "CCodecConfig"
193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <cutils/properties.h>
203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <log/log.h>
213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <C2Component.h>
233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <C2Debug.h>
243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <C2Param.h>
253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <media/stagefright/MediaCodecConstants.h>
273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include "CCodecConfig.h"
293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include "Codec2Mapper.h"
303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarnamespace android {
323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar// CCodecConfig
343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarnamespace {
363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/**
383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * mapping between SDK and Codec 2.0 configurations.
393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar */
403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstruct ConfigMapper {
413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /**
423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * Value mapper (C2Value => C2Value)
433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     */
443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    typedef std::function<C2Value(C2Value)> Mapper;
453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// shorthand
473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    typedef CCodecConfig::Domain Domain;
483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ConfigMapper(std::string mediaKey, C2String c2struct, C2String c2field)
503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        : mDomain(Domain::ALL), mMediaKey(mediaKey), mStruct(c2struct), mField(c2field) { }
513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Limits this parameter to the given domain
533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ConfigMapper &limitTo(uint32_t domain) {
543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2_CHECK(domain & Domain::GUARD_BIT);
553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mDomain = Domain(mDomain & domain);
563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return *this;
573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Adds SDK => Codec 2.0 mapper (should not be in the SDK format)
603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ConfigMapper &withMapper(Mapper mapper) {
613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2_CHECK(!mMapper);
623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2_CHECK(!mReverse);
633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mMapper = mapper;
643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return *this;
653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Adds SDK <=> Codec 2.0 value mappers
683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ConfigMapper &withMappers(Mapper mapper, Mapper reverse) {
693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2_CHECK(!mMapper);
703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2_CHECK(!mReverse);
713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mMapper = mapper;
723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mReverse = reverse;
733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return *this;
743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Maps from SDK values in an AMessage to a suitable C2Value.
773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2Value mapFromMessage(const AMessage::ItemData &item) const {
783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        C2Value value;
793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t int32Value;
803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int64_t int64Value;
813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        float floatValue;
823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        double doubleValue;
833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (item.find(&int32Value)) {
843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = int32Value;
853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (item.find(&int64Value)) {
863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = int64Value;
873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (item.find(&floatValue)) {
883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = floatValue;
893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (item.find(&doubleValue)) {
903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = (float)doubleValue;
913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (value.type() != C2Value::NO_INIT && mMapper) {
933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = mMapper(value);
943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return value;
963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Maps from a C2Value to an SDK value in an AMessage.
993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    AMessage::ItemData mapToMessage(C2Value value) const {
1003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        AMessage::ItemData item;
1013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t int32Value;
1023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        uint32_t uint32Value;
1033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int64_t int64Value;
1043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        uint64_t uint64Value;
1053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        float floatValue;
1063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (value.type() != C2Value::NO_INIT && mReverse) {
1073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            value = mReverse(value);
1083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
1093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (value.get(&int32Value)) {
1103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set(int32Value);
1113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (value.get(&uint32Value) && uint32Value <= uint32_t(INT32_MAX)) {
1123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            // SDK does not support unsigned values
1133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set((int32_t)uint32Value);
1143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (value.get(&int64Value)) {
1153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set(int64Value);
1163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (value.get(&uint64Value) && uint64Value <= uint64_t(INT64_MAX)) {
1173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            // SDK does not support unsigned values
1183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set((int64_t)uint64Value);
1193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (value.get(&floatValue)) {
1203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set(floatValue);
1213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
1223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return item;
1233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
1243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Domain domain() const { return mDomain; }
1263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::string mediaKey() const { return mMediaKey; }
1273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::string path() const { return mStruct + '.' + mField; }
1283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Mapper mapper() const { return mMapper; }
1293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Mapper reverse() const { return mReverse; }
1303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarprivate:
1323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Domain mDomain;         ///< parameter domain
1333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::string mMediaKey;  ///< SDK key
1343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2String mStruct;       ///< Codec 2.0 struct name
1353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2String mField;        ///< Codec 2.0 field name
1363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Mapper mMapper;         ///< optional SDK => Codec 2.0 value mapper
1373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    Mapper mReverse;        ///< optional Codec 2.0 => SDK value mapper
1383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar};
1393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
1413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/**
1433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar * Set of standard parameters used by CCodec that are exposed to MediaCodec.
1443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar */
1453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstruct StandardParams {
1463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    typedef CCodecConfig::Domain Domain;
1473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // standard (MediaCodec) params are keyed by media format key
1493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    typedef std::string SdkKey;
1503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// used to return reference to no config mappers in getConfigMappersForSdkKey
1523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    static const std::vector<ConfigMapper> NO_MAPPERS;
1533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /// Returns Codec 2.0 equivalent parameters for an SDK format key.
1553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    const std::vector<ConfigMapper> &getConfigMappersForSdkKey(std::string key) const {
1563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        auto it = mConfigMappers.find(key);
1573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (it == mConfigMappers.end()) {
1583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            ALOGD("no c2 equivalents for %s", key.c_str());
1593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return NO_MAPPERS;
1603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
1613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGV("found %zu eqs for %s", it->second.size(), key.c_str());
1623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return it->second;
1633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
1643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /**
1663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * Adds a SDK <=> Codec 2.0 parameter mapping. Multiple Codec 2.0 parameters may map to a
1673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * single SDK key, in which case they shall be ordered from least authoritative to most
1683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * authoritative. When constructing SDK formats, the last mapped Codec 2.0 parameter that
1693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * is supported by the component will determine the exposed value. (TODO: perhaps restrict this
1703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * by domain.)
1713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     */
1723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    void add(const ConfigMapper &cm) {
1733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        auto it = mConfigMappers.find(cm.mediaKey());
1743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGV("%c%c%c%c %04x %9s %s => %s",
1753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              ((cm.domain() & Domain::IS_INPUT) ? 'I' : ' '),
1763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              ((cm.domain() & Domain::IS_OUTPUT) ? 'O' : ' '),
1773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              ((cm.domain() & Domain::IS_CODED) ? 'C' : ' '),
1783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              ((cm.domain() & Domain::IS_RAW) ? 'R' : ' '),
1793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              cm.domain(),
1803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              it == mConfigMappers.end() ? "adding" : "extending",
1813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar              cm.mediaKey().c_str(), cm.path().c_str());
1823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (it == mConfigMappers.end()) {
1833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            std::vector<ConfigMapper> eqs = { cm };
1843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            mConfigMappers.emplace(cm.mediaKey(), eqs);
1853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else {
1863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            it->second.push_back(cm);
1873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
1883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
1893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /**
1913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * Returns all paths for a specific domain.
1923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     *
1933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * \param any maximum domain mask. Returned parameters must match at least one of the domains
1943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     *            in the mask.
1953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * \param all minimum domain mask. Returned parameters must match all of the domains in the
1963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     *            mask. This is restricted to the bits of the maximum mask.
1973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     */
1983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<std::string> getPathsForDomain(
1993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            Domain any, Domain all = Domain::ALL) const {
2003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<std::string> res;
2013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
2023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            for (const ConfigMapper &cm : el.second) {
2033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                ALOGV("filtering %s %x %x %x %x", cm.path().c_str(), cm.domain(), any,
2043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        (cm.domain() & any), (cm.domain() & any & all));
2053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                if ((cm.domain() & any) && ((cm.domain() & any & all) == (any & all))) {
2063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    res.push_back(cm.path());
2073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
2083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
2093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
2103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return res;
2113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
2123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /**
2143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * Returns SDK <=> Codec 2.0 mappings.
2153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     *
2163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     * TODO: replace these with better methods as this exposes the inner structure.
2173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar     */
2183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    const std::map<SdkKey, std::vector<ConfigMapper>> getKeys() const {
2193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return mConfigMappers;
2203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
2213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarprivate:
2233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::map<SdkKey, std::vector<ConfigMapper>> mConfigMappers;
2243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar};
2253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarconst std::vector<ConfigMapper> StandardParams::NO_MAPPERS;
2273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
228900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar
229900cd38aeb849984fc40998539bbd75bf0333c83Lajos MolnarCCodecConfig::CCodecConfig()
230900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar    : mInputFormat(new AMessage),
231900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar      mOutputFormat(new AMessage) { }
232900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar
2333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarvoid CCodecConfig::initializeStandardParams() {
2343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    typedef Domain D;
2353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mStandardParams = std::make_shared<StandardParams>();
2363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::function<void(const ConfigMapper &)> add =
2373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        [params = mStandardParams](const ConfigMapper &cm) {
2383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            params->add(cm);
2393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    };
2403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::function<void(const ConfigMapper &)> deprecated = add;
2413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // allow int32 or float SDK values and represent them as float
2433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ConfigMapper::Mapper makeFloat = [](C2Value v) -> C2Value {
2443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // convert from i32 to float
2453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t i32Value;
2463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        float fpValue;
2473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (v.get(&i32Value)) {
2483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return (float)i32Value;
2493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (v.get(&fpValue)) {
2503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return fpValue;
2513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
2523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return C2Value();
2533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    };
2543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
255b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    ConfigMapper::Mapper negate = [](C2Value v) -> C2Value {
256b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        int32_t value;
257b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        if (v.get(&value)) {
258b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar            return -value;
259b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        }
260b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        return C2Value();
261b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    };
262b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar
2633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_INPUT_MEDIA_TYPE,    "value")
2643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::INPUT & D::READ));
2653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_OUTPUT_MEDIA_TYPE,   "value")
2663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::OUTPUT & D::READ));
2673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value").limitTo(D::ENCODER));
2693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(PARAMETER_KEY_VIDEO_BITRATE, C2_PARAMKEY_BITRATE, "value")
2703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
2713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
2723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::ENCODER & D::CODED)
2733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .withMapper([](C2Value v) -> C2Value {
2743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            int32_t value;
2753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            C2Config::bitrate_mode_t mode;
2763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value) && C2Mapper::map(value, &mode)) {
2773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return mode;
2783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
2793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
2803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }));
2813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // remove when codecs switch to PARAMKEY and new modes
2823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
2833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               .limitTo(D::ENCODER));
2843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_FRAME_RATE, C2_PARAMKEY_FRAME_RATE, "value")
2853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO)
2863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .withMappers(makeFloat, [](C2Value v) -> C2Value {
2873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            // read back always as int
2883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            float value;
2893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value)) {
2903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return (int32_t)value;
2913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
2923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
2933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }));
2943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
2953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_MAX_INPUT_SIZE, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE, "value")
2963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::INPUT));
2973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // remove when codecs switch to PARAMKEY
2983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper(KEY_MAX_INPUT_SIZE, "coded.max-frame-size", "value")
2993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               .limitTo(D::INPUT));
300b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    // SDK rotation is clock-wise
3013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
302b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        .limitTo(D::VIDEO & D::CODED)
303b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        .withMappers(negate, negate));
304b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
305b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        .limitTo(D::VIDEO & D::RAW)
306b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        .withMappers(negate, negate));
3073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
3093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                     C2_PARAMKEY_SECURE_MODE, "value"));
3103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("prepend-sps-pps-to-idr-frames",
3123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                     C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
3133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::ENCODER & D::VIDEO)
3143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .withMapper([](C2Value v) -> C2Value {
3153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            int32_t value;
3163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value) && value) {
3173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC);
3183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else {
3193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return C2Value(C2Config::PREPEND_HEADER_TO_NONE);
3203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
3213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }));
3223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // remove when codecs switch to PARAMKEY
3233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper("prepend-sps-pps-to-idr-frames",
3243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                            "coding.add-csd-to-sync-frames", "value")
3253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               .limitTo(D::ENCODER & D::VIDEO));
3263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(C2_PARAMKEY_SYNC_FRAME_PERIOD, C2_PARAMKEY_SYNC_FRAME_PERIOD, "value"));
3273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // remove when codecs switch to PARAMKEY
3283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper(C2_PARAMKEY_SYNC_FRAME_PERIOD, "coding.gop", "intra-period")
3293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               .limitTo(D::ENCODER & D::VIDEO));
3303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_INTRA_REFRESH_PERIOD, C2_PARAMKEY_INTRA_REFRESH, "period")
3313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO & D::ENCODER));
3323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
3333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
3343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                     "coding.request-sync", "value")
3353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::PARAM & D::ENCODER));
3363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
3373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                     C2_PARAMKEY_REQUEST_SYNC_FRAME, "value")
3383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::PARAM & D::ENCODER));
3393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_OPERATING_RATE,   C2_PARAMKEY_OPERATING_RATE,     "value"));
3413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // C2 priorities are inverted
3423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_PRIORITY,         C2_PARAMKEY_PRIORITY,           "value")
343b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        .withMappers(negate, negate));
3443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // remove when codecs switch to PARAMKEY
3453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper(KEY_OPERATING_RATE,   "ctrl.operating-rate",     "value")
3463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               .withMapper(makeFloat));
3473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    deprecated(ConfigMapper(KEY_PRIORITY,         "ctrl.priority",           "value"));
3483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_WIDTH,         C2_PARAMKEY_PICTURE_SIZE,       "width")
3503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_HEIGHT,        C2_PARAMKEY_PICTURE_SIZE,       "height")
3523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("crop-left",       C2_PARAMKEY_CROP_RECT,       "left")
3553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("crop-top",        C2_PARAMKEY_CROP_RECT,       "top")
3573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("crop-width",      C2_PARAMKEY_CROP_RECT,       "width")
3593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("crop-height",     C2_PARAMKEY_CROP_RECT,       "height")
3613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::VIDEO | D::IMAGE));
3623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_MAX_WIDTH,     C2_PARAMKEY_MAX_PICTURE_SIZE,    "width")
3643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
3653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_MAX_HEIGHT,    C2_PARAMKEY_MAX_PICTURE_SIZE,    "height")
3663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
3673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
3683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper("csd-0",           C2_PARAMKEY_INIT_DATA,       "value")
3693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::OUTPUT & D::READ));
370c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar
371c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar    // Pixel Format (use local key for actual pixel format as we don't distinguish between
372c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar    // SDK layouts for flexible format and we need the actual SDK color format in the media format)
373c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar    add(ConfigMapper("android._color-format",  C2_PARAMKEY_PIXEL_FORMAT, "value")
3743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
3753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .withMappers([](C2Value v) -> C2Value {
3763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            int32_t value;
3773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value)) {
3783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                switch (value) {
3793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatSurface:
3803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        return (uint32_t)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
3813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatYUV420Flexible:
3823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        return (uint32_t)HAL_PIXEL_FORMAT_YCBCR_420_888;
3833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatYUV420Planar:
3843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatYUV420SemiPlanar:
3853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatYUV420PackedPlanar:
3863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case COLOR_FormatYUV420PackedSemiPlanar:
3873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        return (uint32_t)HAL_PIXEL_FORMAT_YV12;
3883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    default:
3893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        // TODO: support some sort of passthrough
3903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        break;
3913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
3923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
3933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
3943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }, [](C2Value v) -> C2Value {
3953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            uint32_t value;
3963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value)) {
3973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                switch (value) {
3983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
3993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        return COLOR_FormatSurface;
4003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case HAL_PIXEL_FORMAT_YV12:
4013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case HAL_PIXEL_FORMAT_YCBCR_420_888:
4023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        return COLOR_FormatYUV420Flexible;
4033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    default:
4043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        // TODO: support some sort of passthrough
4053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        break;
4063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
4073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
4083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
4093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }));
4103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CHANNEL_COUNT,       "value")
4123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO)); // read back to both formats
4133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CODED_CHANNEL_COUNT, "value")
4143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO & D::CODED));
4153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_SAMPLE_RATE,        "value")
4173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO)); // read back to both port formats
4183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_CODED_SAMPLE_RATE,  "value")
4193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO & D::CODED));
4203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_PCM_ENCODING,  C2_PARAMKEY_PCM_ENCODING,       "value")
4223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO));
4233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
4253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .limitTo(D::AUDIO & D::CODED)
4263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        .withMappers([](C2Value v) -> C2Value {
4273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            int32_t value;
4283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value) && value) {
4293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return C2Config::AAC_PACKAGING_ADTS;
4303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
4313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
4323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }, [](C2Value v) -> C2Value {
4333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            uint32_t value;
4343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (v.get(&value) && value == C2Config::AAC_PACKAGING_ADTS) {
4353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                return (int32_t)1;
4363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
4373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            return C2Value();
4383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }));
4393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    /* still to do
4413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_DRC_ATTENUATION_FACTOR[] = "aac-drc-cut-level";
4423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_DRC_BOOST_FACTOR[] = "aac-drc-boost-level";
4433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_DRC_EFFECT_TYPE[] = "aac-drc-effect-type";
4443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_DRC_HEAVY_COMPRESSION[] = "aac-drc-heavy-compression";
4453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_DRC_TARGET_REFERENCE_LEVEL[] = "aac-target-ref-level";
4463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_ENCODED_TARGET_LEVEL[] = "aac-encoded-target-level";
4473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT[] = "aac-max-output-channel_count";
4483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AAC_SBR_MODE[] = "aac-sbr-mode";
4503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_AUDIO_SESSION_ID[] = "audio-session-id";
4513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_CAPTURE_RATE[] = "capture-rate";
4533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_CHANNEL_MASK[] = "channel-mask";
4543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_COLOR_RANGE[] = "color-range";
4553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_COLOR_STANDARD[] = "color-standard";
4563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_COLOR_TRANSFER[] = "color-transfer";
4573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_FLAC_COMPRESSION_LEVEL[] = "flac-compression-level";
4583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_GRID_COLUMNS[] = "grid-cols";
4593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_GRID_ROWS[] = "grid-rows";
4603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_HDR_STATIC_INFO[] = "hdr-static-info";
4613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_LATENCY[] = "latency";
4623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_LEVEL[] = "level";
4633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_MAX_BIT_RATE[] = "max-bitrate";
4643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_OUTPUT_REORDER_DEPTH[] = "output-reorder-depth";
4653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_PROFILE[] = "profile";
4663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
4673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_QUALITY[] = "quality";
4683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_REPEAT_PREVIOUS_FRAME_AFTER[] = "repeat-previous-frame-after";
4693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_SLICE_HEIGHT[] = "slice-height";
4703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_STRIDE[] = "stride";
4713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_TEMPORAL_LAYERING[] = "ts-schema";
4723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_TILE_HEIGHT[] = "tile-height";
4733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_TILE_WIDTH[] = "tile-width";
4743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    constexpr char KEY_TRACK_ID[] = "track-id";
4753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    */
4773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
4783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatus_t CCodecConfig::initialize(
4803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const std::shared_ptr<Codec2Client> &client,
4813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const std::shared_ptr<Codec2Client::Component> &component) {
4823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
4833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2ComponentKindSetting kind(C2Component::KIND_OTHER);
4843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<std::unique_ptr<C2Param>> queried;
4863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    c2_status_t c2err = component->query({ &domain, &kind }, {}, C2_DONT_BLOCK, &queried);
4873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (c2err != C2_OK) {
4883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("Query domain & kind failed => %s", asString(c2err));
4893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // TEMP: determine kind from component name
4903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (kind.value == C2Component::KIND_OTHER) {
4913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (component->getName().find("encoder") != std::string::npos) {
4923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                kind.value = C2Component::KIND_ENCODER;
4933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else if (component->getName().find("decoder") != std::string::npos) {
4943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                kind.value = C2Component::KIND_DECODER;
4953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
4963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
4973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
4983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // TEMP: determine domain from media type (port (preferred) or stream #0)
4993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (domain.value == C2Component::DOMAIN_OTHER) {
5003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            c2err = component->query(
5013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    {}, { C2PortMediaTypeSetting::input::PARAM_TYPE,
5023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                          C2StreamMediaTypeSetting::input::PARAM_TYPE }, C2_DONT_BLOCK, &queried);
5033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (c2err != C2_OK && queried.size() == 0) {
5043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                ALOGD("Query media type failed => %s", asString(c2err));
5053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else {
5063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                AString mediaType;
5073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                C2PortMediaTypeSetting::input *portMediaType =
5083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    C2PortMediaTypeSetting::input::From(queried[0].get());
5093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                if (portMediaType) {
5103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    mediaType = AString(portMediaType->m.value, portMediaType->flexCount());
5113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                } else {
5123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    C2StreamMediaTypeSetting::input *streamMediaType =
5133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        C2StreamMediaTypeSetting::input::From(queried[0].get());
5143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    if (streamMediaType) {
5153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        mediaType = AString(streamMediaType->m.value, streamMediaType->flexCount());
5163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    }
5173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
5183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                ALOGD("read media type: %s", mediaType.c_str());
5193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                if (mediaType.startsWith("audio/")) {
5203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    domain.value = C2Component::DOMAIN_AUDIO;
5213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                } else if (mediaType.startsWith("video/")) {
5223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    domain.value = C2Component::DOMAIN_VIDEO;
5233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                } else if (mediaType.startsWith("image/")) {
5243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    domain.value = C2Component::DOMAIN_IMAGE;
5253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
5263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
5273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
5283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
5293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mDomain = (domain.value == C2Component::DOMAIN_VIDEO ? Domain::IS_VIDEO :
5313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               domain.value == C2Component::DOMAIN_IMAGE ? Domain::IS_IMAGE :
5323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               domain.value == C2Component::DOMAIN_AUDIO ? Domain::IS_AUDIO : Domain::OTHER_DOMAIN)
5333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            | (kind.value == C2Component::KIND_DECODER ? Domain::IS_DECODER :
5343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar               kind.value == C2Component::KIND_ENCODER ? Domain::IS_ENCODER : Domain::OTHER_KIND);
5353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mInputDomain = Domain(((mDomain & IS_DECODER) ? IS_CODED : IS_RAW) | IS_INPUT);
5373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mOutputDomain = Domain(((mDomain & IS_ENCODER) ? IS_CODED : IS_RAW) | IS_OUTPUT);
5383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("domain is %#x (%u %u)", mDomain, domain.value, kind.value);
5403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    c2err = component->querySupportedParams(&mParamDescs);
5423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (c2err != C2_OK) {
5433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("Query supported params failed after returning %zu values => %s",
5443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                mParamDescs.size(), asString(c2err));
5453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // TODO: return error once we complete implementation.
5463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return UNKNOWN_ERROR;
5473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
548dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar    for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
549dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar        mSupportedIndices.emplace(desc->index());
550dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar    }
5513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mReflector = client->getParamReflector();
5533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (mReflector == nullptr) {
5543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGE("Failed to get param reflector");
5553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // TODO: report error once we complete implementation.
5563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return UNKNOWN_ERROR;
5573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
5583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // enumerate all fields
5603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mParamUpdater = std::make_shared<ReflectedParamUpdater>();
5613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mParamUpdater->clear();
5623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mParamUpdater->addParamDesc(mReflector, mParamDescs);
5633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // TEMP: add some standard fields even if not reflected
5653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (kind.value == C2Component::KIND_ENCODER) {
5663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mParamUpdater->addStandardParam<C2StreamInitDataInfo::output>(C2_PARAMKEY_INIT_DATA);
5673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
568b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    if (kind.value != C2Component::KIND_ENCODER
569b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar            && (domain.value == C2Component::DOMAIN_IMAGE
570b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar                    || domain.value == C2Component::DOMAIN_VIDEO)) {
571b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam<C2StreamPictureSizeInfo::output>(C2_PARAMKEY_PICTURE_SIZE);
572b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam<C2StreamCropRectInfo::output>(C2_PARAMKEY_CROP_RECT);
573b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam(
574b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar                new C2StreamPixelAspectRatioInfo::output(0u, 1u, 1u),
575b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar                C2_PARAMKEY_PIXEL_ASPECT_RATIO);
576b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam(new C2StreamRotationInfo::output(0u, 0), C2_PARAMKEY_ROTATION);
577b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam(new C2StreamColorAspectsInfo::output(0u), C2_PARAMKEY_COLOR_ASPECTS);
578b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam<C2StreamHdrStaticInfo::output>(C2_PARAMKEY_HDR_STATIC_INFO);
579b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam<C2StreamDataSpaceInfo::output>(C2_PARAMKEY_DATA_SPACE);
580b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar        addLocalParam<C2StreamSurfaceScalingInfo::output>(C2_PARAMKEY_SURFACE_SCALING_MODE);
581b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar    }
5823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    initializeStandardParams();
5843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // subscribe to all supported standard (exposed) params
5863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // TODO: limit this to params that are actually in the domain
5873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<std::string> formatKeys = mStandardParams->getPathsForDomain(Domain(1 << 30));
5883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param::Index> indices;
5893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mParamUpdater->getParamIndicesForKeys(formatKeys, &indices);
5903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.insert(indices.begin(), indices.end());
5913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
5923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // also subscribe to some non-SDK standard parameters
5933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // for number of input/output buffers
5943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::input::PARAM_TYPE);
5953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::output::PARAM_TYPE);
5963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2ActualPipelineDelayTuning::PARAM_TYPE);
5973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2PortActualDelayTuning::input::PARAM_TYPE);
5983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2PortActualDelayTuning::output::PARAM_TYPE);
5993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // for output buffer array allocation
6003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2StreamMaxBufferSizeInfo::output::PARAM_TYPE);
6013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // init data (CSD)
6023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.emplace(C2StreamInitDataInfo::output::PARAM_TYPE);
6033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return OK;
6053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
6063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatus_t CCodecConfig::subscribeToConfigUpdate(
6083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const std::shared_ptr<Codec2Client::Component> &component,
6093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const std::vector<C2Param::Index> &indices,
6103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        c2_blocking_t blocking) {
6113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mSubscribedIndices.insert(indices.begin(), indices.end());
6123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // TODO: enable this when components no longer crash on this config
6133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (mSubscribedIndices.size() != mSubscribedIndicesSize && false) {
6143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<uint32_t> indices;
6153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        for (C2Param::Index ix : mSubscribedIndices) {
6163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            indices.push_back(ix);
6173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
6183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
6193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            C2SubscribedParamIndicesTuning::AllocUnique(indices);
6203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<std::unique_ptr<C2SettingResult>> results;
6213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        c2_status_t c2Err = component->config({ subscribeTuning.get() }, blocking, &results);
6223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (c2Err != C2_OK && c2Err != C2_BAD_INDEX) {
6233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            ALOGD("Failed to subscribe to parameters => %s", asString(c2Err));
6243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            // TODO: error
6253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
6263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
6273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mSubscribedIndicesSize = mSubscribedIndices.size();
6283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return OK;
6303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
6313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatus_t CCodecConfig::queryConfiguration(
6333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const std::shared_ptr<Codec2Client::Component> &component) {
6343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // query all subscribed parameters
6353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
6363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<std::unique_ptr<C2Param>> queried;
6373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    c2_status_t c2Err = component->query({}, indices, C2_MAY_BLOCK, &queried);
6383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (c2Err != OK) {
6393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGI("query failed after returning %zu values (%s)", queried.size(), asString(c2Err));
6403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // TODO: error
6413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    updateConfiguration(queried, ALL);
6443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return OK;
6453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
6463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarbool CCodecConfig::updateConfiguration(
6483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain) {
6493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("updating configuration with %zu params", configUpdate.size());
6503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    bool changed = false;
6513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    for (std::unique_ptr<C2Param> &p : configUpdate) {
6523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (p && *p) {
6533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
6543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (insertion.second || *insertion.first->second != *p) {
6553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                changed = true;
6563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
6573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            insertion.first->second = std::move(p);
6583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
6593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("updated configuration has %zu params (%s)", mCurrentConfig.size(),
6623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            changed ? "CHANGED" : "no change");
6633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (changed) {
6643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return updateFormats(domain);
6653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return false;
6673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
6683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarbool CCodecConfig::updateFormats(Domain domain) {
6703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // get addresses of params in the current config
6713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param*> paramPointers;
6723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    for (const auto &it : mCurrentConfig) {
6733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        paramPointers.push_back(it.second.get());
6743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ReflectedParamUpdater::Dict reflected = mParamUpdater->getParams(paramPointers);
6773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGD("c2 config is %s", reflected.debugString().c_str());
6783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
6793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    bool changed = false;
6803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (domain & mInputDomain) {
6813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        sp<AMessage> oldFormat = mInputFormat;
682c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar        mInputFormat->extend(getSdkFormatForDomain(reflected, mInputDomain));
683900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar        if (mInputFormat->countEntries() != oldFormat->countEntries()
684900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar                || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
6853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            changed = true;
6863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
6873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (domain & mOutputDomain) {
6893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        sp<AMessage> oldFormat = mOutputFormat;
690c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar        mOutputFormat->extend(getSdkFormatForDomain(reflected, mOutputDomain));
691900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar        if (!changed &&
692900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar                (mOutputFormat->countEntries() != oldFormat->countEntries()
693900cd38aeb849984fc40998539bbd75bf0333c83Lajos Molnar                        || mOutputFormat->changesFrom(oldFormat)->countEntries() > 0)) {
6943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            changed = true;
6953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
6963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
6973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV_IF(changed, "format(s) changed");
6983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return changed;
6993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
7003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarsp<AMessage> CCodecConfig::getSdkFormatForDomain(
7023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const ReflectedParamUpdater::Dict &reflected, Domain domain) const {
7033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    sp<AMessage> msg = new AMessage;
7043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
7053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        for (const ConfigMapper &cm : el.second) {
7063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if ((cm.domain() & domain) == 0 || (cm.domain() & mDomain) == 0) {
7073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                continue;
7083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
7093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            auto it = reflected.find(cm.path());
7103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (it == reflected.end()) {
7113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                continue;
7123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
7133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            C2Value c2Value;
7143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            sp<ABuffer> bufValue;
7153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            AString strValue;
7163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            AMessage::ItemData item;
7173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (it->second.find(&c2Value)) {
7183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                item = cm.mapToMessage(c2Value);
7193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else if (it->second.find(&bufValue)) {
7203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                item.set(bufValue);
7213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else if (it->second.find(&strValue)) {
7223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                item.set(strValue);
7233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else {
7243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
7253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                continue;
7263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
7273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->setItem(el.first.c_str(), item);
7283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
7293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
7303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
7323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t left, top, width, height;
7333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (msg->findInt32("crop-left", &left) && msg->findInt32("crop-width", &width)
7343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                && msg->findInt32("crop-top", &top) && msg->findInt32("crop-height", &height)
7353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                && left >= 0 && width >=0 && width <= INT32_MAX - left
7363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                && top >= 0 && height >=0 && height <= INT32_MAX - top) {
7373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->removeEntryAt(msg->findEntryByName("crop-left"));
7383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->removeEntryAt(msg->findEntryByName("crop-top"));
7393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->removeEntryAt(msg->findEntryByName("crop-width"));
7403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->removeEntryAt(msg->findEntryByName("crop-height"));
7413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->setRect("crop", left, top, left + width - 1, top + height - 1);
7423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        } else if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
7433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            msg->setRect("crop", 0, 0, width - 1, height - 1);
7443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
7453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
7463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("converted to SDK values as %s", msg->debugString().c_str());
7483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return msg;
7493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
7503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/// converts an AMessage value to a ParamUpdater value
7523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatic void convert(const AMessage::ItemData &from, ReflectedParamUpdater::Value *to) {
7533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    int32_t int32Value;
7543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    int64_t int64Value;
7553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    sp<ABuffer> bufValue;
7563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    AString strValue;
7573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    float floatValue;
7583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    double doubleValue;
7593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (from.find(&int32Value)) {
7613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(int32Value);
7623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (from.find(&int64Value)) {
7633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(int64Value);
7643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (from.find(&bufValue)) {
7653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(bufValue);
7663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (from.find(&strValue)) {
7673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(strValue);
7683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (from.find(&floatValue)) {
7693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(C2Value(floatValue));
7703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (from.find(&doubleValue)) {
7713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // convert double to float
7723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        to->set(C2Value((float)doubleValue));
7733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
7743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // ignore all other AMessage types
7753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
7763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/// relaxes Codec 2.0 specific value types to SDK types (mainly removes signedness and counterness
7783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar/// from 32/64-bit values.)
7793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatic void relaxValues(ReflectedParamUpdater::Value &item) {
7803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    C2Value c2Value;
7813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    int32_t int32Value;
7823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    int64_t int64Value;
7833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    (void)item.find(&c2Value);
7843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (c2Value.get(&int32Value) || c2Value.get((uint32_t*)&int32Value)
7853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            || c2Value.get((c2_cntr32_t*)&int32Value)) {
7863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        item.set(int32Value);
7873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else if (c2Value.get(&int64Value)
7883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            || c2Value.get((uint64_t*)&int64Value)
7893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            || c2Value.get((c2_cntr64_t*)&int64Value)) {
7903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        item.set(int64Value);
7913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
7923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
7933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
7943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos MolnarReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
7953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const sp<AMessage> &params_, Domain domain) const {
7963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // create a modifiable copy of params
7973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    sp<AMessage> params = params_->dup();
7983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("filtering with domain %x", domain);
7993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // convert some macro parameters to Codec 2.0 specific expressions
8013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    { // make i-frame-interval time based
8033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t iFrameInterval;
8043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (params->findInt32("i-frame-interval", &iFrameInterval)) {
8053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            int32_t intFrameRate;
8063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            float frameRate;
8073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (params->findInt32("frame-rate", &intFrameRate)) {
8083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                params->setInt32(C2_PARAMKEY_SYNC_FRAME_PERIOD, iFrameInterval * intFrameRate + 0.5);
8093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            } else if (params->findFloat("frame-rate", &frameRate)) {
8103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                params->setInt32(C2_PARAMKEY_SYNC_FRAME_PERIOD, iFrameInterval * frameRate + 0.5);
8113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
8123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
8133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
8143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    { // convert from MediaFormat rect to Codec 2.0 rect
8163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t offset;
8173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        int32_t end;
8183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        AMessage::ItemData item;
8193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (params->findInt32("crop-left", &offset) && params->findInt32("crop-right", &end)
8203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                && offset >= 0 && end >= offset - 1) {
8213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            size_t ix = params->findEntryByName("crop-right");
8223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            params->setEntryNameAt(ix, "crop-width");
8233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set(end - offset + 1);
8243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            params->setEntryAt(ix, item);
8253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
8263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (params->findInt32("crop-top", &offset) && params->findInt32("crop-bottom", &end)
8273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                && offset >= 0 && end >= offset - 1) {
8283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            size_t ix = params->findEntryByName("crop-bottom");
8293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            params->setEntryNameAt(ix, "crop-height");
8303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            item.set(end - offset + 1);
8313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            params->setEntryAt(ix, item);
8323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
8333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
8343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // this is to verify that we set proper signedness for standard parameters
8363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
8373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // this is to allow vendors to use the wrong signedness for standard parameters
8383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    bool beVeryLax = property_get_bool("debug.stagefright.ccodec_lax_type", false);
8393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ReflectedParamUpdater::Dict filtered;
8413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    for (size_t ix = 0; ix < params->countEntries(); ++ix) {
8423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        AMessage::Type type;
8433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        AString name = params->getEntryNameAt(ix, &type);
8443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        AMessage::ItemData msgItem = params->getEntryAt(ix);
8453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ReflectedParamUpdater::Value item;
8463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        convert(msgItem, &item); // convert item to param updater item
8473bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        if (name.startsWith("vendor.")) {
8493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            // vendor params pass through as is
8503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            filtered.emplace(name.c_str(), item);
8513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            continue;
8523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
8533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // standard parameters may get modified, filtered or duplicated
8543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        for (const ConfigMapper &cm : mStandardParams->getConfigMappersForSdkKey(name.c_str())) {
8553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            if (cm.domain() & domain & mDomain) {
8563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                // map arithmetic values, pass through string or buffer
8573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                switch (type) {
8583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeBuffer:
8593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeString:
8603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        break;
8613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeInt32:
8623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeInt64:
8633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeFloat:
8643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    case AMessage::kTypeDouble:
8653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        // for now only map settings with mappers as we are not creating
8663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        // signed <=> unsigned mappers
8673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        // TODO: be precise about signed unsigned
8683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        if (beVeryStrict || cm.mapper()) {
8693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                            item.set(cm.mapFromMessage(params->getEntryAt(ix)));
8703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                            // also allow to relax type strictness
8713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                            if (beVeryLax) {
8723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                                relaxValues(item);
8733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                            }
8743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        }
8753bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        break;
8763bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                    default:
8773bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                        continue;
8783bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                }
8793bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar                filtered.emplace(cm.path(), item);
8803bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            }
8813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        }
8823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
8833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ALOGV("filtered %s to %s", params->debugString(4).c_str(),
8843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar            filtered.debugString(4).c_str());
8853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return filtered;
8863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
8873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatus_t CCodecConfig::getConfigUpdateFromSdkParams(
8893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::shared_ptr<Codec2Client::Component> component,
8903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        const sp<AMessage> &sdkParams, Domain domain,
8913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        c2_blocking_t blocking,
8923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<std::unique_ptr<C2Param>> *configUpdate) const {
8933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    ReflectedParamUpdater::Dict params = getReflectedFormat(sdkParams, domain);
8943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
8953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param::Index> indices;
8963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    mParamUpdater->getParamIndicesFromMessage(params, &indices);
8973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (indices.empty()) {
8983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("no recognized params in: %s", params.debugString().c_str());
8993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return OK;
9003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    configUpdate->clear();
903b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar    std::vector<C2Param::Index> supportedIndices;
904b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar    for (C2Param::Index ix : indices) {
905b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar        if (mSupportedIndices.count(ix)) {
906b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar            supportedIndices.push_back(ix);
907b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar        } else if (mLocalParams.count(ix)) {
908b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar            // query local parameter here
909b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar            auto it = mCurrentConfig.find(ix);
910e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar            if (it != mCurrentConfig.end()) {
911e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar                configUpdate->emplace_back(C2Param::Copy(*it->second));
912e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar            }
913b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar        }
914b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar    }
915b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar
916b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar    c2_status_t err = component->query({ }, supportedIndices, blocking, configUpdate);
9173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (err != C2_OK) {
9183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("query failed after returning %zu params => %s", configUpdate->size(), asString(err));
9193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (configUpdate->size()) {
9223bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        mParamUpdater->updateParamsFromMessage(params, configUpdate);
9233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    return OK;
9253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
9263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarstatus_t CCodecConfig::setParameters(
9283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::shared_ptr<Codec2Client::Component> component,
9293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        std::vector<std::unique_ptr<C2Param>> &configUpdate,
9303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        c2_blocking_t blocking) {
931dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar    status_t result = OK;
9323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (configUpdate.empty()) {
9333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return OK;
9343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param::Index> indices;
9373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<C2Param *> paramVector;
9383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    for (const std::unique_ptr<C2Param> &param : configUpdate) {
939dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar        if (mSupportedIndices.count(param->index())) {
940dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            // component parameter
941dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            paramVector.push_back(param.get());
942dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            indices.push_back(param->index());
943dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar        } else if (mLocalParams.count(param->index())) {
944dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            // handle local parameter here
945dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            LocalParamValidator validator = mLocalParams.find(param->index())->second;
946dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            c2_status_t err = C2_OK;
947dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            std::unique_ptr<C2Param> copy = C2Param::Copy(*param);
948dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            if (validator) {
949dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar                err = validator(copy);
950dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            }
951dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            if (err == C2_OK) {
952b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar                ALOGV("updated local parameter value for %s",
953b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar                        mParamUpdater->getParamName(param->index()).c_str());
954b342d363b88acb36415a0d0c752d06eee99392dfLajos Molnar
955dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar                mCurrentConfig[param->index()] = std::move(copy);
956dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            } else {
957dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar                ALOGD("failed to set parameter value for %s => %s",
958dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar                        mParamUpdater->getParamName(param->index()).c_str(), asString(err));
959dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar                result = BAD_VALUE;
960dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar            }
961dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar        }
9623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // update subscribed param indices
9643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    subscribeToConfigUpdate(component, indices, blocking);
9653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    std::vector<std::unique_ptr<C2SettingResult>> failures;
9673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    c2_status_t err = component->config(paramVector, blocking, &failures);
9683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (err != C2_OK) {
9693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("config failed => %s", asString(err));
9703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        // This is non-fatal.
9713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9723078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim    for (const std::unique_ptr<C2SettingResult> &failure : failures) {
9733078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim        switch (failure->failure) {
9743078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim            case C2SettingResult::BAD_VALUE:
9753078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim                ALOGD("Bad parameter value");
9763078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim                result = BAD_VALUE;
9773078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim                break;
9783078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim            default:
9793078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim                ALOGV("failure = %d", int(failure->failure));
9803078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim                break;
9813078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim        }
9823078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim    }
9833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // Re-query parameter values in case config could not update them and update the current
9853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // configuration.
9863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    configUpdate.clear();
9873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    err = component->query({}, indices, blocking, &configUpdate);
9883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (err != C2_OK) {
9893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        ALOGD("query failed after returning %zu params => %s", configUpdate.size(), asString(err));
9903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
9913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    (void)updateConfiguration(configUpdate, ALL);
9923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    // TODO: error value
994dde7fcc060b3af0a4e8d3ba1109b4ba48bcc3b3aLajos Molnar    return result;
9953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
9963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
9973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarconst C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const {
9983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    auto it = mCurrentConfig.find(index);
9993bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    if (it == mCurrentConfig.end()) {
10003bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return nullptr;
10013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    } else {
10023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar        return it->second.get();
10033bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar    }
10043bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}
10053bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
10063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar}  // namespace android
10073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar
1008