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; ValueValue60 explicit Value(C2Value i) { set(i); } ValueValue61 explicit Value(int32_t i) { set(i); } ValueValue62 explicit Value(int64_t i) { set(i); } ValueValue63 explicit Value(const AString &i) { set(i); } ValueValue64 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 /** 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 /** 179 * Get field type for the given name 180 * 181 * \param key[in] field name 182 * \return type of the field, or type_t(~0) if not found. 183 */ 184 C2FieldDescriptor::type_t getTypeForKey(const std::string &name) const; 185 186 /** 187 * Update C2Param objects from field name and value in AMessage object. 188 * 189 * \param params[in] Dict object with field name to value pairs. 190 * \param vec[in,out] vector of the C2Param objects to be updated. 191 */ 192 void updateParamsFromMessage( 193 const Dict ¶ms, 194 std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const; 195 196 /** 197 * Get fields from C2Param objects in AMessage object. 198 * 199 * \param params[in] vector of the C2Param objects to be queried 200 * \return a Dict object containing the known parameters 201 */ 202 Dict getParams( 203 const std::vector<C2Param*> ¶ms /* nonnull */) const; 204 205 Dict getParams( 206 const std::vector<std::unique_ptr<C2Param>> ¶ms /* nonnull */) const; 207 208 /** 209 * Clear param descriptors in this object. 210 */ 211 void clear(); 212 213 private: 214 struct FieldDesc { 215 std::shared_ptr<C2ParamDescriptor> paramDesc; 216 std::unique_ptr<C2FieldDescriptor> fieldDesc; 217 size_t offset; 218 }; 219 std::map<std::string, FieldDesc> mMap; 220 std::map<C2Param::Index, std::string> mParamNames; 221 std::map<std::string, C2Param::CoreIndex> mWholeParams; 222 223 void parseMessageAndDoWork( 224 const Dict ¶ms, 225 std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const; 226 227 C2_DO_NOT_COPY(ReflectedParamUpdater); 228 }; 229 230 } // namespace android 231 232 #endif // REFLECTED_PARAM_BUILDER_H_ 233