blob: e3f8b1c24321d5811d7d793276e926621c8ce5a5 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002 * Copyright 2018 The Android Open Source Project
Pawin Vongmasa36653902018-11-15 00:10:25 -08003 *
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 "Codec2Client"
Pawin Vongmasa1c75a232019-01-09 04:41:52 -080019#include <android-base/logging.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080020
21#include <codec2/hidl/client.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070022#include <C2Debug.h>
23#include <C2BufferPriv.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080024#include <C2Config.h> // for C2StreamUsageTuning
Pawin Vongmasabf69de92019-10-29 06:21:27 -070025#include <C2PlatformSupport.h>
26
27#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
28#include <android/hardware/media/c2/1.0/IComponent.h>
29#include <android/hardware/media/c2/1.0/IComponentInterface.h>
30#include <android/hardware/media/c2/1.0/IComponentListener.h>
31#include <android/hardware/media/c2/1.0/IComponentStore.h>
32#include <android/hardware/media/c2/1.0/IConfigurable.h>
33#include <android/hidl/manager/1.2/IServiceManager.h>
34
Wonsik Kime8e98152022-12-16 16:04:17 -080035#include <aidl/android/hardware/media/bufferpool2/IClientManager.h>
36#include <aidl/android/hardware/media/c2/BnComponentListener.h>
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080037#include <aidl/android/hardware/media/c2/FieldSupportedValues.h>
38#include <aidl/android/hardware/media/c2/FieldSupportedValuesQuery.h>
39#include <aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.h>
40#include <aidl/android/hardware/media/c2/IComponent.h>
41#include <aidl/android/hardware/media/c2/IComponentInterface.h>
42#include <aidl/android/hardware/media/c2/IComponentStore.h>
43#include <aidl/android/hardware/media/c2/IConfigurable.h>
44#include <aidl/android/hardware/media/c2/ParamDescriptor.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080045#include <aidl/android/hardware/media/c2/StructDescriptor.h>
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080046
Wonsik Kime8e98152022-12-16 16:04:17 -080047#include <aidlcommonsupport/NativeHandle.h>
48#include <android/binder_auto_utils.h>
49#include <android/binder_ibinder.h>
50#include <android/binder_manager.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070051#include <android-base/properties.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080052#include <android-base/stringprintf.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070053#include <bufferpool/ClientManager.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080054#include <bufferpool2/ClientManager.h>
55#include <codec2/aidl/BufferTypes.h>
Wonsik Kim1caded02022-12-09 13:03:11 -080056#include <codec2/aidl/ParamTypes.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070057#include <codec2/hidl/1.0/types.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070058#include <codec2/hidl/1.1/types.h>
Sungtak Lee8577dab2021-03-12 02:25:50 -080059#include <codec2/hidl/1.2/types.h>
Sungtak Leea714f112021-03-16 05:40:03 -070060#include <codec2/hidl/output.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070061
62#include <cutils/native_handle.h>
63#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
64#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080065#include <hardware/gralloc.h> // for GRALLOC_USAGE_*
Pawin Vongmasabf69de92019-10-29 06:21:27 -070066#include <hidl/HidlSupport.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080067#include <system/window.h> // for NATIVE_WINDOW_QUERY_*
68#include <media/stagefright/foundation/ADebug.h> // for asString(status_t)
Pawin Vongmasa36653902018-11-15 00:10:25 -080069
70#include <deque>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070071#include <iterator>
Pawin Vongmasa36653902018-11-15 00:10:25 -080072#include <limits>
73#include <map>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070074#include <mutex>
75#include <sstream>
76#include <thread>
Pawin Vongmasa36653902018-11-15 00:10:25 -080077#include <type_traits>
78#include <vector>
79
Pawin Vongmasa36653902018-11-15 00:10:25 -080080namespace android {
81
82using ::android::hardware::hidl_vec;
83using ::android::hardware::hidl_string;
84using ::android::hardware::Return;
85using ::android::hardware::Void;
Pawin Vongmasa36653902018-11-15 00:10:25 -080086
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080087using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
88 V1_0::IGraphicBufferProducer;
89using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
90 V2_0::IGraphicBufferProducer;
91using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
92 V2_0::utils::B2HGraphicBufferProducer;
93using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
94 V2_0::utils::H2BGraphicBufferProducer;
Sungtak Leea714f112021-03-16 05:40:03 -070095using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080096
Wonsik Kime8e98152022-12-16 16:04:17 -080097namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080098namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
99namespace c2_aidl = ::aidl::android::hardware::media::c2;
100namespace c2_hidl_base = ::android::hardware::media::c2;
101namespace c2_hidl = ::android::hardware::media::c2::V1_2;
102
103using c2_hidl::utils::operator<<;
104
Pawin Vongmasa36653902018-11-15 00:10:25 -0800105namespace /* unnamed */ {
106
107// c2_status_t value that corresponds to hwbinder transaction failure.
108constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
109
Lajos Molnar78aa7c92021-02-18 21:39:01 -0800110// By default prepare buffer to be displayed on any of the common surfaces
111constexpr uint64_t kDefaultConsumerUsage =
112 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER);
113
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700114// Searches for a name in GetServiceNames() and returns the index found. If the
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700115// name is not found, the returned index will be equal to
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700116// GetServiceNames().size().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700117size_t getServiceIndex(char const* name) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700118 std::vector<std::string> const& names = Codec2Client::GetServiceNames();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700119 size_t i = 0;
120 for (; i < names.size(); ++i) {
121 if (name == names[i]) {
122 break;
123 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800124 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700125 return i;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800126}
127
Pawin Vongmasa83d2c552020-03-05 04:36:08 -0800128class Client2Store : public C2ComponentStore {
129 std::shared_ptr<Codec2Client> mClient;
130
131public:
132 Client2Store(std::shared_ptr<Codec2Client> const& client)
133 : mClient(client) { }
134
135 virtual ~Client2Store() = default;
136
137 virtual c2_status_t config_sm(
138 std::vector<C2Param*> const &params,
139 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
140 return mClient->config(params, C2_MAY_BLOCK, failures);
141 };
142
143 virtual c2_status_t copyBuffer(
144 std::shared_ptr<C2GraphicBuffer>,
145 std::shared_ptr<C2GraphicBuffer>) {
146 return C2_OMITTED;
147 }
148
149 virtual c2_status_t createComponent(
150 C2String, std::shared_ptr<C2Component>* const component) {
151 component->reset();
152 return C2_OMITTED;
153 }
154
155 virtual c2_status_t createInterface(
156 C2String, std::shared_ptr<C2ComponentInterface>* const interface) {
157 interface->reset();
158 return C2_OMITTED;
159 }
160
161 virtual c2_status_t query_sm(
162 std::vector<C2Param*> const& stackParams,
163 std::vector<C2Param::Index> const& heapParamIndices,
164 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
165 return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
166 }
167
168 virtual c2_status_t querySupportedParams_nb(
169 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
170 return mClient->querySupportedParams(params);
171 }
172
173 virtual c2_status_t querySupportedValues_sm(
174 std::vector<C2FieldSupportedValuesQuery>& fields) const {
175 return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
176 }
177
178 virtual C2String getName() const {
179 return mClient->getName();
180 }
181
182 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
183 return mClient->getParamReflector();
184 }
185
186 virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() {
187 return std::vector<std::shared_ptr<C2Component::Traits const>>();
188 }
189};
190
Wonsik Kime8e98152022-12-16 16:04:17 -0800191c2_status_t GetC2Status(const ::ndk::ScopedAStatus &transStatus, const char *method) {
192 if (!transStatus.isOk()) {
193 if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
194 c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
195 LOG(DEBUG) << method << " -- call failed: " << status << ".";
196 return status;
197 } else {
198 LOG(ERROR) << method << " -- transaction failed.";
199 return C2_TRANSACTION_FAILED;
200 }
201 }
202 return C2_OK;
203}
204
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700205} // unnamed namespace
206
207// This class caches a Codec2Client object and its component traits. The client
208// will be created the first time it is needed, and it can be refreshed if the
209// service dies (by calling invalidate()). The first time listComponents() is
210// called from the client, the result will be cached.
211class Codec2Client::Cache {
212 // Cached client
213 std::shared_ptr<Codec2Client> mClient;
214 mutable std::mutex mClientMutex;
215
216 // Cached component traits
217 std::vector<C2Component::Traits> mTraits;
218 std::once_flag mTraitsInitializationFlag;
219
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700220 // The index of the service. This is based on GetServiceNames().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700221 size_t mIndex;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700222 // Called by s() exactly once to initialize the cache. The index must be a
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700223 // valid index into the vector returned by GetServiceNames(). Calling
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700224 // init(index) will associate the cache to the service with name
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700225 // GetServiceNames()[index].
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700226 void init(size_t index) {
227 mIndex = index;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700228 }
229
230public:
231 Cache() = default;
232
233 // Initializes mClient if needed, then returns mClient.
234 // If the service is unavailable but listed in the manifest, this function
235 // will block indefinitely.
236 std::shared_ptr<Codec2Client> getClient() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700237 std::scoped_lock lock{mClientMutex};
238 if (!mClient) {
239 mClient = Codec2Client::_CreateFromIndex(mIndex);
240 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -0700241 CHECK(mClient) << "Failed to create Codec2Client to service \""
242 << GetServiceNames()[mIndex] << "\". (Index = "
243 << mIndex << ").";
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700244 return mClient;
245 }
246
247 // Causes a subsequent call to getClient() to create a new client. This
248 // function should be called after the service dies.
249 //
250 // Note: This function is called only by ForAllServices().
251 void invalidate() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700252 std::scoped_lock lock{mClientMutex};
253 mClient = nullptr;
254 }
255
256 // Returns a list of traits for components supported by the service. This
257 // list is cached.
258 std::vector<C2Component::Traits> const& getTraits() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700259 std::call_once(mTraitsInitializationFlag, [this]() {
260 bool success{false};
261 // Spin until _listComponents() is successful.
262 while (true) {
263 std::shared_ptr<Codec2Client> client = getClient();
264 mTraits = client->_listComponents(&success);
265 if (success) {
266 break;
267 }
Pawin Vongmasa21617db2020-04-24 06:16:42 -0700268 invalidate();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700269 using namespace std::chrono_literals;
270 static constexpr auto kServiceRetryPeriod = 5s;
271 LOG(INFO) << "Failed to retrieve component traits from service "
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700272 "\"" << GetServiceNames()[mIndex] << "\". "
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700273 "Retrying...";
274 std::this_thread::sleep_for(kServiceRetryPeriod);
275 }
276 });
277 return mTraits;
278 }
279
280 // List() returns the list of all caches.
281 static std::vector<Cache>& List() {
282 static std::vector<Cache> sCaches{[]() {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700283 size_t numServices = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700284 std::vector<Cache> caches(numServices);
285 for (size_t i = 0; i < numServices; ++i) {
286 caches[i].init(i);
287 }
288 return caches;
289 }()};
290 return sCaches;
291 }
292};
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800293// Codec2ConfigurableClient::HidlImpl
Pawin Vongmasa36653902018-11-15 00:10:25 -0800294
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800295struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase {
296 typedef c2_hidl::IConfigurable Base;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800297
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800298 // base cannot be null.
299 explicit HidlImpl(const sp<Base>& base);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800300
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800301 const C2String& getName() const override {
302 return mName;
303 }
304
305 c2_status_t query(
306 const std::vector<C2Param*>& stackParams,
307 const std::vector<C2Param::Index> &heapParamIndices,
308 c2_blocking_t mayBlock,
309 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
310
311 c2_status_t config(
312 const std::vector<C2Param*> &params,
313 c2_blocking_t mayBlock,
314 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
315
316 c2_status_t querySupportedParams(
317 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
318 ) const override;
319
320 c2_status_t querySupportedValues(
321 std::vector<C2FieldSupportedValuesQuery>& fields,
322 c2_blocking_t mayBlock) const override;
323
324private:
325 sp<Base> mBase;
326 const C2String mName;
327};
328
329Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800330 : mBase{base},
331 mName{[base]() -> C2String {
332 C2String outName;
333 Return<void> transStatus = base->getName(
334 [&outName](const hidl_string& name) {
335 outName = name.c_str();
336 });
337 return transStatus.isOk() ? outName : "";
338 }()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800339}
340
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800341c2_status_t Codec2ConfigurableClient::HidlImpl::query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800342 const std::vector<C2Param*> &stackParams,
343 const std::vector<C2Param::Index> &heapParamIndices,
344 c2_blocking_t mayBlock,
345 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800346 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800347 stackParams.size() + heapParamIndices.size());
348 size_t numIndices = 0;
349 for (C2Param* const& stackParam : stackParams) {
350 if (!stackParam) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800351 LOG(WARNING) << "query -- null stack param encountered.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800352 continue;
353 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800354 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800355 }
356 size_t numStackIndices = numIndices;
357 for (const C2Param::Index& index : heapParamIndices) {
358 indices[numIndices++] =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800359 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800360 }
361 indices.resize(numIndices);
362 if (heapParams) {
363 heapParams->reserve(heapParams->size() + numIndices);
364 }
365 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800366 Return<void> transStatus = mBase->query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800367 indices,
368 mayBlock == C2_MAY_BLOCK,
369 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800370 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800371 status = static_cast<c2_status_t>(s);
372 if (status != C2_OK && status != C2_BAD_INDEX) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800373 LOG(DEBUG) << "query -- call failed: "
374 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800375 return;
376 }
377 std::vector<C2Param*> paramPointers;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800378 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800379 LOG(ERROR) << "query -- error while parsing params.";
380 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800381 return;
382 }
383 size_t i = 0;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800384 for (auto it = paramPointers.begin();
385 it != paramPointers.end(); ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800386 C2Param* paramPointer = *it;
387 if (numStackIndices > 0) {
388 --numStackIndices;
389 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800390 LOG(WARNING) << "query -- null stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800391 ++it;
392 continue;
393 }
394 for (; i < stackParams.size() && !stackParams[i]; ) {
395 ++i;
396 }
397 if (i >= stackParams.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800398 LOG(ERROR) << "query -- unexpected error.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800399 status = C2_CORRUPTED;
400 return;
401 }
402 if (stackParams[i]->index() != paramPointer->index()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800403 LOG(WARNING) << "query -- param skipped: "
404 "index = "
405 << stackParams[i]->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800406 stackParams[i++]->invalidate();
407 continue;
408 }
409 if (!stackParams[i++]->updateFrom(*paramPointer)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800410 LOG(WARNING) << "query -- param update failed: "
411 "index = "
412 << paramPointer->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800413 }
414 } else {
415 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800416 LOG(WARNING) << "query -- null heap param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800417 ++it;
418 continue;
419 }
420 if (!heapParams) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800421 LOG(WARNING) << "query -- "
422 "unexpected extra stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800423 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800424 heapParams->emplace_back(
425 C2Param::Copy(*paramPointer));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800426 }
427 }
428 ++it;
429 }
430 });
431 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800432 LOG(ERROR) << "query -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800433 return C2_TRANSACTION_FAILED;
434 }
435 return status;
436}
437
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800438c2_status_t Codec2ConfigurableClient::HidlImpl::config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800439 const std::vector<C2Param*> &params,
440 c2_blocking_t mayBlock,
441 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800442 c2_hidl::Params hidlParams;
443 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800444 LOG(ERROR) << "config -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800445 return C2_TRANSACTION_FAILED;
446 }
447 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800448 Return<void> transStatus = mBase->config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800449 hidlParams,
450 mayBlock == C2_MAY_BLOCK,
451 [&status, &params, failures](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800452 c2_hidl::Status s,
453 const hidl_vec<c2_hidl::SettingResult> f,
454 const c2_hidl::Params& o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800455 status = static_cast<c2_status_t>(s);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800456 if (status != C2_OK && status != C2_BAD_INDEX) {
457 LOG(DEBUG) << "config -- call failed: "
458 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800459 }
460 size_t i = failures->size();
461 failures->resize(i + f.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800462 for (const c2_hidl::SettingResult& sf : f) {
463 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800464 LOG(ERROR) << "config -- "
465 << "invalid SettingResult returned.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800466 return;
467 }
468 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800469 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800470 LOG(ERROR) << "config -- "
471 << "failed to parse returned params.";
472 status = C2_CORRUPTED;
473 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800474 });
475 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800476 LOG(ERROR) << "config -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800477 return C2_TRANSACTION_FAILED;
478 }
479 return status;
480}
481
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800482c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800483 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
484 // TODO: Cache and query properly!
485 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800486 Return<void> transStatus = mBase->querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800487 std::numeric_limits<uint32_t>::min(),
488 std::numeric_limits<uint32_t>::max(),
489 [&status, params](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800490 c2_hidl::Status s,
491 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800492 status = static_cast<c2_status_t>(s);
493 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800494 LOG(DEBUG) << "querySupportedParams -- call failed: "
495 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800496 return;
497 }
498 size_t i = params->size();
499 params->resize(i + p.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800500 for (const c2_hidl::ParamDescriptor& sp : p) {
501 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800502 LOG(ERROR) << "querySupportedParams -- "
503 << "invalid returned ParamDescriptor.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800504 return;
505 }
506 }
507 });
508 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800509 LOG(ERROR) << "querySupportedParams -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800510 return C2_TRANSACTION_FAILED;
511 }
512 return status;
513}
514
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800515c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800516 std::vector<C2FieldSupportedValuesQuery>& fields,
517 c2_blocking_t mayBlock) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800518 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800519 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800520 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800521 LOG(ERROR) << "querySupportedValues -- bad input";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800522 return C2_TRANSACTION_FAILED;
523 }
524 }
525
526 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800527 Return<void> transStatus = mBase->querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800528 inFields,
529 mayBlock == C2_MAY_BLOCK,
530 [&status, &inFields, &fields](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800531 c2_hidl::Status s,
532 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800533 status = static_cast<c2_status_t>(s);
534 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800535 LOG(DEBUG) << "querySupportedValues -- call failed: "
536 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800537 return;
538 }
539 if (r.size() != fields.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800540 LOG(ERROR) << "querySupportedValues -- "
541 "input and output lists "
542 "have different sizes.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800543 status = C2_CORRUPTED;
544 return;
545 }
546 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800547 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800548 LOG(ERROR) << "querySupportedValues -- "
549 "invalid returned value.";
550 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800551 return;
552 }
553 }
554 });
555 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800556 LOG(ERROR) << "querySupportedValues -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800557 return C2_TRANSACTION_FAILED;
558 }
559 return status;
560}
561
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800562// Codec2ConfigurableClient::AidlImpl
563
564struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase {
565 typedef c2_aidl::IConfigurable Base;
566
567 // base cannot be null.
568 explicit AidlImpl(const std::shared_ptr<Base>& base);
569
570 const C2String& getName() const override {
571 return mName;
572 }
573
574 c2_status_t query(
575 const std::vector<C2Param*>& stackParams,
576 const std::vector<C2Param::Index> &heapParamIndices,
577 c2_blocking_t mayBlock,
578 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
579
580 c2_status_t config(
581 const std::vector<C2Param*> &params,
582 c2_blocking_t mayBlock,
583 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
584
585 c2_status_t querySupportedParams(
586 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
587 ) const override;
588
589 c2_status_t querySupportedValues(
590 std::vector<C2FieldSupportedValuesQuery>& fields,
591 c2_blocking_t mayBlock) const override;
592
593private:
594 std::shared_ptr<Base> mBase;
595 const C2String mName;
596};
597
598Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base)
599 : mBase{base},
600 mName{[base]() -> C2String {
601 std::string outName;
602 ndk::ScopedAStatus status = base->getName(&outName);
603 return status.isOk() ? outName : "";
604 }()} {
605}
606
607c2_status_t Codec2ConfigurableClient::AidlImpl::query(
608 const std::vector<C2Param*> &stackParams,
609 const std::vector<C2Param::Index> &heapParamIndices,
610 c2_blocking_t mayBlock,
611 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800612 std::vector<int> indices(
613 stackParams.size() + heapParamIndices.size());
614 size_t numIndices = 0;
615 for (C2Param* const& stackParam : stackParams) {
616 if (!stackParam) {
617 LOG(WARNING) << "query -- null stack param encountered.";
618 continue;
619 }
620 indices[numIndices++] = int(stackParam->index());
621 }
622 size_t numStackIndices = numIndices;
623 for (const C2Param::Index& index : heapParamIndices) {
624 indices[numIndices++] = int(static_cast<uint32_t>(index));
625 }
626 indices.resize(numIndices);
627 if (heapParams) {
628 heapParams->reserve(heapParams->size() + numIndices);
629 }
630 c2_aidl::Params result;
631 ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800632 c2_status_t status = GetC2Status(transStatus, "query");
633 if (status != C2_OK) {
634 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800635 }
636
Wonsik Kim1caded02022-12-09 13:03:11 -0800637 std::vector<C2Param*> paramPointers;
638 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, result)) {
639 LOG(ERROR) << "query -- error while parsing params.";
640 return C2_CORRUPTED;
641 }
642 size_t i = 0;
643 for (auto it = paramPointers.begin();
644 it != paramPointers.end(); ) {
645 C2Param* paramPointer = *it;
646 if (numStackIndices > 0) {
647 --numStackIndices;
648 if (!paramPointer) {
649 LOG(DEBUG) << "query -- null stack param.";
650 ++it;
651 continue;
652 }
653 for (; i < stackParams.size() && !stackParams[i]; ) {
654 ++i;
655 }
656 if (i >= stackParams.size()) {
657 LOG(ERROR) << "query -- unexpected error.";
658 status = C2_CORRUPTED;
659 break;
660 }
661 if (stackParams[i]->index() != paramPointer->index()) {
662 LOG(DEBUG) << "query -- param skipped: "
663 "index = "
664 << stackParams[i]->index() << ".";
665 stackParams[i++]->invalidate();
666 // this means that the param could not be queried.
667 // signalling C2_BAD_INDEX to the client.
668 status = C2_BAD_INDEX;
669 continue;
670 }
671 if (!stackParams[i++]->updateFrom(*paramPointer)) {
672 LOG(WARNING) << "query -- param update failed: "
673 "index = "
674 << paramPointer->index() << ".";
675 }
676 } else {
677 if (!paramPointer) {
678 LOG(DEBUG) << "query -- null heap param.";
679 ++it;
680 continue;
681 }
682 if (!heapParams) {
683 LOG(WARNING) << "query -- "
684 "unexpected extra stack param.";
685 } else {
686 heapParams->emplace_back(C2Param::Copy(*paramPointer));
687 }
688 }
689 ++it;
690 }
691 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800692}
693
694c2_status_t Codec2ConfigurableClient::AidlImpl::config(
695 const std::vector<C2Param*> &params,
696 c2_blocking_t mayBlock,
697 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kim1caded02022-12-09 13:03:11 -0800698 c2_aidl::Params aidlParams;
699 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
700 LOG(ERROR) << "config -- bad input.";
701 return C2_TRANSACTION_FAILED;
702 }
703 c2_aidl::IConfigurable::ConfigResult result;
704 ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800705 c2_status_t status = GetC2Status(transStatus, "config");
706 if (status != C2_OK) {
707 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800708 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800709 size_t i = failures->size();
710 failures->resize(i + result.failures.size());
711 for (const c2_aidl::SettingResult& sf : result.failures) {
712 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
713 LOG(ERROR) << "config -- invalid SettingResult returned.";
714 return C2_CORRUPTED;
715 }
716 }
717 if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) {
718 LOG(ERROR) << "config -- "
719 << "failed to parse returned params.";
720 status = C2_CORRUPTED;
721 }
722 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800723}
724
725c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams(
726 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800727 // TODO: Cache and query properly!
728 std::vector<c2_aidl::ParamDescriptor> result;
729 ndk::ScopedAStatus transStatus = mBase->querySupportedParams(
730 std::numeric_limits<uint32_t>::min(),
731 std::numeric_limits<uint32_t>::max(),
732 &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800733 c2_status_t status = GetC2Status(transStatus, "querySupportedParams");
734 if (status != C2_OK) {
735 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800736 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800737 size_t i = params->size();
738 params->resize(i + result.size());
739 for (const c2_aidl::ParamDescriptor& sp : result) {
740 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
741 LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor.";
742 return C2_CORRUPTED;
743 }
744 }
745 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800746}
747
748c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues(
749 std::vector<C2FieldSupportedValuesQuery>& fields,
750 c2_blocking_t mayBlock) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800751 std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size());
752 for (size_t i = 0; i < fields.size(); ++i) {
753 if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) {
754 LOG(ERROR) << "querySupportedValues -- bad input";
755 return C2_TRANSACTION_FAILED;
756 }
757 }
758
759 std::vector<c2_aidl::FieldSupportedValuesQueryResult> result;
760 ndk::ScopedAStatus transStatus = mBase->querySupportedValues(
761 inFields, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800762 c2_status_t status = GetC2Status(transStatus, "querySupportedValues");
763 if (status != C2_OK) {
764 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800765 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800766 if (result.size() != fields.size()) {
767 LOG(ERROR) << "querySupportedValues -- "
768 "input and output lists "
769 "have different sizes.";
770 return C2_CORRUPTED;
771 }
772 for (size_t i = 0; i < fields.size(); ++i) {
773 if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) {
774 LOG(ERROR) << "querySupportedValues -- "
775 "invalid returned value.";
776 return C2_CORRUPTED;
777 }
778 }
779 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800780}
781
782// Codec2ConfigurableClient
783
784Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase)
785 : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) {
786}
787
788Codec2ConfigurableClient::Codec2ConfigurableClient(
789 const std::shared_ptr<AidlBase> &aidlBase)
790 : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) {
791}
792
793const C2String& Codec2ConfigurableClient::getName() const {
794 return mImpl->getName();
795}
796
797c2_status_t Codec2ConfigurableClient::query(
798 const std::vector<C2Param*>& stackParams,
799 const std::vector<C2Param::Index> &heapParamIndices,
800 c2_blocking_t mayBlock,
801 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
802 return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
803}
804
805c2_status_t Codec2ConfigurableClient::config(
806 const std::vector<C2Param*> &params,
807 c2_blocking_t mayBlock,
808 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
809 return mImpl->config(params, mayBlock, failures);
810}
811
812c2_status_t Codec2ConfigurableClient::querySupportedParams(
813 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
814 return mImpl->querySupportedParams(params);
815}
816
817c2_status_t Codec2ConfigurableClient::querySupportedValues(
818 std::vector<C2FieldSupportedValuesQuery>& fields,
819 c2_blocking_t mayBlock) const {
820 return mImpl->querySupportedValues(fields, mayBlock);
821}
822
823
Pawin Vongmasa36653902018-11-15 00:10:25 -0800824// Codec2Client::Component::HidlListener
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800825struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800826 std::weak_ptr<Component> component;
827 std::weak_ptr<Listener> base;
828
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800829 virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800830 std::list<std::unique_ptr<C2Work>> workItems;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800831 if (!c2_hidl::utils::objcpy(&workItems, workBundle)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800832 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800833 return Void();
834 }
835 // release input buffers potentially held by the component from queue
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800836 std::shared_ptr<Codec2Client::Component> strongComponent =
837 component.lock();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800838 if (strongComponent) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800839 strongComponent->handleOnWorkDone(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800840 }
841 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800842 listener->onWorkDone(component, workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800843 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800844 LOG(DEBUG) << "onWorkDone -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800845 }
846 return Void();
847 }
848
849 virtual Return<void> onTripped(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800850 const hidl_vec<c2_hidl::SettingResult>& settingResults) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800851 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
852 settingResults.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800853 for (size_t i = 0; i < settingResults.size(); ++i) {
854 std::unique_ptr<C2SettingResult> c2SettingResult;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800855 if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800856 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800857 return Void();
858 }
859 c2SettingResults[i] = std::move(c2SettingResult);
860 }
861 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
862 listener->onTripped(component, c2SettingResults);
863 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800864 LOG(DEBUG) << "onTripped -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800865 }
866 return Void();
867 }
868
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800869 virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800870 LOG(DEBUG) << "onError --"
871 << " status = " << s
872 << ", errorCode = " << errorCode
873 << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800874 if (std::shared_ptr<Listener> listener = base.lock()) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800875 listener->onError(component, s == c2_hidl::Status::OK ?
Pawin Vongmasa36653902018-11-15 00:10:25 -0800876 errorCode : static_cast<c2_status_t>(s));
877 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800878 LOG(DEBUG) << "onError -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800879 }
880 return Void();
881 }
882
883 virtual Return<void> onFramesRendered(
884 const hidl_vec<RenderedFrame>& renderedFrames) override {
885 std::shared_ptr<Listener> listener = base.lock();
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800886 if (!listener) {
887 LOG(DEBUG) << "onFramesRendered -- listener died.";
888 return Void();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800889 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800890 for (const RenderedFrame& renderedFrame : renderedFrames) {
891 listener->onFrameRendered(
892 renderedFrame.bufferQueueId,
893 renderedFrame.slotId,
894 renderedFrame.timestampNs);
895 }
896 return Void();
897 }
898
899 virtual Return<void> onInputBuffersReleased(
900 const hidl_vec<InputBuffer>& inputBuffers) override {
901 std::shared_ptr<Listener> listener = base.lock();
902 if (!listener) {
903 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
904 return Void();
905 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800906 for (const InputBuffer& inputBuffer : inputBuffers) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800907 LOG(VERBOSE) << "onInputBuffersReleased --"
908 " received death notification of"
909 " input buffer:"
910 " frameIndex = " << inputBuffer.frameIndex
911 << ", bufferIndex = " << inputBuffer.arrayIndex
912 << ".";
Wonsik Kimab34ed62019-01-31 15:28:46 -0800913 listener->onInputBufferDone(
914 inputBuffer.frameIndex, inputBuffer.arrayIndex);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800915 }
916 return Void();
917 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800918
Pawin Vongmasa36653902018-11-15 00:10:25 -0800919};
920
Wonsik Kime8e98152022-12-16 16:04:17 -0800921// Codec2Client::Component::AidlListener
922struct Codec2Client::Component::AidlListener : public c2_aidl::BnComponentListener {
923 std::weak_ptr<Component> component;
924 std::weak_ptr<Listener> base;
925
926 virtual ::ndk::ScopedAStatus onWorkDone(const c2_aidl::WorkBundle& workBundle) override {
927 std::list<std::unique_ptr<C2Work>> workItems;
928 if (!c2_aidl::utils::FromAidl(&workItems, workBundle)) {
929 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
930 return ::ndk::ScopedAStatus::ok();
931 }
932 // release input buffers potentially held by the component from queue
933 std::shared_ptr<Codec2Client::Component> strongComponent =
934 component.lock();
935 if (strongComponent) {
936 strongComponent->handleOnWorkDone(workItems);
937 }
938 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
939 listener->onWorkDone(component, workItems);
940 } else {
941 LOG(DEBUG) << "onWorkDone -- listener died.";
942 }
943 return ::ndk::ScopedAStatus::ok();
944 }
945
946 virtual ::ndk::ScopedAStatus onTripped(
947 const std::vector<c2_aidl::SettingResult>& settingResults) override {
948 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
949 settingResults.size());
950 for (size_t i = 0; i < settingResults.size(); ++i) {
951 std::unique_ptr<C2SettingResult> c2SettingResult;
952 if (!c2_aidl::utils::FromAidl(&c2SettingResult, settingResults[i])) {
953 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
954 return ::ndk::ScopedAStatus::ok();
955 }
956 c2SettingResults[i] = std::move(c2SettingResult);
957 }
958 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
959 listener->onTripped(component, c2SettingResults);
960 } else {
961 LOG(DEBUG) << "onTripped -- listener died.";
962 }
963 return ::ndk::ScopedAStatus::ok();
964 }
965
966 virtual ::ndk::ScopedAStatus onError(const c2_aidl::Status &s, int32_t errorCode) override {
967 LOG(DEBUG) << "onError --"
968 << " status = " << s.status
969 << ", errorCode = " << errorCode
970 << ".";
971 if (std::shared_ptr<Listener> listener = base.lock()) {
972 listener->onError(component, s.status == c2_aidl::Status::OK ?
973 errorCode : static_cast<c2_status_t>(s.status));
974 } else {
975 LOG(DEBUG) << "onError -- listener died.";
976 }
977 return ::ndk::ScopedAStatus::ok();
978 }
979
980 virtual ::ndk::ScopedAStatus onFramesRendered(
981 const std::vector<RenderedFrame>& renderedFrames) override {
982 std::shared_ptr<Listener> listener = base.lock();
983 if (!listener) {
984 LOG(DEBUG) << "onFramesRendered -- listener died.";
985 return ::ndk::ScopedAStatus::ok();
986 }
987 for (const RenderedFrame& renderedFrame : renderedFrames) {
988 listener->onFrameRendered(
989 renderedFrame.bufferQueueId,
990 renderedFrame.slotId,
991 renderedFrame.timestampNs);
992 }
993 return ::ndk::ScopedAStatus::ok();
994 }
995
996 virtual ::ndk::ScopedAStatus onInputBuffersReleased(
997 const std::vector<InputBuffer>& inputBuffers) override {
998 std::shared_ptr<Listener> listener = base.lock();
999 if (!listener) {
1000 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
1001 return ::ndk::ScopedAStatus::ok();
1002 }
1003 for (const InputBuffer& inputBuffer : inputBuffers) {
1004 LOG(VERBOSE) << "onInputBuffersReleased --"
1005 " received death notification of"
1006 " input buffer:"
1007 " frameIndex = " << inputBuffer.frameIndex
1008 << ", bufferIndex = " << inputBuffer.arrayIndex
1009 << ".";
1010 listener->onInputBufferDone(
1011 inputBuffer.frameIndex, inputBuffer.arrayIndex);
1012 }
1013 return ::ndk::ScopedAStatus::ok();
1014 }
1015
1016};
1017
1018// Codec2Client::Component::HidlBufferPoolSender
1019struct Codec2Client::Component::HidlBufferPoolSender :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001020 hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
Wonsik Kime8e98152022-12-16 16:04:17 -08001021 HidlBufferPoolSender()
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001022 : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
1023 }
1024};
1025
Wonsik Kime8e98152022-12-16 16:04:17 -08001026// Codec2Client::Component::AidlBufferPoolSender
1027struct Codec2Client::Component::AidlBufferPoolSender :
1028 c2_aidl::utils::DefaultBufferPoolSender {
1029 AidlBufferPoolSender()
1030 : c2_aidl::utils::DefaultBufferPoolSender() {
1031 }
1032};
1033
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001034// Codec2Client::Component::OutputBufferQueue
1035struct Codec2Client::Component::OutputBufferQueue :
Sungtak Leea714f112021-03-16 05:40:03 -07001036 hardware::media::c2::OutputBufferQueue {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001037 OutputBufferQueue()
Sungtak Leea714f112021-03-16 05:40:03 -07001038 : hardware::media::c2::OutputBufferQueue() {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001039 }
1040};
1041
Pawin Vongmasa36653902018-11-15 00:10:25 -08001042// Codec2Client
Wonsik Kime8e98152022-12-16 16:04:17 -08001043Codec2Client::Codec2Client(sp<HidlBase> const& base,
Sungtak Leef4b39512023-05-10 07:17:22 +00001044 sp<c2_hidl::IConfigurable> const& configurable,
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001045 size_t serviceIndex)
Sungtak Leef4b39512023-05-10 07:17:22 +00001046 : Configurable{configurable},
Wonsik Kime8e98152022-12-16 16:04:17 -08001047 mHidlBase1_0{base},
1048 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1049 mHidlBase1_2{HidlBase1_2::castFrom(base)},
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001050 mServiceIndex{serviceIndex} {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001051 Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager();
Pawin Vongmasa36653902018-11-15 00:10:25 -08001052 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001053 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001054 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08001055 mHidlHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001056 }
1057}
1058
Wonsik Kime8e98152022-12-16 16:04:17 -08001059Codec2Client::Codec2Client(std::shared_ptr<AidlBase> const& base,
1060 std::shared_ptr<c2_aidl::IConfigurable> const& configurable,
1061 size_t serviceIndex)
1062 : Configurable{configurable},
1063 mAidlBase{base},
1064 mServiceIndex{serviceIndex} {
1065 ::ndk::ScopedAStatus transStatus = base->getPoolClientManager(&mAidlHostPoolManager);
1066 if (!transStatus.isOk()) {
1067 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
1068 mAidlHostPoolManager.reset();
1069 }
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001070}
1071
Wonsik Kime8e98152022-12-16 16:04:17 -08001072sp<Codec2Client::HidlBase> const& Codec2Client::getHidlBase() const {
1073 return mHidlBase1_0;
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001074}
1075
Wonsik Kime8e98152022-12-16 16:04:17 -08001076sp<Codec2Client::HidlBase1_0> const& Codec2Client::getHidlBase1_0() const {
1077 return mHidlBase1_0;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001078}
1079
Wonsik Kime8e98152022-12-16 16:04:17 -08001080sp<Codec2Client::HidlBase1_1> const& Codec2Client::getHidlBase1_1() const {
1081 return mHidlBase1_1;
1082}
1083
1084sp<Codec2Client::HidlBase1_2> const& Codec2Client::getHidlBase1_2() const {
1085 return mHidlBase1_2;
1086}
1087
1088::ndk::SpAIBinder Codec2Client::getAidlBase() const {
1089 return mAidlBase ? mAidlBase->asBinder() : nullptr;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001090}
1091
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001092std::string const& Codec2Client::getServiceName() const {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001093 return GetServiceNames()[mServiceIndex];
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001094}
1095
Pawin Vongmasa36653902018-11-15 00:10:25 -08001096c2_status_t Codec2Client::createComponent(
1097 const C2String& name,
1098 const std::shared_ptr<Codec2Client::Listener>& listener,
1099 std::shared_ptr<Codec2Client::Component>* const component) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001100 if (mAidlBase) {
1101 std::shared_ptr<Component::AidlListener> aidlListener =
1102 Component::AidlListener::make<Component::AidlListener>();
1103 aidlListener->base = listener;
1104 std::shared_ptr<c2_aidl::IComponent> aidlComponent;
1105 ::ndk::ScopedAStatus transStatus = mAidlBase->createComponent(
1106 name,
1107 aidlListener,
1108 bufferpool2_aidl::implementation::ClientManager::getInstance(),
1109 &aidlComponent);
1110 c2_status_t status = GetC2Status(transStatus, "createComponent");
1111 if (status != C2_OK) {
1112 return status;
1113 } else if (!aidlComponent) {
1114 LOG(ERROR) << "createComponent(" << name.c_str()
1115 << ") -- null component.";
1116 return C2_CORRUPTED;
1117 }
1118 *component = std::make_shared<Codec2Client::Component>(aidlComponent);
1119 status = (*component)->setDeathListener((*component), listener);
1120 if (status != C2_OK) {
1121 LOG(ERROR) << "createComponent(" << name.c_str()
1122 << ") -- failed to set up death listener: "
1123 << status << ".";
1124 }
1125 (*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager);
1126 return status;
1127 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001128
Pawin Vongmasa36653902018-11-15 00:10:25 -08001129 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001130 sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001131 hidlListener->base = listener;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001132 Return<void> transStatus;
Wonsik Kime8e98152022-12-16 16:04:17 -08001133 if (mHidlBase1_2) {
1134 transStatus = mHidlBase1_2->createComponent_1_2(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001135 name,
1136 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001137 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasa36653902018-11-15 00:10:25 -08001138 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001139 c2_hidl::Status s,
1140 const sp<c2_hidl::IComponent>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001141 status = static_cast<c2_status_t>(s);
1142 if (status != C2_OK) {
1143 return;
1144 }
1145 *component = std::make_shared<Codec2Client::Component>(c);
1146 hidlListener->component = *component;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001147 });
1148 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001149 else if (mHidlBase1_1) {
1150 transStatus = mHidlBase1_1->createComponent_1_1(
Sungtak Lee8577dab2021-03-12 02:25:50 -08001151 name,
1152 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001153 bufferpool_hidl::implementation::ClientManager::getInstance(),
Sungtak Lee8577dab2021-03-12 02:25:50 -08001154 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001155 c2_hidl::Status s,
1156 const sp<c2_hidl_base::V1_1::IComponent>& c) {
Sungtak Lee8577dab2021-03-12 02:25:50 -08001157 status = static_cast<c2_status_t>(s);
1158 if (status != C2_OK) {
1159 return;
1160 }
1161 *component = std::make_shared<Codec2Client::Component>(c);
1162 hidlListener->component = *component;
1163 });
Wonsik Kime8e98152022-12-16 16:04:17 -08001164 } else if (mHidlBase1_0) { // ver1_0
1165 transStatus = mHidlBase1_0->createComponent(
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001166 name,
1167 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001168 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001169 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001170 c2_hidl::Status s,
1171 const sp<c2_hidl_base::V1_0::IComponent>& c) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001172 status = static_cast<c2_status_t>(s);
1173 if (status != C2_OK) {
1174 return;
1175 }
1176 *component = std::make_shared<Codec2Client::Component>(c);
1177 hidlListener->component = *component;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001178 });
Sungtak Lee8577dab2021-03-12 02:25:50 -08001179 } else {
1180 status = C2_CORRUPTED;
1181 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001182 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001183 LOG(ERROR) << "createComponent(" << name.c_str()
1184 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001185 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001186 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001187 if (status == C2_NOT_FOUND) {
1188 LOG(VERBOSE) << "createComponent(" << name.c_str()
1189 << ") -- component not found.";
1190 } else {
1191 LOG(ERROR) << "createComponent(" << name.c_str()
1192 << ") -- call failed: " << status << ".";
1193 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001194 return status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001195 } else if (!*component) {
1196 LOG(ERROR) << "createComponent(" << name.c_str()
1197 << ") -- null component.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001198 return C2_CORRUPTED;
1199 }
1200
1201 status = (*component)->setDeathListener(*component, listener);
1202 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001203 LOG(ERROR) << "createComponent(" << name.c_str()
1204 << ") -- failed to set up death listener: "
1205 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001206 }
1207
Wonsik Kime8e98152022-12-16 16:04:17 -08001208 (*component)->mHidlBufferPoolSender->setReceiver(mHidlHostPoolManager);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001209 return status;
1210}
1211
1212c2_status_t Codec2Client::createInterface(
1213 const C2String& name,
1214 std::shared_ptr<Codec2Client::Interface>* const interface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001215 if (mAidlBase) {
1216 std::shared_ptr<c2_aidl::IComponentInterface> aidlInterface;
1217 ::ndk::ScopedAStatus transStatus = mAidlBase->createInterface(
1218 name,
1219 &aidlInterface);
1220 c2_status_t status = GetC2Status(transStatus, "createInterface");
1221 if (status != C2_OK) {
1222 return status;
1223 } else if (!aidlInterface) {
1224 LOG(ERROR) << "createInterface(" << name.c_str()
1225 << ") -- null interface.";
1226 return C2_CORRUPTED;
1227 }
1228 interface->reset(new Codec2Client::Interface(aidlInterface));
1229 return C2_OK;
1230 }
1231
Pawin Vongmasa36653902018-11-15 00:10:25 -08001232 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001233 Return<void> transStatus = mHidlBase1_0->createInterface(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001234 name,
1235 [&status, interface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001236 c2_hidl::Status s,
1237 const sp<c2_hidl::IComponentInterface>& i) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001238 status = static_cast<c2_status_t>(s);
1239 if (status != C2_OK) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001240 return;
1241 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001242 *interface = std::make_shared<Interface>(i);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001243 });
1244 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001245 LOG(ERROR) << "createInterface(" << name.c_str()
1246 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001247 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001248 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001249 if (status == C2_NOT_FOUND) {
1250 LOG(VERBOSE) << "createInterface(" << name.c_str()
1251 << ") -- component not found.";
1252 } else {
1253 LOG(ERROR) << "createInterface(" << name.c_str()
1254 << ") -- call failed: " << status << ".";
1255 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001256 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001257 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001258
Pawin Vongmasa36653902018-11-15 00:10:25 -08001259 return status;
1260}
1261
1262c2_status_t Codec2Client::createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001263 std::shared_ptr<InputSurface>* const inputSurface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001264 if (mAidlBase) {
1265 // FIXME
1266 return C2_OMITTED;
1267 }
1268
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001269 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001270 Return<void> transStatus = mHidlBase1_0->createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001271 [&status, inputSurface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001272 c2_hidl::Status s,
1273 const sp<c2_hidl::IInputSurface>& i) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001274 status = static_cast<c2_status_t>(s);
1275 if (status != C2_OK) {
1276 return;
1277 }
1278 *inputSurface = std::make_shared<InputSurface>(i);
1279 });
1280 if (!transStatus.isOk()) {
1281 LOG(ERROR) << "createInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001282 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001283 } else if (status != C2_OK) {
1284 LOG(DEBUG) << "createInputSurface -- call failed: "
1285 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001286 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001287 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001288}
1289
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001290std::vector<C2Component::Traits> const& Codec2Client::listComponents() const {
1291 return Cache::List()[mServiceIndex].getTraits();
1292}
1293
1294std::vector<C2Component::Traits> Codec2Client::_listComponents(
1295 bool* success) const {
1296 std::vector<C2Component::Traits> traits;
1297 std::string const& serviceName = getServiceName();
Wonsik Kime8e98152022-12-16 16:04:17 -08001298
1299 if (mAidlBase) {
1300 std::vector<c2_aidl::IComponentStore::ComponentTraits> aidlTraits;
1301 ::ndk::ScopedAStatus transStatus = mAidlBase->listComponents(&aidlTraits);
1302 if (!transStatus.isOk()) {
1303 LOG(ERROR) << "_listComponents -- transaction failed.";
1304 *success = false;
1305 } else {
1306 traits.resize(aidlTraits.size());
1307 *success = true;
1308 for (size_t i = 0; i < aidlTraits.size(); ++i) {
1309 if (!c2_aidl::utils::FromAidl(&traits[i], aidlTraits[i])) {
1310 LOG(ERROR) << "_listComponents -- corrupted output.";
1311 *success = false;
1312 traits.clear();
1313 break;
1314 }
1315 traits[i].owner = serviceName;
1316 }
1317 }
1318 return traits;
1319 }
1320 Return<void> transStatus = mHidlBase1_0->listComponents(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001321 [&traits, &serviceName](c2_hidl::Status s,
1322 const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) {
1323 if (s != c2_hidl::Status::OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001324 LOG(DEBUG) << "_listComponents -- call failed: "
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001325 << static_cast<c2_status_t>(s) << ".";
1326 return;
1327 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001328 traits.resize(t.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001329 for (size_t i = 0; i < t.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001330 if (!c2_hidl::utils::objcpy(&traits[i], t[i])) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001331 LOG(ERROR) << "_listComponents -- corrupted output.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001332 return;
1333 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001334 traits[i].owner = serviceName;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001335 }
1336 });
1337 if (!transStatus.isOk()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001338 LOG(ERROR) << "_listComponents -- transaction failed.";
1339 *success = false;
1340 } else {
1341 *success = true;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001342 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001343 return traits;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001344}
1345
1346c2_status_t Codec2Client::copyBuffer(
1347 const std::shared_ptr<C2Buffer>& src,
1348 const std::shared_ptr<C2Buffer>& dst) {
1349 // TODO: Implement?
1350 (void)src;
1351 (void)dst;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001352 LOG(ERROR) << "copyBuffer not implemented";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001353 return C2_OMITTED;
1354}
1355
Wonsik Kime8e98152022-12-16 16:04:17 -08001356std::shared_ptr<C2ParamReflector> Codec2Client::getParamReflector() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001357 // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it
1358 // should reflect the HAL API.
Wonsik Kime8e98152022-12-16 16:04:17 -08001359 struct HidlSimpleParamReflector : public C2ParamReflector {
1360 std::unique_ptr<C2StructDescriptor> describe(
1361 C2Param::CoreIndex coreIndex) const override {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001362 hidl_vec<c2_hidl::ParamIndex> indices(1);
1363 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001364 std::unique_ptr<C2StructDescriptor> descriptor;
1365 Return<void> transStatus = mBase->getStructDescriptors(
1366 indices,
1367 [&descriptor](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001368 c2_hidl::Status s,
1369 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001370 c2_status_t status = static_cast<c2_status_t>(s);
1371 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001372 LOG(DEBUG) << "SimpleParamReflector -- "
1373 "getStructDescriptors() failed: "
1374 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001375 descriptor.reset();
1376 return;
1377 }
1378 if (sd.size() != 1) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001379 LOG(DEBUG) << "SimpleParamReflector -- "
1380 "getStructDescriptors() "
1381 "returned vector of size "
1382 << sd.size() << ". "
1383 "It should be 1.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001384 descriptor.reset();
1385 return;
1386 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001387 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001388 LOG(DEBUG) << "SimpleParamReflector -- "
1389 "getStructDescriptors() returned "
1390 "corrupted data.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001391 descriptor.reset();
1392 return;
1393 }
1394 });
Wonsik Kim492fecd2020-11-19 11:14:11 -08001395 if (!transStatus.isOk()) {
1396 LOG(DEBUG) << "SimpleParamReflector -- transaction failed: "
1397 << transStatus.description();
1398 descriptor.reset();
1399 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001400 return descriptor;
1401 }
1402
Wonsik Kime8e98152022-12-16 16:04:17 -08001403 HidlSimpleParamReflector(sp<HidlBase> base)
Pawin Vongmasa36653902018-11-15 00:10:25 -08001404 : mBase(base) { }
1405
Wonsik Kime8e98152022-12-16 16:04:17 -08001406 sp<HidlBase> mBase;
1407 };
1408 struct AidlSimpleParamReflector : public C2ParamReflector {
1409 std::unique_ptr<C2StructDescriptor> describe(
1410 C2Param::CoreIndex coreIndex) const override {
1411 std::vector<c2_aidl::StructDescriptor> aidlDesc;
1412 std::unique_ptr<C2StructDescriptor> descriptor;
1413 ::ndk::ScopedAStatus transStatus = mBase->getStructDescriptors(
1414 {int32_t(coreIndex.coreIndex())},
1415 &aidlDesc);
1416 c2_status_t status = GetC2Status(transStatus, "describe");
1417 if (status != C2_OK) {
1418 descriptor.reset();
1419 } else if (!c2_aidl::utils::FromAidl(&descriptor, aidlDesc[0])) {
1420 LOG(ERROR) << "describe -- conversion failed.";
1421 descriptor.reset();
1422 }
1423 return descriptor;
1424 }
1425
1426 AidlSimpleParamReflector(const std::shared_ptr<AidlBase> &base)
1427 : mBase(base) { }
1428
1429 std::shared_ptr<AidlBase> mBase;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001430 };
1431
Wonsik Kime8e98152022-12-16 16:04:17 -08001432 if (mAidlBase) {
1433 return std::make_shared<AidlSimpleParamReflector>(mAidlBase);
1434 }
1435 return std::make_shared<HidlSimpleParamReflector>(mHidlBase1_0);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001436};
1437
Wonsik Kime8e98152022-12-16 16:04:17 -08001438std::vector<std::string> Codec2Client::CacheServiceNames() {
1439 std::vector<std::string> names;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001440
Wonsik Kime8e98152022-12-16 16:04:17 -08001441 if (c2_aidl::utils::IsEnabled()) {
1442 // Get AIDL service names
1443 AServiceManager_forEachDeclaredInstance(
1444 AidlBase::descriptor, &names, [](const char *name, void *context) {
1445 std::vector<std::string> *names = (std::vector<std::string> *)context;
1446 names->emplace_back(name);
1447 });
1448 }
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001449
Wonsik Kime8e98152022-12-16 16:04:17 -08001450 // Get HIDL service names
1451 using ::android::hardware::media::c2::V1_0::IComponentStore;
1452 using ::android::hidl::manager::V1_2::IServiceManager;
1453 while (true) {
1454 sp<IServiceManager> serviceManager = IServiceManager::getService();
1455 CHECK(serviceManager) << "Hardware service manager is not running.";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001456
Wonsik Kime8e98152022-12-16 16:04:17 -08001457 Return<void> transResult;
1458 transResult = serviceManager->listManifestByInterface(
1459 IComponentStore::descriptor,
1460 [&names](
1461 hidl_vec<hidl_string> const& instanceNames) {
1462 names.insert(names.end(), instanceNames.begin(), instanceNames.end());
1463 });
1464 if (transResult.isOk()) {
1465 break;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001466 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001467 LOG(ERROR) << "Could not retrieve the list of service instances of "
1468 << IComponentStore::descriptor
1469 << ". Retrying...";
1470 }
1471 // Sort service names in each category.
1472 std::stable_sort(
1473 names.begin(), names.end(),
1474 [](const std::string &a, const std::string &b) {
1475 // First compare by prefix: default -> vendor -> {everything else}
1476 constexpr int DEFAULT = 1;
1477 constexpr int VENDOR = 2;
1478 constexpr int OTHER = 3;
1479 int aPrefix = ((a.compare(0, 7, "default") == 0) ? DEFAULT :
1480 (a.compare(0, 6, "vendor") == 0) ? VENDOR :
1481 OTHER);
1482 int bPrefix = ((b.compare(0, 7, "default") == 0) ? DEFAULT :
1483 (b.compare(0, 6, "vendor") == 0) ? VENDOR :
1484 OTHER);
1485 if (aPrefix != bPrefix) {
1486 return aPrefix < bPrefix;
1487 }
1488 // If the prefix is the same, compare alphabetically
1489 return a < b;
1490 });
1491
1492 // Summarize to logcat.
1493 if (names.empty()) {
1494 LOG(INFO) << "No Codec2 services declared in the manifest.";
1495 } else {
1496 std::stringstream stringOutput;
1497 stringOutput << "Available Codec2 services:";
1498 for (std::string const& name : names) {
1499 stringOutput << " \"" << name << "\"";
1500 }
1501 LOG(INFO) << stringOutput.str();
1502 }
1503
1504 return names;
1505}
1506
1507std::vector<std::string> const& Codec2Client::GetServiceNames() {
1508 static std::vector<std::string> sServiceNames = CacheServiceNames();
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001509 return sServiceNames;
1510}
1511
Pawin Vongmasa36653902018-11-15 00:10:25 -08001512std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001513 const char* name,
1514 bool setAsPreferredCodec2ComponentStore) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001515 size_t index = getServiceIndex(name);
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001516 if (index == GetServiceNames().size()) {
1517 if (setAsPreferredCodec2ComponentStore) {
1518 LOG(WARNING) << "CreateFromService(" << name
1519 << ") -- preferred C2ComponentStore not set.";
1520 }
1521 return nullptr;
1522 }
1523 std::shared_ptr<Codec2Client> client = _CreateFromIndex(index);
1524 if (setAsPreferredCodec2ComponentStore) {
1525 SetPreferredCodec2ComponentStore(
1526 std::make_shared<Client2Store>(client));
1527 LOG(INFO) << "CreateFromService(" << name
1528 << ") -- service set as preferred C2ComponentStore.";
1529 }
1530 return client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001531}
1532
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001533std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
1534 CreateFromAllServices() {
1535 std::vector<std::shared_ptr<Codec2Client>> clients(
1536 GetServiceNames().size());
1537 for (size_t i = GetServiceNames().size(); i > 0; ) {
1538 --i;
1539 clients[i] = _CreateFromIndex(i);
1540 }
1541 return clients;
1542}
1543
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001544std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001545 std::string const& name = GetServiceNames()[index];
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001546 LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\"";
Wonsik Kime8e98152022-12-16 16:04:17 -08001547
1548 if (c2_aidl::utils::IsEnabled()) {
1549 std::string instanceName =
1550 ::android::base::StringPrintf("%s/%s", AidlBase::descriptor, name.c_str());
1551 if (AServiceManager_isDeclared(instanceName.c_str())) {
1552 std::shared_ptr<AidlBase> baseStore = AidlBase::fromBinder(
1553 ::ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));
1554 CHECK(baseStore) << "Codec2 AIDL service \"" << name << "\""
1555 " inaccessible for unknown reasons.";
1556 LOG(VERBOSE) << "Client to Codec2 AIDL service \"" << name << "\" created";
1557 std::shared_ptr<c2_aidl::IConfigurable> configurable;
1558 ::ndk::ScopedAStatus transStatus = baseStore->getConfigurable(&configurable);
1559 CHECK(transStatus.isOk()) << "Codec2 AIDL service \"" << name << "\""
1560 "does not have IConfigurable.";
1561 return std::make_shared<Codec2Client>(baseStore, configurable, index);
1562 }
1563 }
1564
1565 std::string instanceName = "android.hardware.media.c2/" + name;
1566 sp<HidlBase> baseStore = HidlBase::getService(name);
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001567 CHECK(baseStore) << "Codec2 service \"" << name << "\""
1568 " inaccessible for unknown reasons.";
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001569 LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created";
Wonsik Kime8e98152022-12-16 16:04:17 -08001570 Return<sp<c2_hidl::IConfigurable>> transResult = baseStore->getConfigurable();
Sungtak Leef4b39512023-05-10 07:17:22 +00001571 CHECK(transResult.isOk()) << "Codec2 service \"" << name << "\""
1572 "does not have IConfigurable.";
Wonsik Kime8e98152022-12-16 16:04:17 -08001573 sp<c2_hidl::IConfigurable> configurable =
1574 static_cast<sp<c2_hidl::IConfigurable>>(transResult);
Sungtak Leef4b39512023-05-10 07:17:22 +00001575 return std::make_shared<Codec2Client>(baseStore, configurable, index);
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001576}
1577
1578c2_status_t Codec2Client::ForAllServices(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001579 const std::string &key,
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001580 size_t numberOfAttempts,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001581 std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
1582 predicate) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001583 c2_status_t status = C2_NO_INIT; // no IComponentStores present
1584
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001585 // Cache the mapping key -> index of Codec2Client in Cache::List().
Pawin Vongmasa36653902018-11-15 00:10:25 -08001586 static std::mutex key2IndexMutex;
1587 static std::map<std::string, size_t> key2Index;
1588
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001589 // By default try all stores. However, try the last known client first. If
1590 // the last known client fails, retry once. We do this by pushing the last
1591 // known client in front of the list of all clients.
Pawin Vongmasa36653902018-11-15 00:10:25 -08001592 std::deque<size_t> indices;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001593 for (size_t index = Cache::List().size(); index > 0; ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001594 indices.push_front(--index);
1595 }
1596
1597 bool wasMapped = false;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001598 {
1599 std::scoped_lock lock{key2IndexMutex};
1600 auto it = key2Index.find(key);
1601 if (it != key2Index.end()) {
1602 indices.push_front(it->second);
1603 wasMapped = true;
1604 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001605 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001606
1607 for (size_t index : indices) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001608 Cache& cache = Cache::List()[index];
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001609 for (size_t tries = numberOfAttempts; tries > 0; --tries) {
1610 std::shared_ptr<Codec2Client> client{cache.getClient()};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001611 status = predicate(client);
1612 if (status == C2_OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001613 std::scoped_lock lock{key2IndexMutex};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001614 key2Index[key] = index; // update last known client index
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001615 return C2_OK;
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001616 } else if (status == C2_NO_MEMORY) {
1617 return C2_NO_MEMORY;
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001618 } else if (status == C2_TRANSACTION_FAILED) {
1619 LOG(WARNING) << "\"" << key << "\" failed for service \""
1620 << client->getName()
1621 << "\" due to transaction failure. "
1622 << "(Service may have crashed.)"
1623 << (tries > 1 ? " Retrying..." : "");
1624 cache.invalidate();
1625 continue;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001626 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001627 if (wasMapped) {
1628 LOG(INFO) << "\"" << key << "\" became invalid in service \""
1629 << client->getName() << "\". Retrying...";
1630 wasMapped = false;
1631 }
1632 break;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001633 }
1634 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001635 return status; // return the last status from a valid client
Pawin Vongmasa36653902018-11-15 00:10:25 -08001636}
1637
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001638c2_status_t Codec2Client::CreateComponentByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001639 const char* componentName,
1640 const std::shared_ptr<Listener>& listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001641 std::shared_ptr<Component>* component,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001642 std::shared_ptr<Codec2Client>* owner,
1643 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001644 std::string key{"create:"};
1645 key.append(componentName);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001646 c2_status_t status = ForAllServices(
1647 key,
1648 numberOfAttempts,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001649 [owner, component, componentName, &listener](
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001650 const std::shared_ptr<Codec2Client> &client)
1651 -> c2_status_t {
1652 c2_status_t status = client->createComponent(componentName,
1653 listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001654 component);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001655 if (status == C2_OK) {
1656 if (owner) {
1657 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001658 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001659 } else if (status != C2_NOT_FOUND) {
1660 LOG(DEBUG) << "IComponentStore("
1661 << client->getServiceName()
1662 << ")::createComponent(\"" << componentName
1663 << "\") returned status = "
1664 << status << ".";
1665 }
1666 return status;
1667 });
1668 if (status != C2_OK) {
1669 LOG(DEBUG) << "Failed to create component \"" << componentName
1670 << "\" from all known services. "
1671 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001672 }
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001673 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001674}
1675
Wonsik Kime8e98152022-12-16 16:04:17 -08001676std::shared_ptr<Codec2Client::Interface> Codec2Client::CreateInterfaceByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001677 const char* interfaceName,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001678 std::shared_ptr<Codec2Client>* owner,
1679 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001680 std::string key{"create:"};
1681 key.append(interfaceName);
1682 std::shared_ptr<Interface> interface;
1683 c2_status_t status = ForAllServices(
1684 key,
1685 numberOfAttempts,
1686 [owner, &interface, interfaceName](
1687 const std::shared_ptr<Codec2Client> &client)
1688 -> c2_status_t {
1689 c2_status_t status = client->createInterface(interfaceName,
1690 &interface);
1691 if (status == C2_OK) {
1692 if (owner) {
1693 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001694 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001695 } else if (status != C2_NOT_FOUND) {
1696 LOG(DEBUG) << "IComponentStore("
1697 << client->getServiceName()
1698 << ")::createInterface(\"" << interfaceName
1699 << "\") returned status = "
1700 << status << ".";
1701 }
1702 return status;
1703 });
1704 if (status != C2_OK) {
1705 LOG(DEBUG) << "Failed to create interface \"" << interfaceName
1706 << "\" from all known services. "
1707 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001708 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001709 return interface;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001710}
1711
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001712std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
1713 static std::vector<C2Component::Traits> sList{[]() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001714 std::vector<C2Component::Traits> list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001715 for (Cache& cache : Cache::List()) {
1716 std::vector<C2Component::Traits> const& traits = cache.getTraits();
1717 list.insert(list.end(), traits.begin(), traits.end());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001718 }
1719 return list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001720 }()};
1721 return sList;
1722}
Pawin Vongmasa36653902018-11-15 00:10:25 -08001723
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001724std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
1725 char const* serviceName) {
Pawin Vongmasa18588322019-05-18 01:52:13 -07001726 int32_t inputSurfaceSetting = ::android::base::GetIntProperty(
1727 "debug.stagefright.c2inputsurface", int32_t(0));
1728 if (inputSurfaceSetting <= 0) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001729 return nullptr;
1730 }
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001731 size_t index = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001732 if (serviceName) {
1733 index = getServiceIndex(serviceName);
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001734 if (index == GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001735 LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
1736 << serviceName << "\"";
1737 }
1738 }
1739
1740 std::shared_ptr<Codec2Client::InputSurface> inputSurface;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001741 if (index != GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001742 std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
1743 if (client->createInputSurface(&inputSurface) == C2_OK) {
1744 return inputSurface;
1745 }
1746 }
1747 LOG(INFO) << "CreateInputSurface -- attempting to create an input surface "
1748 "from all services...";
1749 for (Cache& cache : Cache::List()) {
1750 std::shared_ptr<Codec2Client> client = cache.getClient();
1751 if (client->createInputSurface(&inputSurface) == C2_OK) {
1752 LOG(INFO) << "CreateInputSurface -- input surface obtained from "
1753 "service \"" << client->getServiceName() << "\"";
1754 return inputSurface;
1755 }
1756 }
1757 LOG(WARNING) << "CreateInputSurface -- failed to create an input surface "
1758 "from all services";
1759 return nullptr;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001760}
1761
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001762// Codec2Client::Interface
Wonsik Kime8e98152022-12-16 16:04:17 -08001763Codec2Client::Interface::Interface(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001764 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001765 [base]() -> sp<c2_hidl::IConfigurable> {
1766 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001767 base->getConfigurable();
1768 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001769 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001770 nullptr;
1771 }()
1772 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001773 mHidlBase{base} {
1774}
1775
1776Codec2Client::Interface::Interface(const std::shared_ptr<AidlBase>& base)
1777 : Configurable{
1778 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1779 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1780 ::ndk::ScopedAStatus transStatus =
1781 base->getConfigurable(&aidlConfigurable);
1782 return transStatus.isOk() ? aidlConfigurable : nullptr;
1783 }()
1784 },
1785 mAidlBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001786}
1787
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001788// Codec2Client::Component
Wonsik Kime8e98152022-12-16 16:04:17 -08001789
1790class Codec2Client::Component::AidlDeathManager {
1791public:
1792 AidlDeathManager()
1793 : mSeq(0),
1794 mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) {
1795 }
1796
1797 ~AidlDeathManager() = default;
1798
1799 bool linkToDeath(
1800 const std::shared_ptr<Component> &comp,
1801 const std::shared_ptr<Listener> &listener,
1802 size_t *seqPtr) {
1803 std::unique_lock lock(mMutex);
1804 size_t seq = mSeq++;
1805 if (!mMap.try_emplace(seq, comp, listener).second) {
1806 return false;
1807 }
1808 if (STATUS_OK != AIBinder_linkToDeath(
1809 comp->mAidlBase->asBinder().get(), mDeathRecipient.get(), (void *)seq)) {
1810 mMap.erase(seq);
1811 return false;
1812 }
1813 *seqPtr = seq;
1814 return true;
1815 }
1816
1817 void unlinkToDeath(size_t seq, const std::shared_ptr<AidlBase> &base) {
1818 std::unique_lock lock(mMutex);
1819 AIBinder_unlinkToDeath(base->asBinder().get(), mDeathRecipient.get(), (void *)seq);
1820 mMap.erase(seq);
1821 }
1822
1823private:
1824 std::mutex mMutex;
1825 size_t mSeq;
1826 typedef std::tuple<std::weak_ptr<Component>, std::weak_ptr<Listener>> Context;
1827 std::map<size_t, Context> mMap;
1828 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
1829
1830 bool extractContext(size_t seq, Context *context) {
1831 std::unique_lock lock(mMutex);
1832 auto node = mMap.extract(seq);
1833 if (!node) {
1834 return false;
1835 }
1836 *context = node.mapped();
1837 return true;
1838 }
1839
1840 static void OnBinderDied(void *cookie) {
1841 size_t seq = size_t(cookie);
1842 Context context;
1843 if (!Component::GetAidlDeathManager()->extractContext(seq, &context)) {
1844 return;
1845 }
1846 std::weak_ptr<Component> weakComponent;
1847 std::weak_ptr<Listener> weakListener;
1848 std::tie(weakComponent, weakListener) = context;
1849 if (std::shared_ptr<Listener> listener = weakListener.lock()) {
1850 listener->onDeath(weakComponent);
1851 } else {
1852 LOG(DEBUG) << "onDeath -- listener died.";
1853 }
1854 }
1855};
1856
1857Codec2Client::Component::Component(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001858 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001859 [base]() -> sp<c2_hidl::IConfigurable> {
1860 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001861 base->getInterface();
1862 if (!transResult1.isOk()) {
1863 return nullptr;
1864 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001865 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1866 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001867 getConfigurable();
1868 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001869 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001870 nullptr;
1871 }()
1872 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001873 mHidlBase1_0{base},
1874 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1875 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1876 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001877 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1878}
1879
Wonsik Kime8e98152022-12-16 16:04:17 -08001880Codec2Client::Component::Component(const sp<HidlBase1_1>& base)
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001881 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001882 [base]() -> sp<c2_hidl::IConfigurable> {
1883 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001884 base->getInterface();
1885 if (!transResult1.isOk()) {
1886 return nullptr;
1887 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001888 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1889 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001890 getConfigurable();
1891 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001892 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001893 nullptr;
1894 }()
1895 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001896 mHidlBase1_0{base},
1897 mHidlBase1_1{base},
1898 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1899 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Sungtak Lee8577dab2021-03-12 02:25:50 -08001900 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1901}
1902
Wonsik Kime8e98152022-12-16 16:04:17 -08001903Codec2Client::Component::Component(const sp<HidlBase1_2>& base)
Sungtak Lee8577dab2021-03-12 02:25:50 -08001904 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001905 [base]() -> sp<c2_hidl::IConfigurable> {
1906 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Sungtak Lee8577dab2021-03-12 02:25:50 -08001907 base->getInterface();
1908 if (!transResult1.isOk()) {
1909 return nullptr;
1910 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001911 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1912 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Sungtak Lee8577dab2021-03-12 02:25:50 -08001913 getConfigurable();
1914 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001915 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Sungtak Lee8577dab2021-03-12 02:25:50 -08001916 nullptr;
1917 }()
1918 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001919 mHidlBase1_0{base},
1920 mHidlBase1_1{base},
1921 mHidlBase1_2{base},
1922 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
1923 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1924}
1925
1926Codec2Client::Component::Component(const std::shared_ptr<AidlBase> &base)
1927 : Configurable{
1928 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1929 std::shared_ptr<c2_aidl::IComponentInterface> aidlIntf;
1930 ::ndk::ScopedAStatus transStatus = base->getInterface(&aidlIntf);
1931 if (!transStatus.isOk()) {
1932 return nullptr;
1933 }
1934 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1935 transStatus = aidlIntf->getConfigurable(&aidlConfigurable);
1936 return transStatus.isOk() ? aidlConfigurable : nullptr;
1937 }()
1938 },
1939 mAidlBase{base},
1940 mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001941 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001942}
1943
1944Codec2Client::Component::~Component() {
Wonsik Kime8e98152022-12-16 16:04:17 -08001945 if (mAidlDeathSeq) {
1946 GetAidlDeathManager()->unlinkToDeath(*mAidlDeathSeq, mAidlBase);
1947 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001948}
1949
1950c2_status_t Codec2Client::Component::createBlockPool(
1951 C2Allocator::id_t id,
1952 C2BlockPool::local_id_t* blockPoolId,
1953 std::shared_ptr<Codec2Client::Configurable>* configurable) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001954 if (mAidlBase) {
1955 c2_aidl::IComponent::BlockPool aidlBlockPool;
Ryan Prichard8d37bb02023-09-13 20:23:15 -07001956 ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id),
1957 &aidlBlockPool);
Wonsik Kime8e98152022-12-16 16:04:17 -08001958 c2_status_t status = GetC2Status(transStatus, "createBlockPool");
1959 if (status != C2_OK) {
1960 return status;
1961 }
1962 *blockPoolId = aidlBlockPool.blockPoolId;
1963 *configurable = std::make_shared<Configurable>(aidlBlockPool.configurable);
1964 return C2_OK;
1965 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001966 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001967 Return<void> transStatus = mHidlBase1_0->createBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001968 static_cast<uint32_t>(id),
1969 [&status, blockPoolId, configurable](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001970 c2_hidl::Status s,
Pawin Vongmasa36653902018-11-15 00:10:25 -08001971 uint64_t pId,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001972 const sp<c2_hidl::IConfigurable>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001973 status = static_cast<c2_status_t>(s);
1974 configurable->reset();
1975 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001976 LOG(DEBUG) << "createBlockPool -- call failed: "
1977 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001978 return;
1979 }
1980 *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001981 *configurable = std::make_shared<Configurable>(c);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001982 });
1983 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001984 LOG(ERROR) << "createBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001985 return C2_TRANSACTION_FAILED;
1986 }
1987 return status;
1988}
1989
1990c2_status_t Codec2Client::Component::destroyBlockPool(
1991 C2BlockPool::local_id_t localId) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001992 if (mAidlBase) {
1993 ::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId);
1994 return GetC2Status(transStatus, "destroyBlockPool");
1995 }
1996 Return<c2_hidl::Status> transResult = mHidlBase1_0->destroyBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001997 static_cast<uint64_t>(localId));
1998 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001999 LOG(ERROR) << "destroyBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002000 return C2_TRANSACTION_FAILED;
2001 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002002 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002003}
2004
Wonsik Kimab34ed62019-01-31 15:28:46 -08002005void Codec2Client::Component::handleOnWorkDone(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002006 const std::list<std::unique_ptr<C2Work>> &workItems) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002007 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002008 mOutputBufferQueue->holdBufferQueueBlocks(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002009}
2010
2011c2_status_t Codec2Client::Component::queue(
2012 std::list<std::unique_ptr<C2Work>>* const items) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002013 if (mAidlBase) {
2014 c2_aidl::WorkBundle workBundle;
2015 if (!c2_aidl::utils::ToAidl(&workBundle, *items, mAidlBufferPoolSender.get())) {
2016 LOG(ERROR) << "queue -- bad input.";
2017 return C2_TRANSACTION_FAILED;
2018 }
2019 ::ndk::ScopedAStatus transStatus = mAidlBase->queue(workBundle);
2020 return GetC2Status(transStatus, "queue");
2021 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002022 c2_hidl::WorkBundle workBundle;
Wonsik Kime8e98152022-12-16 16:04:17 -08002023 if (!c2_hidl::utils::objcpy(&workBundle, *items, mHidlBufferPoolSender.get())) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002024 LOG(ERROR) << "queue -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002025 return C2_TRANSACTION_FAILED;
2026 }
Wonsik Kime8e98152022-12-16 16:04:17 -08002027 Return<c2_hidl::Status> transStatus = mHidlBase1_0->queue(workBundle);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002028 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002029 LOG(ERROR) << "queue -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002030 return C2_TRANSACTION_FAILED;
2031 }
2032 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002033 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002034 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002035 LOG(DEBUG) << "queue -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002036 }
2037 return status;
2038}
2039
2040c2_status_t Codec2Client::Component::flush(
2041 C2Component::flush_mode_t mode,
2042 std::list<std::unique_ptr<C2Work>>* const flushedWork) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002043 (void)mode; // Flush mode isn't supported in HIDL/AIDL yet.
2044 c2_status_t status = C2_OK;
2045 if (mAidlBase) {
2046 c2_aidl::WorkBundle workBundle;
2047 ::ndk::ScopedAStatus transStatus = mAidlBase->flush(&workBundle);
2048 c2_status_t status = GetC2Status(transStatus, "flush");
2049 if (status != C2_OK) {
2050 return status;
2051 }
2052 if (!c2_aidl::utils::FromAidl(flushedWork, workBundle)) {
2053 LOG(DEBUG) << "flush -- flushedWork corrupted.";
2054 return C2_CORRUPTED;
2055 }
2056 } else {
2057 Return<void> transStatus = mHidlBase1_0->flush(
2058 [&status, flushedWork](
2059 c2_hidl::Status s, const c2_hidl::WorkBundle& wb) {
2060 status = static_cast<c2_status_t>(s);
2061 if (status != C2_OK) {
2062 LOG(DEBUG) << "flush -- call failed: " << status << ".";
2063 return;
2064 }
2065 if (!c2_hidl::utils::objcpy(flushedWork, wb)) {
2066 status = C2_CORRUPTED;
2067 } else {
2068 status = C2_OK;
2069 }
2070 });
2071 if (!transStatus.isOk()) {
2072 LOG(ERROR) << "flush -- transaction failed.";
2073 return C2_TRANSACTION_FAILED;
2074 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002075 }
2076
2077 // Indices of flushed work items.
2078 std::vector<uint64_t> flushedIndices;
2079 for (const std::unique_ptr<C2Work> &work : *flushedWork) {
2080 if (work) {
2081 if (work->worklets.empty()
2082 || !work->worklets.back()
2083 || (work->worklets.back()->output.flags &
2084 C2FrameData::FLAG_INCOMPLETE) == 0) {
2085 // input is complete
2086 flushedIndices.emplace_back(
2087 work->input.ordinal.frameIndex.peeku());
2088 }
2089 }
2090 }
2091
Pawin Vongmasa36653902018-11-15 00:10:25 -08002092 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002093 mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002094
2095 return status;
2096}
2097
2098c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002099 if (mAidlBase) {
2100 ::ndk::ScopedAStatus transStatus = mAidlBase->drain(
2101 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2102 return GetC2Status(transStatus, "drain");
2103 }
2104 Return<c2_hidl::Status> transStatus = mHidlBase1_0->drain(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002105 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2106 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002107 LOG(ERROR) << "drain -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002108 return C2_TRANSACTION_FAILED;
2109 }
2110 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002111 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002112 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002113 LOG(DEBUG) << "drain -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002114 }
2115 return status;
2116}
2117
2118c2_status_t Codec2Client::Component::start() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002119 if (mAidlBase) {
2120 ::ndk::ScopedAStatus transStatus = mAidlBase->start();
2121 return GetC2Status(transStatus, "start");
2122 }
2123 Return<c2_hidl::Status> transStatus = mHidlBase1_0->start();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002124 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002125 LOG(ERROR) << "start -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002126 return C2_TRANSACTION_FAILED;
2127 }
2128 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002129 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002130 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002131 LOG(DEBUG) << "start -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002132 }
2133 return status;
2134}
2135
2136c2_status_t Codec2Client::Component::stop() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002137 if (mAidlBase) {
2138 ::ndk::ScopedAStatus transStatus = mAidlBase->stop();
2139 return GetC2Status(transStatus, "stop");
2140 }
2141 Return<c2_hidl::Status> transStatus = mHidlBase1_0->stop();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002142 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002143 LOG(ERROR) << "stop -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002144 return C2_TRANSACTION_FAILED;
2145 }
2146 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002147 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002148 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002149 LOG(DEBUG) << "stop -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002150 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002151 return status;
2152}
2153
2154c2_status_t Codec2Client::Component::reset() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002155 if (mAidlBase) {
2156 ::ndk::ScopedAStatus transStatus = mAidlBase->reset();
2157 return GetC2Status(transStatus, "reset");
2158 }
2159 Return<c2_hidl::Status> transStatus = mHidlBase1_0->reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002160 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002161 LOG(ERROR) << "reset -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002162 return C2_TRANSACTION_FAILED;
2163 }
2164 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002165 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002166 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002167 LOG(DEBUG) << "reset -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002168 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002169 return status;
2170}
2171
2172c2_status_t Codec2Client::Component::release() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002173 if (mAidlBase) {
2174 ::ndk::ScopedAStatus transStatus = mAidlBase->release();
2175 return GetC2Status(transStatus, "release");
2176 }
2177 Return<c2_hidl::Status> transStatus = mHidlBase1_0->release();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002178 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002179 LOG(ERROR) << "release -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002180 return C2_TRANSACTION_FAILED;
2181 }
2182 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002183 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002184 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002185 LOG(DEBUG) << "release -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002186 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002187 return status;
2188}
2189
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002190c2_status_t Codec2Client::Component::configureVideoTunnel(
2191 uint32_t avSyncHwId,
2192 native_handle_t** sidebandHandle) {
2193 *sidebandHandle = nullptr;
Wonsik Kime8e98152022-12-16 16:04:17 -08002194 if (mAidlBase) {
2195 ::aidl::android::hardware::common::NativeHandle handle;
2196 ::ndk::ScopedAStatus transStatus = mAidlBase->configureVideoTunnel(avSyncHwId, &handle);
2197 c2_status_t status = GetC2Status(transStatus, "configureVideoTunnel");
2198 if (status != C2_OK) {
2199 return status;
2200 }
2201 if (isAidlNativeHandleEmpty(handle)) {
2202 LOG(DEBUG) << "configureVideoTunnel -- empty handle returned";
2203 } else {
2204 *sidebandHandle = dupFromAidl(handle);
2205 }
2206 return C2_OK;
2207 }
2208 if (!mHidlBase1_1) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002209 return C2_OMITTED;
2210 }
2211 c2_status_t status{};
Wonsik Kime8e98152022-12-16 16:04:17 -08002212 Return<void> transStatus = mHidlBase1_1->configureVideoTunnel(avSyncHwId,
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002213 [&status, sidebandHandle](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002214 c2_hidl::Status s, hardware::hidl_handle const& h) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002215 status = static_cast<c2_status_t>(s);
2216 if (h.getNativeHandle()) {
2217 *sidebandHandle = native_handle_clone(h.getNativeHandle());
2218 }
2219 });
2220 if (!transStatus.isOk()) {
2221 LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
2222 return C2_TRANSACTION_FAILED;
2223 }
2224 return status;
2225}
2226
Pawin Vongmasa36653902018-11-15 00:10:25 -08002227c2_status_t Codec2Client::Component::setOutputSurface(
2228 C2BlockPool::local_id_t blockPoolId,
2229 const sp<IGraphicBufferProducer>& surface,
Sungtak Leedb14cba2021-04-10 00:50:23 -07002230 uint32_t generation,
2231 int maxDequeueCount) {
Sungtak Lee08515812019-06-05 11:16:32 -07002232 uint64_t bqId = 0;
2233 sp<IGraphicBufferProducer> nullIgbp;
2234 sp<HGraphicBufferProducer2> nullHgbp;
Pawin Vongmasa3866c7e2019-01-31 05:21:29 -08002235
Sungtak Lee08515812019-06-05 11:16:32 -07002236 sp<HGraphicBufferProducer2> igbp = surface ?
2237 surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp;
2238 if (surface && !igbp) {
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002239 igbp = new B2HGraphicBufferProducer2(surface);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002240 }
2241
Sungtak Leefb579022022-05-10 06:36:15 +00002242 std::scoped_lock lock(mOutputMutex);
Sungtak Leea714f112021-03-16 05:40:03 -07002243 std::shared_ptr<SurfaceSyncObj> syncObj;
2244
Sungtak Lee08515812019-06-05 11:16:32 -07002245 if (!surface) {
Sungtak Leedb14cba2021-04-10 00:50:23 -07002246 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002247 } else if (surface->getUniqueId(&bqId) != OK) {
2248 LOG(ERROR) << "setOutputSurface -- "
2249 "cannot obtain bufferqueue id.";
2250 bqId = 0;
Sungtak Leedb14cba2021-04-10 00:50:23 -07002251 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002252 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08002253 mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount,
2254 mHidlBase1_2 ? &syncObj : nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002255 }
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002256
2257 // set consumer bits
2258 // TODO: should this get incorporated into setOutputSurface method so that consumer bits
2259 // can be set atomically?
2260 uint64_t consumerUsage = kDefaultConsumerUsage;
2261 {
2262 if (surface) {
Sungtak Lee46a69d62023-08-12 07:24:24 +00002263 uint64_t usage = 0;
2264 status_t err = surface->getConsumerUsage(&usage);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002265 if (err != NO_ERROR) {
2266 ALOGD("setOutputSurface -- failed to get consumer usage bits (%d/%s). ignoring",
2267 err, asString(err));
2268 } else {
2269 // Note: we are adding the default usage because components must support
2270 // producing output frames that can be displayed an all output surfaces.
2271
2272 // TODO: do not set usage for tunneled scenario. It is unclear if consumer usage
2273 // is meaningful in a tunneled scenario; on one hand output buffers exist, but
2274 // they do not exist inside of C2 scope. Any buffer usage shall be communicated
2275 // through the sideband channel.
2276
Sungtak Lee46a69d62023-08-12 07:24:24 +00002277 consumerUsage = usage | kDefaultConsumerUsage;
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002278 }
2279 }
2280
2281 C2StreamUsageTuning::output outputUsage{
2282 0u, C2AndroidMemoryUsage::FromGrallocUsage(consumerUsage).expected};
2283 std::vector<std::unique_ptr<C2SettingResult>> failures;
2284 c2_status_t err = config({&outputUsage}, C2_MAY_BLOCK, &failures);
2285 if (err != C2_OK) {
2286 ALOGD("setOutputSurface -- failed to set consumer usage (%d/%s)",
2287 err, asString(err));
2288 }
2289 }
2290 ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
2291 generation, (long long)consumerUsage, syncObj ? " sync" : "");
Sungtak Lee08515812019-06-05 11:16:32 -07002292
Wonsik Kime8e98152022-12-16 16:04:17 -08002293 if (mAidlBase) {
2294 // FIXME
2295 return C2_OMITTED;
2296 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002297 Return<c2_hidl::Status> transStatus = syncObj ?
Wonsik Kime8e98152022-12-16 16:04:17 -08002298 mHidlBase1_2->setOutputSurfaceWithSyncObj(
Sungtak Leea714f112021-03-16 05:40:03 -07002299 static_cast<uint64_t>(blockPoolId),
2300 bqId == 0 ? nullHgbp : igbp, *syncObj) :
Wonsik Kime8e98152022-12-16 16:04:17 -08002301 mHidlBase1_0->setOutputSurface(
Sungtak Leea714f112021-03-16 05:40:03 -07002302 static_cast<uint64_t>(blockPoolId),
2303 bqId == 0 ? nullHgbp : igbp);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002304
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002305 mOutputBufferQueue->expireOldWaiters();
2306
Pawin Vongmasa36653902018-11-15 00:10:25 -08002307 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002308 LOG(ERROR) << "setOutputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002309 return C2_TRANSACTION_FAILED;
2310 }
2311 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002312 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002313 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002314 LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002315 }
Sungtak Leea714f112021-03-16 05:40:03 -07002316 ALOGD("Surface configure completed");
Pawin Vongmasa36653902018-11-15 00:10:25 -08002317 return status;
2318}
2319
2320status_t Codec2Client::Component::queueToOutputSurface(
2321 const C2ConstGraphicBlock& block,
2322 const QueueBufferInput& input,
2323 QueueBufferOutput* output) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002324 return mOutputBufferQueue->outputBuffer(block, input, output);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002325}
2326
Brian Lindahlc953b462023-01-27 16:21:43 -07002327void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
2328 mOutputBufferQueue->pollForRenderedFrames(delta);
2329}
2330
Sungtak Leea714f112021-03-16 05:40:03 -07002331void Codec2Client::Component::setOutputSurfaceMaxDequeueCount(
2332 int maxDequeueCount) {
2333 mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount);
2334}
2335
Sungtak Leec7da7a02022-05-05 08:45:33 +00002336void Codec2Client::Component::stopUsingOutputSurface(
2337 C2BlockPool::local_id_t blockPoolId) {
Sungtak Leefb579022022-05-10 06:36:15 +00002338 std::scoped_lock lock(mOutputMutex);
Sungtak Leec7da7a02022-05-05 08:45:33 +00002339 mOutputBufferQueue->stop();
Wonsik Kime8e98152022-12-16 16:04:17 -08002340 if (mAidlBase) {
2341 // FIXME
2342 return;
2343 }
2344 Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface(
Sungtak Leec7da7a02022-05-05 08:45:33 +00002345 static_cast<uint64_t>(blockPoolId), nullptr);
2346 if (!transStatus.isOk()) {
2347 LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed.";
2348 } else {
2349 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002350 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Sungtak Leec7da7a02022-05-05 08:45:33 +00002351 if (status != C2_OK) {
2352 LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: "
2353 << status << ".";
2354 }
2355 }
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002356 mOutputBufferQueue->expireOldWaiters();
Sungtak Leec7da7a02022-05-05 08:45:33 +00002357}
2358
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002359c2_status_t Codec2Client::Component::connectToInputSurface(
2360 const std::shared_ptr<InputSurface>& inputSurface,
2361 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002362 if (mAidlBase) {
2363 // FIXME
2364 return C2_OMITTED;
2365 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002366 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002367 Return<void> transStatus = mHidlBase1_0->connectToInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002368 inputSurface->mBase,
2369 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002370 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002371 status = static_cast<c2_status_t>(s);
2372 if (status != C2_OK) {
2373 LOG(DEBUG) << "connectToInputSurface -- call failed: "
2374 << status << ".";
2375 return;
2376 }
2377 *connection = std::make_shared<InputSurfaceConnection>(c);
2378 });
Pawin Vongmasa36653902018-11-15 00:10:25 -08002379 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002380 LOG(ERROR) << "connectToInputSurface -- transaction failed";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002381 return C2_TRANSACTION_FAILED;
2382 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002383 return status;
2384}
2385
2386c2_status_t Codec2Client::Component::connectToOmxInputSurface(
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002387 const sp<HGraphicBufferProducer1>& producer,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002388 const sp<HGraphicBufferSource>& source,
2389 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002390 if (mAidlBase) {
2391 LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL";
2392 return C2_OMITTED;
2393 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002394 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002395 Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002396 producer, source,
2397 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002398 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002399 status = static_cast<c2_status_t>(s);
2400 if (status != C2_OK) {
2401 LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
2402 << status << ".";
2403 return;
2404 }
2405 *connection = std::make_shared<InputSurfaceConnection>(c);
2406 });
2407 if (!transStatus.isOk()) {
2408 LOG(ERROR) << "connectToOmxInputSurface -- transaction failed.";
2409 return C2_TRANSACTION_FAILED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08002410 }
2411 return status;
2412}
2413
2414c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002415 if (mAidlBase) {
2416 // FIXME
2417 return C2_OMITTED;
2418 }
2419 Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002420 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002421 LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002422 return C2_TRANSACTION_FAILED;
2423 }
2424 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002425 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002426 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002427 LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
2428 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002429 }
2430 return status;
2431}
2432
Wonsik Kime8e98152022-12-16 16:04:17 -08002433Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() {
2434 // This object never gets destructed
2435 static AidlDeathManager *sManager = new AidlDeathManager();
2436 return sManager;
2437}
2438
Pawin Vongmasa36653902018-11-15 00:10:25 -08002439c2_status_t Codec2Client::Component::setDeathListener(
2440 const std::shared_ptr<Component>& component,
2441 const std::shared_ptr<Listener>& listener) {
2442
2443 struct HidlDeathRecipient : public hardware::hidl_death_recipient {
2444 std::weak_ptr<Component> component;
2445 std::weak_ptr<Listener> base;
2446
2447 virtual void serviceDied(
2448 uint64_t /* cookie */,
2449 const wp<::android::hidl::base::V1_0::IBase>& /* who */
2450 ) override {
2451 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
2452 listener->onDeath(component);
2453 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002454 LOG(DEBUG) << "onDeath -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002455 }
2456 }
2457 };
2458
Wonsik Kime8e98152022-12-16 16:04:17 -08002459 if (component->mAidlBase) {
2460 size_t seq;
2461 if (GetAidlDeathManager()->linkToDeath(component, listener, &seq)) {
2462 component->mAidlDeathSeq = seq;
2463 }
2464 return C2_OK;
2465 }
2466
Pawin Vongmasa36653902018-11-15 00:10:25 -08002467 sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient();
2468 deathRecipient->base = listener;
2469 deathRecipient->component = component;
2470
2471 component->mDeathRecipient = deathRecipient;
Wonsik Kime8e98152022-12-16 16:04:17 -08002472 Return<bool> transResult = component->mHidlBase1_0->linkToDeath(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002473 component->mDeathRecipient, 0);
2474 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002475 LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002476 return C2_TRANSACTION_FAILED;
2477 }
2478 if (!static_cast<bool>(transResult)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002479 LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002480 return C2_CORRUPTED;
2481 }
2482 return C2_OK;
2483}
2484
2485// Codec2Client::InputSurface
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002486Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002487 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002488 [base]() -> sp<c2_hidl::IConfigurable> {
2489 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002490 base->getConfigurable();
2491 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002492 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002493 nullptr;
2494 }()
2495 },
2496 mBase{base},
2497 mGraphicBufferProducer{new
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002498 H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> {
2499 Return<sp<HGraphicBufferProducer2>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002500 base->getGraphicBufferProducer();
2501 return transResult.isOk() ?
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002502 static_cast<sp<HGraphicBufferProducer2>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002503 nullptr;
2504 }())} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002505}
2506
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002507sp<IGraphicBufferProducer>
Pawin Vongmasa36653902018-11-15 00:10:25 -08002508 Codec2Client::InputSurface::getGraphicBufferProducer() const {
2509 return mGraphicBufferProducer;
2510}
2511
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002512sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002513 return mBase;
2514}
2515
2516// Codec2Client::InputSurfaceConnection
Pawin Vongmasa36653902018-11-15 00:10:25 -08002517Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002518 const sp<c2_hidl::IInputSurfaceConnection>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002519 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002520 [base]() -> sp<c2_hidl::IConfigurable> {
2521 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002522 base->getConfigurable();
2523 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002524 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002525 nullptr;
2526 }()
2527 },
2528 mBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002529}
2530
2531c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002532 Return<c2_hidl::Status> transResult = mBase->disconnect();
2533 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002534}
2535
2536} // namespace android