xref: /aosp_15_r20/frameworks/av/media/codec2/hal/aidl/ComponentInterface.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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