1 /*
2 * Copyright 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Codec2-Configurable"
19 #include <android-base/logging.h>
20
21 #include <codec2/hidl/1.0/Configurable.h>
22 #include <codec2/hidl/1.0/ComponentStore.h>
23 #include <codec2/hidl/1.0/types.h>
24
25 #include <C2ParamInternal.h>
26
27 namespace android {
28 namespace hardware {
29 namespace media {
30 namespace c2 {
31 namespace V1_0 {
32 namespace utils {
33
34 using namespace ::android;
35
CachedConfigurable(std::unique_ptr<ConfigurableC2Intf> && intf)36 CachedConfigurable::CachedConfigurable(
37 std::unique_ptr<ConfigurableC2Intf>&& intf)
38 : mIntf{std::move(intf)} {
39 }
40
init(const std::shared_ptr<ParameterCache> & cache)41 c2_status_t CachedConfigurable::init(
42 const std::shared_ptr<ParameterCache>& cache) {
43 // Retrieve supported parameters from store
44 c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
45 c2_status_t validate = cache->validate(mSupportedParams);
46 return init == C2_OK ? C2_OK : validate;
47 }
48
49 // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
getId()50 Return<uint32_t> CachedConfigurable::getId() {
51 return mIntf->getId();
52 }
53
getName(getName_cb _hidl_cb)54 Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) {
55 _hidl_cb(mIntf->getName());
56 return Void();
57 }
58
query(const hidl_vec<uint32_t> & indices,bool mayBlock,query_cb _hidl_cb)59 Return<void> CachedConfigurable::query(
60 const hidl_vec<uint32_t>& indices,
61 bool mayBlock,
62 query_cb _hidl_cb) {
63 typedef C2Param::Index Index;
64 std::vector<Index> c2heapParamIndices(
65 (Index*)indices.data(),
66 (Index*)indices.data() + indices.size());
67 std::vector<std::unique_ptr<C2Param>> c2heapParams;
68 c2_status_t c2res = mIntf->query(
69 c2heapParamIndices,
70 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
71 &c2heapParams);
72
73 hidl_vec<uint8_t> params;
74 if (!createParamsBlob(¶ms, c2heapParams)) {
75 LOG(WARNING) << "query -- invalid output params.";
76 }
77 _hidl_cb(static_cast<Status>(c2res), params);
78 return Void();
79 }
80
config(const hidl_vec<uint8_t> & inParams,bool mayBlock,config_cb _hidl_cb)81 Return<void> CachedConfigurable::config(
82 const hidl_vec<uint8_t>& inParams,
83 bool mayBlock,
84 config_cb _hidl_cb) {
85 // inParams is not writable, so create a copy as config modifies the parameters
86 hidl_vec<uint8_t> inParamsCopy = inParams;
87 std::vector<C2Param*> c2params;
88 if (!parseParamsBlob(&c2params, inParamsCopy)) {
89 LOG(WARNING) << "config -- invalid input params.";
90 _hidl_cb(Status::CORRUPTED,
91 hidl_vec<SettingResult>(),
92 hidl_vec<uint8_t>());
93 return Void();
94 }
95 // TODO: check if blob was invalid
96 std::vector<std::unique_ptr<C2SettingResult>> c2failures;
97 c2_status_t c2res = mIntf->config(
98 c2params,
99 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
100 &c2failures);
101 hidl_vec<SettingResult> failures(c2failures.size());
102 {
103 size_t ix = 0;
104 for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
105 if (c2result) {
106 if (objcpy(&failures[ix], *c2result)) {
107 ++ix;
108 } else {
109 LOG(DEBUG) << "config -- invalid setting results.";
110 break;
111 }
112 }
113 }
114 failures.resize(ix);
115 }
116 hidl_vec<uint8_t> outParams;
117 if (!createParamsBlob(&outParams, c2params)) {
118 LOG(DEBUG) << "config -- invalid output params.";
119 }
120 _hidl_cb((Status)c2res, failures, outParams);
121 return Void();
122 }
123
querySupportedParams(uint32_t start,uint32_t count,querySupportedParams_cb _hidl_cb)124 Return<void> CachedConfigurable::querySupportedParams(
125 uint32_t start,
126 uint32_t count,
127 querySupportedParams_cb _hidl_cb) {
128 C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range(
129 start, count);
130 hidl_vec<ParamDescriptor> params(request.size());
131 Status res = Status::OK;
132 size_t dstIx = 0;
133 for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
134 if (mSupportedParams[srcIx]) {
135 if (objcpy(¶ms[dstIx], *mSupportedParams[srcIx])) {
136 ++dstIx;
137 } else {
138 res = Status::CORRUPTED;
139 LOG(WARNING) << "querySupportedParams -- invalid output params.";
140 break;
141 }
142 } else {
143 res = Status::BAD_INDEX;
144 }
145 }
146 params.resize(dstIx);
147 _hidl_cb(res, params);
148 return Void();
149 }
150
querySupportedValues(const hidl_vec<FieldSupportedValuesQuery> & inFields,bool mayBlock,querySupportedValues_cb _hidl_cb)151 Return<void> CachedConfigurable::querySupportedValues(
152 const hidl_vec<FieldSupportedValuesQuery>& inFields,
153 bool mayBlock,
154 querySupportedValues_cb _hidl_cb) {
155 std::vector<C2FieldSupportedValuesQuery> c2fields;
156 {
157 // C2FieldSupportedValuesQuery objects are restricted in that some
158 // members are const.
159 // C2ParamField - required for its constructor - has no constructors
160 // from fields. Use C2ParamInspector.
161 for (const FieldSupportedValuesQuery &query : inFields) {
162 c2fields.emplace_back(_C2ParamInspector::CreateParamField(
163 query.field.index,
164 query.field.fieldId.offset,
165 query.field.fieldId.size),
166 query.type == FieldSupportedValuesQuery::Type::POSSIBLE ?
167 C2FieldSupportedValuesQuery::POSSIBLE :
168 C2FieldSupportedValuesQuery::CURRENT);
169 }
170 }
171 c2_status_t c2res = mIntf->querySupportedValues(
172 c2fields,
173 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK);
174 hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size());
175 size_t dstIx = 0;
176 for (const C2FieldSupportedValuesQuery &result : c2fields) {
177 if (objcpy(&outFields[dstIx], result)) {
178 ++dstIx;
179 } else {
180 outFields.resize(dstIx);
181 c2res = C2_CORRUPTED;
182 LOG(WARNING) << "querySupportedValues -- invalid output params.";
183 break;
184 }
185 }
186 _hidl_cb((Status)c2res, outFields);
187 return Void();
188 }
189
190 } // namespace utils
191 } // namespace V1_0
192 } // namespace c2
193 } // namespace media
194 } // namespace hardware
195 } // namespace android
196
197