• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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