blob: 5436ba566713bbf9b582c98fa0be0a5c9b7210b7 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
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
31namespace 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 */
49class ReflectedParamUpdater {
50public:
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
195private:
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_