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-ComponentInterface"
19 #include <android-base/logging.h>
20
21 #include <codec2/hidl/1.0/Component.h>
22 #include <codec2/hidl/1.0/ComponentInterface.h>
23 #include <codec2/hidl/1.0/ComponentStore.h>
24
25 #include <hidl/HidlBinderSupport.h>
26 #include <utils/Timers.h>
27
28 #include <C2Debug.h>
29 #include <C2PlatformSupport.h>
30
31 #include <chrono>
32 #include <thread>
33
34 namespace android {
35 namespace hardware {
36 namespace media {
37 namespace c2 {
38 namespace V1_0 {
39 namespace utils {
40
41 using namespace ::android;
42
43 namespace /* unnamed */ {
44
45 // Implementation of ConfigurableC2Intf based on C2ComponentInterface
46 struct CompIntf : public ConfigurableC2Intf {
CompIntfandroid::hardware::media::c2::V1_0::utils::__anon4a050a7e0111::CompIntf47 CompIntf(const std::shared_ptr<C2ComponentInterface>& intf,
48 const std::shared_ptr<MultiAccessUnitInterface>& multiAccessUnitIntf):
49 ConfigurableC2Intf{intf->getName(), intf->getId()},
50 mIntf{intf}, mMultiAccessUnitIntf{multiAccessUnitIntf} {
51 }
52
configandroid::hardware::media::c2::V1_0::utils::__anon4a050a7e0111::CompIntf53 virtual c2_status_t config(
54 const std::vector<C2Param*>& params,
55 c2_blocking_t mayBlock,
56 std::vector<std::unique_ptr<C2SettingResult>>* const failures
57 ) override {
58 std::vector<C2Param*> paramsToIntf;
59 std::vector<C2Param*> paramsToLargeFrameIntf;
60 c2_status_t err = C2_OK;
61 if (mMultiAccessUnitIntf == nullptr) {
62 err = mIntf->config_vb(params, mayBlock, failures);
63 return err;
64 }
65 for (auto &p : params) {
66 if (mMultiAccessUnitIntf->isParamSupported(p->index())) {
67 paramsToLargeFrameIntf.push_back(p);
68 } else {
69 paramsToIntf.push_back(p);
70 }
71 }
72 c2_status_t err1 = C2_OK;
73 if (paramsToIntf.size() > 0) {
74 err1 = mIntf->config_vb(paramsToIntf, mayBlock, failures);
75 }
76 if (err1 != C2_OK) {
77 LOG(ERROR) << "We have a failed config";
78 }
79 c2_status_t err2 = C2_OK;
80 if (paramsToLargeFrameIntf.size() > 0) {
81 C2ComponentKindSetting kind;
82 C2StreamMaxBufferSizeInfo::input maxInputSize(0);
83 c2_status_t err = mIntf->query_vb(
84 {&kind, &maxInputSize}, {}, C2_MAY_BLOCK, nullptr);
85 if ((err == C2_OK) && (kind.value == C2Component::KIND_ENCODER)) {
86 for (int i = 0 ; i < paramsToLargeFrameIntf.size(); i++) {
87 if (paramsToLargeFrameIntf[i]->index() ==
88 C2LargeFrame::output::PARAM_TYPE) {
89 C2LargeFrame::output *lfp = C2LargeFrame::output::From(
90 paramsToLargeFrameIntf[i]);
91 // This is assuming a worst case compression ratio of 1:1
92 // In no case the encoder should give an output more than
93 // what is being provided to the encoder in a single call.
94 if (lfp && (lfp->maxSize < maxInputSize.value)) {
95 lfp->maxSize = maxInputSize.value;
96 }
97 break;
98 }
99 }
100 }
101 err2 = mMultiAccessUnitIntf->config(
102 paramsToLargeFrameIntf, mayBlock, failures);
103 }
104 // TODO: correct failure vector
105 return err1 != C2_OK ? err1 : err2;
106 }
107
queryandroid::hardware::media::c2::V1_0::utils::__anon4a050a7e0111::CompIntf108 virtual c2_status_t query(
109 const std::vector<C2Param::Index>& indices,
110 c2_blocking_t mayBlock,
111 std::vector<std::unique_ptr<C2Param>>* const params
112 ) const override {
113 c2_status_t err = C2_OK;
114 if (mMultiAccessUnitIntf == nullptr) {
115 err = mIntf->query_vb({}, indices, mayBlock, params);
116 return err;
117 }
118 std::vector<C2Param::Index> paramsToIntf;
119 std::vector<C2Param::Index> paramsToLargeFrameIntf;
120 for (auto &i : indices) {
121 if (mMultiAccessUnitIntf->isParamSupported(i)) {
122 paramsToLargeFrameIntf.push_back(i);
123 } else {
124 paramsToIntf.push_back(i);
125 }
126 }
127 c2_status_t err1 = C2_OK;
128 if (paramsToIntf.size() > 0) {
129 err1 = mIntf->query_vb({}, paramsToIntf, mayBlock, params);
130 }
131 c2_status_t err2 = C2_OK;
132 if (paramsToLargeFrameIntf.size() > 0) {
133 err2 = mMultiAccessUnitIntf->query(
134 {}, paramsToLargeFrameIntf, mayBlock, params);
135 }
136 // TODO: correct failure vector
137 return err1 != C2_OK ? err1 : err2;
138 }
139
querySupportedParamsandroid::hardware::media::c2::V1_0::utils::__anon4a050a7e0111::CompIntf140 virtual c2_status_t querySupportedParams(
141 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
142 ) const override {
143 c2_status_t err = mIntf->querySupportedParams_nb(params);
144 if (mMultiAccessUnitIntf != nullptr) {
145 err = mMultiAccessUnitIntf->querySupportedParams(params);
146 }
147 return err;
148 }
149
querySupportedValuesandroid::hardware::media::c2::V1_0::utils::__anon4a050a7e0111::CompIntf150 virtual c2_status_t querySupportedValues(
151 std::vector<C2FieldSupportedValuesQuery>& fields,
152 c2_blocking_t mayBlock) const override {
153 if (mMultiAccessUnitIntf == nullptr) {
154 return mIntf->querySupportedValues_vb(fields, mayBlock);
155 }
156 std::vector<C2FieldSupportedValuesQuery> dup = fields;
157 std::vector<C2FieldSupportedValuesQuery> queryArray[2];
158 std::map<C2ParamField, std::pair<uint32_t, size_t>> queryMap;
159 c2_status_t err = C2_OK;
160 for (int i = 0 ; i < fields.size(); i++) {
161 const C2ParamField &field = fields[i].field();
162 uint32_t queryArrayIdx = 1;
163 if (mMultiAccessUnitIntf->isValidField(field)) {
164 queryArrayIdx = 0;
165 }
166 queryMap[field] = std::make_pair(
167 queryArrayIdx, queryArray[queryArrayIdx].size());
168 queryArray[queryArrayIdx].push_back(fields[i]);
169 }
170 if (queryArray[0].size() > 0) {
171 err = mMultiAccessUnitIntf->querySupportedValues(queryArray[0], mayBlock);
172 }
173 if (queryArray[1].size() > 0) {
174 err = mIntf->querySupportedValues_vb(queryArray[1], mayBlock);
175 }
176 for (int i = 0 ; i < dup.size(); i++) {
177 auto it = queryMap.find(dup[i].field());
178 if (it != queryMap.end()) {
179 std::pair<uint32_t, size_t> queryid = it->second;
180 fields[i] = queryArray[queryid.first][queryid.second];
181 }
182 }
183 return err;
184 }
185
186 protected:
187 std::shared_ptr<C2ComponentInterface> mIntf;
188 std::shared_ptr<MultiAccessUnitInterface> mMultiAccessUnitIntf;
189 };
190
191 } // unnamed namespace
192
193
194 // ComponentInterface
ComponentInterface(const std::shared_ptr<C2ComponentInterface> & intf,const std::shared_ptr<ParameterCache> & cache)195 ComponentInterface::ComponentInterface(
196 const std::shared_ptr<C2ComponentInterface>& intf,
197 const std::shared_ptr<ParameterCache>& cache):ComponentInterface(intf, nullptr, cache) {
198 }
199
ComponentInterface(const std::shared_ptr<C2ComponentInterface> & intf,const std::shared_ptr<MultiAccessUnitInterface> & multiAccessUnitIntf,const std::shared_ptr<ParameterCache> & cache)200 ComponentInterface::ComponentInterface(
201 const std::shared_ptr<C2ComponentInterface>& intf,
202 const std::shared_ptr<MultiAccessUnitInterface>& multiAccessUnitIntf,
203 const std::shared_ptr<ParameterCache>& cache)
204 : mInterface{intf},
205 mConfigurable{new CachedConfigurable(
206 std::make_unique<CompIntf>(intf, multiAccessUnitIntf))} {
207 mInit = mConfigurable->init(cache);
208 }
209
status() const210 c2_status_t ComponentInterface::status() const {
211 return mInit;
212 }
213
getConfigurable()214 Return<sp<IConfigurable>> ComponentInterface::getConfigurable() {
215 return mConfigurable;
216 }
217
218 } // namespace utils
219 } // namespace V1_0
220 } // namespace c2
221 } // namespace media
222 } // namespace hardware
223 } // namespace android
224
225