Home | History | Annotate | Download | only in sfplugin
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef REFLECTED_PARAM_BUILDER_H_
     18 #define REFLECTED_PARAM_BUILDER_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 
     23 #include <C2.h>
     24 #include <C2Param.h>
     25 
     26 #include <media/stagefright/foundation/ABuffer.h>
     27 #include <media/stagefright/foundation/AData.h>
     28 #include <media/stagefright/foundation/AMessage.h>
     29 #include <media/stagefright/foundation/AString.h>
     30 
     31 namespace android {
     32 
     33 /**
     34  * Utility class to query and update Codec 2.0 configuration values. Use custom dictionary as
     35  * AMessage cannot represent all types of Codec 2.0 parameters and C2Value cannot represent
     36  * all types of SDK values. We want to be precise when setting standard parameters (use C2Value
     37  * for arithmetic values), but also support int32 and int64 for SDK values specifically for
     38  * vendor parameters (as SDK API does not allow specifying proper type.) When querying fields,
     39  * we can use C2Values as they are defined.
     40  *
     41  *      Item => Codec 2.0 value mappings:
     42  *     CValue::type => type
     43  *     int32 => int32, ctr32 or uint32
     44  *     int64 => int64, ctr64 or uint64
     45  *     AString => string
     46  *     ABuffer => blob
     47  *     'Rect' => C2RectStruct (not exposed in SDK as a rectangle)
     48  */
     49 class ReflectedParamUpdater {
     50 public:
     51     ReflectedParamUpdater() = default;
     52     ~ReflectedParamUpdater() = default;
     53 
     54     /**
     55      * Element for values
     56      */
     57     struct Value : public AData<C2Value, int32_t, int64_t, AString, sp<ABuffer>>::Basic {
     58         // allow construction from base types
     59         Value() = default;
     60         explicit Value(C2Value i)            { set(i); }
     61         explicit Value(int32_t i)            { set(i); }
     62         explicit Value(int64_t i)            { set(i); }
     63         explicit Value(const AString &i)     { set(i); }
     64         explicit Value(const sp<ABuffer> &i) { set(i); }
     65     };
     66 
     67     struct Dict : public std::map<std::string, Value> {
     68         Dict() = default;
     69         std::string debugString(size_t indent = 0) const;
     70     };
     71 
     72     /**
     73      * Enumerates all fields of the parameter descriptors supplied, so that this opbject can later
     74      * query and update these.
     75      *
     76      * For now only first-level fields are supported. Also, array fields are not supported.
     77      *
     78      * \param reflector   C2ParamReflector object for C2Param reflection.
     79      * \param paramDescs  vector of C2ParamDescriptor objects that this object
     80      *                    would recognize when building params.
     81      */
     82     void addParamDesc(
     83             const std::shared_ptr<C2ParamReflector> &reflector,
     84             const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs);
     85 
     86     /**
     87      * Adds fields of a standard parameter (that may not be supported by the parameter reflector
     88      * or may not be listed as a supported value by the component). If the parameter name is
     89      * used for another parameter, this operation is a no-op. (Technically, this is by fields).
     90      *
     91      * \param T standard parameter type
     92      * \param name parameter name
     93      */
     94     template<typename T>
     95     void addStandardParam(const std::string &name, C2ParamDescriptor::attrib_t attrib =
     96                           C2ParamDescriptor::IS_READ_ONLY) {
     97         addParamDesc(std::make_shared<C2ParamDescriptor>(
     98                 C2Param::Index(T::PARAM_TYPE), attrib, name.c_str()),
     99                 C2StructDescriptor((T*)nullptr), nullptr /* descriptor */);
    100     }
    101 
    102     /**
    103      * Adds fields of a structure (or a parameater) described by the struct descriptor. If
    104      * reflector is provided, fields of sub-structures are also added. Otherwise, only top-level
    105      * fundamental typed fields (arithmetic, string and blob) are added.
    106      *
    107      * \param paramDesc parameter descriptor
    108      * \param fieldDesc field descriptor
    109      * \param path path/name of the structure (field or parent parameter)
    110      * \param offset offset of the structure in the parameter
    111      * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
    112      */
    113     void addParamStructDesc(
    114             std::shared_ptr<C2ParamDescriptor> paramDesc, C2String path, size_t offset,
    115             const C2StructDescriptor &structDesc,
    116             const std::shared_ptr<C2ParamReflector> &reflector);
    117 
    118     /**
    119      * Adds fields of a parameter described by the struct descriptor. If reflector is provided,
    120      * fields of sub-structures are also added. Otherwise, only top-level fundamental typed fields
    121      * (arithmetic, string and blob) are added.
    122      *
    123      * \param paramDesc parameter descriptor
    124      * \param fieldDesc field descriptor
    125      * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
    126      * \param markVendor TEMP if true, prefix vendor parameter names with "vendor."
    127      */
    128     void addParamDesc(
    129             std::shared_ptr<C2ParamDescriptor> paramDesc, const C2StructDescriptor &structDesc,
    130             const std::shared_ptr<C2ParamReflector> &reflector,
    131             bool markVendor = true);
    132 
    133     /**
    134      * Add support for setting a parameter as a binary blob.
    135      *
    136      * \param name name of the parameter
    137      * \param coreIndex parameter (core) index
    138      */
    139     void supportWholeParam(std::string name, C2Param::CoreIndex coreIndex);
    140 
    141     /**
    142      * Returns the name of the parameter for an index.
    143      */
    144     std::string getParamName(C2Param::Index index) const;
    145 
    146     /**
    147      * Get list of param indices from field names and values in AMessage object.
    148      *
    149      * TODO: This should be in the order that they are listed by the component.
    150      *
    151      * \param params[in]  Dict object with field name to value pairs.
    152      * \param vec[out]    vector to store the indices from |params|.
    153      */
    154     void getParamIndicesFromMessage(
    155             const Dict &params,
    156             std::vector<C2Param::Index> *vec /* nonnull */) const;
    157 
    158     /**
    159      * Get list of param indices from field names (only) in AMessage object.
    160      *
    161      * \param params[in]  Vector object with field names.
    162      * \param vec[out]    vector to store the indices from |params|.
    163      */
    164     void getParamIndicesForKeys(
    165             const std::vector<std::string> &keys,
    166             std::vector<C2Param::Index> *vec /* nonnull */) const;
    167 
    168     /**
    169      * Update C2Param objects from field name and value in AMessage object.
    170      *
    171      * \param params[in]    Dict object with field name to value pairs.
    172      * \param vec[in,out]   vector of the C2Param objects to be updated.
    173      */
    174     void updateParamsFromMessage(
    175             const Dict &params,
    176             std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const;
    177 
    178     /**
    179      * Get fields from C2Param objects in AMessage object.
    180      *
    181      * \param params[in]    vector of the C2Param objects to be queried
    182      * \return a Dict object containing the known parameters
    183      */
    184     Dict getParams(
    185             const std::vector<C2Param*> &params /* nonnull */) const;
    186 
    187     Dict getParams(
    188             const std::vector<std::unique_ptr<C2Param>> &params /* nonnull */) const;
    189 
    190     /**
    191      * Clear param descriptors in this object.
    192      */
    193     void clear();
    194 
    195 private:
    196     struct FieldDesc {
    197         std::shared_ptr<C2ParamDescriptor> paramDesc;
    198         std::unique_ptr<C2FieldDescriptor> fieldDesc;
    199         size_t offset;
    200     };
    201     std::map<std::string, FieldDesc> mMap;
    202     std::map<C2Param::Index, std::string> mParamNames;
    203     std::map<std::string, C2Param::CoreIndex> mWholeParams;
    204 
    205     void parseMessageAndDoWork(
    206             const Dict &params,
    207             std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const;
    208 
    209     C2_DO_NOT_COPY(ReflectedParamUpdater);
    210 };
    211 
    212 }  // namespace android
    213 
    214 #endif  // REFLECTED_PARAM_BUILDER_H_
    215