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