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