Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 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>> ¶mDescs); |
| 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 ¶ms, |
| 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 | /** |
Wonsik Kim | 8a6ed37 | 2019-12-03 16:05:51 -0800 | [diff] [blame] | 169 | * Get list of field names for the given param index. |
| 170 | * |
| 171 | * \param index[in] param index |
| 172 | * \param keys[out] vector to store the field names |
| 173 | */ |
| 174 | void getKeysForParamIndex( |
| 175 | const C2Param::Index &index, |
| 176 | std::vector<std::string> *keys /* nonnull */) const; |
| 177 | |
| 178 | /** |
Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 179 | * Update C2Param objects from field name and value in AMessage object. |
| 180 | * |
| 181 | * \param params[in] Dict object with field name to value pairs. |
| 182 | * \param vec[in,out] vector of the C2Param objects to be updated. |
| 183 | */ |
| 184 | void updateParamsFromMessage( |
| 185 | const Dict ¶ms, |
| 186 | std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const; |
| 187 | |
| 188 | /** |
| 189 | * Get fields from C2Param objects in AMessage object. |
| 190 | * |
| 191 | * \param params[in] vector of the C2Param objects to be queried |
| 192 | * \return a Dict object containing the known parameters |
| 193 | */ |
| 194 | Dict getParams( |
| 195 | const std::vector<C2Param*> ¶ms /* nonnull */) const; |
| 196 | |
| 197 | Dict getParams( |
| 198 | const std::vector<std::unique_ptr<C2Param>> ¶ms /* nonnull */) const; |
| 199 | |
| 200 | /** |
| 201 | * Clear param descriptors in this object. |
| 202 | */ |
| 203 | void clear(); |
| 204 | |
| 205 | private: |
| 206 | struct FieldDesc { |
| 207 | std::shared_ptr<C2ParamDescriptor> paramDesc; |
| 208 | std::unique_ptr<C2FieldDescriptor> fieldDesc; |
| 209 | size_t offset; |
| 210 | }; |
| 211 | std::map<std::string, FieldDesc> mMap; |
| 212 | std::map<C2Param::Index, std::string> mParamNames; |
| 213 | std::map<std::string, C2Param::CoreIndex> mWholeParams; |
| 214 | |
| 215 | void parseMessageAndDoWork( |
| 216 | const Dict ¶ms, |
| 217 | std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const; |
| 218 | |
| 219 | C2_DO_NOT_COPY(ReflectedParamUpdater); |
| 220 | }; |
| 221 | |
| 222 | } // namespace android |
| 223 | |
| 224 | #endif // REFLECTED_PARAM_BUILDER_H_ |