blob: 5311b3112abe35212f3e96ae9fe7563fd0b0f046 [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>
Wonsik Kim65febd22023-09-20 16:26:02 -070048#include <android/api-level.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080049#include <android/binder_auto_utils.h>
50#include <android/binder_ibinder.h>
51#include <android/binder_manager.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070052#include <android-base/properties.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080053#include <android-base/stringprintf.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070054#include <bufferpool/ClientManager.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080055#include <bufferpool2/ClientManager.h>
56#include <codec2/aidl/BufferTypes.h>
Wonsik Kim1caded02022-12-09 13:03:11 -080057#include <codec2/aidl/ParamTypes.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070058#include <codec2/hidl/1.0/types.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070059#include <codec2/hidl/1.1/types.h>
Sungtak Lee8577dab2021-03-12 02:25:50 -080060#include <codec2/hidl/1.2/types.h>
Sungtak Leea714f112021-03-16 05:40:03 -070061#include <codec2/hidl/output.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070062
63#include <cutils/native_handle.h>
64#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
65#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080066#include <hardware/gralloc.h> // for GRALLOC_USAGE_*
Pawin Vongmasabf69de92019-10-29 06:21:27 -070067#include <hidl/HidlSupport.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080068#include <system/window.h> // for NATIVE_WINDOW_QUERY_*
69#include <media/stagefright/foundation/ADebug.h> // for asString(status_t)
Pawin Vongmasa36653902018-11-15 00:10:25 -080070
71#include <deque>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070072#include <iterator>
Pawin Vongmasa36653902018-11-15 00:10:25 -080073#include <limits>
74#include <map>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070075#include <mutex>
76#include <sstream>
77#include <thread>
Pawin Vongmasa36653902018-11-15 00:10:25 -080078#include <type_traits>
79#include <vector>
80
Pawin Vongmasa36653902018-11-15 00:10:25 -080081namespace android {
82
83using ::android::hardware::hidl_vec;
84using ::android::hardware::hidl_string;
85using ::android::hardware::Return;
86using ::android::hardware::Void;
Pawin Vongmasa36653902018-11-15 00:10:25 -080087
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080088using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
89 V1_0::IGraphicBufferProducer;
90using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
91 V2_0::IGraphicBufferProducer;
92using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
93 V2_0::utils::B2HGraphicBufferProducer;
94using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
95 V2_0::utils::H2BGraphicBufferProducer;
Sungtak Leea714f112021-03-16 05:40:03 -070096using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080097
Wonsik Kime8e98152022-12-16 16:04:17 -080098namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080099namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
100namespace c2_aidl = ::aidl::android::hardware::media::c2;
101namespace c2_hidl_base = ::android::hardware::media::c2;
102namespace c2_hidl = ::android::hardware::media::c2::V1_2;
103
104using c2_hidl::utils::operator<<;
105
Pawin Vongmasa36653902018-11-15 00:10:25 -0800106namespace /* unnamed */ {
107
108// c2_status_t value that corresponds to hwbinder transaction failure.
109constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
110
Lajos Molnar78aa7c92021-02-18 21:39:01 -0800111// By default prepare buffer to be displayed on any of the common surfaces
112constexpr uint64_t kDefaultConsumerUsage =
113 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER);
114
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700115// Searches for a name in GetServiceNames() and returns the index found. If the
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700116// name is not found, the returned index will be equal to
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700117// GetServiceNames().size().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700118size_t getServiceIndex(char const* name) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700119 std::vector<std::string> const& names = Codec2Client::GetServiceNames();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700120 size_t i = 0;
121 for (; i < names.size(); ++i) {
122 if (name == names[i]) {
123 break;
124 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800125 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700126 return i;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800127}
128
Pawin Vongmasa83d2c552020-03-05 04:36:08 -0800129class Client2Store : public C2ComponentStore {
130 std::shared_ptr<Codec2Client> mClient;
131
132public:
133 Client2Store(std::shared_ptr<Codec2Client> const& client)
134 : mClient(client) { }
135
136 virtual ~Client2Store() = default;
137
138 virtual c2_status_t config_sm(
139 std::vector<C2Param*> const &params,
140 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
141 return mClient->config(params, C2_MAY_BLOCK, failures);
142 };
143
144 virtual c2_status_t copyBuffer(
145 std::shared_ptr<C2GraphicBuffer>,
146 std::shared_ptr<C2GraphicBuffer>) {
147 return C2_OMITTED;
148 }
149
150 virtual c2_status_t createComponent(
151 C2String, std::shared_ptr<C2Component>* const component) {
152 component->reset();
153 return C2_OMITTED;
154 }
155
156 virtual c2_status_t createInterface(
157 C2String, std::shared_ptr<C2ComponentInterface>* const interface) {
158 interface->reset();
159 return C2_OMITTED;
160 }
161
162 virtual c2_status_t query_sm(
163 std::vector<C2Param*> const& stackParams,
164 std::vector<C2Param::Index> const& heapParamIndices,
165 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
166 return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
167 }
168
169 virtual c2_status_t querySupportedParams_nb(
170 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
171 return mClient->querySupportedParams(params);
172 }
173
174 virtual c2_status_t querySupportedValues_sm(
175 std::vector<C2FieldSupportedValuesQuery>& fields) const {
176 return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
177 }
178
179 virtual C2String getName() const {
180 return mClient->getName();
181 }
182
183 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
184 return mClient->getParamReflector();
185 }
186
187 virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() {
188 return std::vector<std::shared_ptr<C2Component::Traits const>>();
189 }
190};
191
Wonsik Kime8e98152022-12-16 16:04:17 -0800192c2_status_t GetC2Status(const ::ndk::ScopedAStatus &transStatus, const char *method) {
193 if (!transStatus.isOk()) {
194 if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
195 c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
196 LOG(DEBUG) << method << " -- call failed: " << status << ".";
197 return status;
198 } else {
199 LOG(ERROR) << method << " -- transaction failed.";
200 return C2_TRANSACTION_FAILED;
201 }
202 }
203 return C2_OK;
204}
205
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700206} // unnamed namespace
207
208// This class caches a Codec2Client object and its component traits. The client
209// will be created the first time it is needed, and it can be refreshed if the
210// service dies (by calling invalidate()). The first time listComponents() is
211// called from the client, the result will be cached.
212class Codec2Client::Cache {
213 // Cached client
214 std::shared_ptr<Codec2Client> mClient;
215 mutable std::mutex mClientMutex;
216
217 // Cached component traits
218 std::vector<C2Component::Traits> mTraits;
219 std::once_flag mTraitsInitializationFlag;
220
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700221 // The index of the service. This is based on GetServiceNames().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700222 size_t mIndex;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700223 // Called by s() exactly once to initialize the cache. The index must be a
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700224 // valid index into the vector returned by GetServiceNames(). Calling
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700225 // init(index) will associate the cache to the service with name
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700226 // GetServiceNames()[index].
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700227 void init(size_t index) {
228 mIndex = index;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700229 }
230
231public:
232 Cache() = default;
233
234 // Initializes mClient if needed, then returns mClient.
235 // If the service is unavailable but listed in the manifest, this function
236 // will block indefinitely.
237 std::shared_ptr<Codec2Client> getClient() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700238 std::scoped_lock lock{mClientMutex};
239 if (!mClient) {
240 mClient = Codec2Client::_CreateFromIndex(mIndex);
241 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -0700242 CHECK(mClient) << "Failed to create Codec2Client to service \""
243 << GetServiceNames()[mIndex] << "\". (Index = "
244 << mIndex << ").";
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700245 return mClient;
246 }
247
248 // Causes a subsequent call to getClient() to create a new client. This
249 // function should be called after the service dies.
250 //
251 // Note: This function is called only by ForAllServices().
252 void invalidate() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700253 std::scoped_lock lock{mClientMutex};
254 mClient = nullptr;
255 }
256
257 // Returns a list of traits for components supported by the service. This
258 // list is cached.
259 std::vector<C2Component::Traits> const& getTraits() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700260 std::call_once(mTraitsInitializationFlag, [this]() {
261 bool success{false};
262 // Spin until _listComponents() is successful.
263 while (true) {
264 std::shared_ptr<Codec2Client> client = getClient();
265 mTraits = client->_listComponents(&success);
266 if (success) {
267 break;
268 }
Pawin Vongmasa21617db2020-04-24 06:16:42 -0700269 invalidate();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700270 using namespace std::chrono_literals;
271 static constexpr auto kServiceRetryPeriod = 5s;
272 LOG(INFO) << "Failed to retrieve component traits from service "
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700273 "\"" << GetServiceNames()[mIndex] << "\". "
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700274 "Retrying...";
275 std::this_thread::sleep_for(kServiceRetryPeriod);
276 }
277 });
278 return mTraits;
279 }
280
281 // List() returns the list of all caches.
282 static std::vector<Cache>& List() {
283 static std::vector<Cache> sCaches{[]() {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700284 size_t numServices = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700285 std::vector<Cache> caches(numServices);
286 for (size_t i = 0; i < numServices; ++i) {
287 caches[i].init(i);
288 }
289 return caches;
290 }()};
291 return sCaches;
292 }
293};
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800294// Codec2ConfigurableClient::HidlImpl
Pawin Vongmasa36653902018-11-15 00:10:25 -0800295
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800296struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase {
297 typedef c2_hidl::IConfigurable Base;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800298
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800299 // base cannot be null.
300 explicit HidlImpl(const sp<Base>& base);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800301
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800302 const C2String& getName() const override {
303 return mName;
304 }
305
306 c2_status_t query(
307 const std::vector<C2Param*>& stackParams,
308 const std::vector<C2Param::Index> &heapParamIndices,
309 c2_blocking_t mayBlock,
310 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
311
312 c2_status_t config(
313 const std::vector<C2Param*> &params,
314 c2_blocking_t mayBlock,
315 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
316
317 c2_status_t querySupportedParams(
318 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
319 ) const override;
320
321 c2_status_t querySupportedValues(
322 std::vector<C2FieldSupportedValuesQuery>& fields,
323 c2_blocking_t mayBlock) const override;
324
325private:
326 sp<Base> mBase;
327 const C2String mName;
328};
329
330Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800331 : mBase{base},
332 mName{[base]() -> C2String {
333 C2String outName;
334 Return<void> transStatus = base->getName(
335 [&outName](const hidl_string& name) {
336 outName = name.c_str();
337 });
338 return transStatus.isOk() ? outName : "";
339 }()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800340}
341
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800342c2_status_t Codec2ConfigurableClient::HidlImpl::query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800343 const std::vector<C2Param*> &stackParams,
344 const std::vector<C2Param::Index> &heapParamIndices,
345 c2_blocking_t mayBlock,
346 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800347 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800348 stackParams.size() + heapParamIndices.size());
349 size_t numIndices = 0;
350 for (C2Param* const& stackParam : stackParams) {
351 if (!stackParam) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800352 LOG(WARNING) << "query -- null stack param encountered.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800353 continue;
354 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800355 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800356 }
357 size_t numStackIndices = numIndices;
358 for (const C2Param::Index& index : heapParamIndices) {
359 indices[numIndices++] =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800360 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800361 }
362 indices.resize(numIndices);
363 if (heapParams) {
364 heapParams->reserve(heapParams->size() + numIndices);
365 }
366 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800367 Return<void> transStatus = mBase->query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800368 indices,
369 mayBlock == C2_MAY_BLOCK,
370 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800371 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800372 status = static_cast<c2_status_t>(s);
373 if (status != C2_OK && status != C2_BAD_INDEX) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800374 LOG(DEBUG) << "query -- call failed: "
375 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800376 return;
377 }
378 std::vector<C2Param*> paramPointers;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800379 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800380 LOG(ERROR) << "query -- error while parsing params.";
381 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800382 return;
383 }
384 size_t i = 0;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800385 for (auto it = paramPointers.begin();
386 it != paramPointers.end(); ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800387 C2Param* paramPointer = *it;
388 if (numStackIndices > 0) {
389 --numStackIndices;
390 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800391 LOG(WARNING) << "query -- null stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800392 ++it;
393 continue;
394 }
395 for (; i < stackParams.size() && !stackParams[i]; ) {
396 ++i;
397 }
398 if (i >= stackParams.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800399 LOG(ERROR) << "query -- unexpected error.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800400 status = C2_CORRUPTED;
401 return;
402 }
403 if (stackParams[i]->index() != paramPointer->index()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800404 LOG(WARNING) << "query -- param skipped: "
405 "index = "
406 << stackParams[i]->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800407 stackParams[i++]->invalidate();
408 continue;
409 }
410 if (!stackParams[i++]->updateFrom(*paramPointer)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800411 LOG(WARNING) << "query -- param update failed: "
412 "index = "
413 << paramPointer->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800414 }
415 } else {
416 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800417 LOG(WARNING) << "query -- null heap param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800418 ++it;
419 continue;
420 }
421 if (!heapParams) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800422 LOG(WARNING) << "query -- "
423 "unexpected extra stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800424 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800425 heapParams->emplace_back(
426 C2Param::Copy(*paramPointer));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800427 }
428 }
429 ++it;
430 }
431 });
432 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800433 LOG(ERROR) << "query -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800434 return C2_TRANSACTION_FAILED;
435 }
436 return status;
437}
438
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800439c2_status_t Codec2ConfigurableClient::HidlImpl::config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800440 const std::vector<C2Param*> &params,
441 c2_blocking_t mayBlock,
442 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800443 c2_hidl::Params hidlParams;
444 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800445 LOG(ERROR) << "config -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800446 return C2_TRANSACTION_FAILED;
447 }
448 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800449 Return<void> transStatus = mBase->config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800450 hidlParams,
451 mayBlock == C2_MAY_BLOCK,
452 [&status, &params, failures](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800453 c2_hidl::Status s,
454 const hidl_vec<c2_hidl::SettingResult> f,
455 const c2_hidl::Params& o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800456 status = static_cast<c2_status_t>(s);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800457 if (status != C2_OK && status != C2_BAD_INDEX) {
458 LOG(DEBUG) << "config -- call failed: "
459 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800460 }
461 size_t i = failures->size();
462 failures->resize(i + f.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800463 for (const c2_hidl::SettingResult& sf : f) {
464 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800465 LOG(ERROR) << "config -- "
466 << "invalid SettingResult returned.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800467 return;
468 }
469 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800470 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800471 LOG(ERROR) << "config -- "
472 << "failed to parse returned params.";
473 status = C2_CORRUPTED;
474 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800475 });
476 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800477 LOG(ERROR) << "config -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800478 return C2_TRANSACTION_FAILED;
479 }
480 return status;
481}
482
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800483c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800484 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
485 // TODO: Cache and query properly!
486 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800487 Return<void> transStatus = mBase->querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800488 std::numeric_limits<uint32_t>::min(),
489 std::numeric_limits<uint32_t>::max(),
490 [&status, params](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800491 c2_hidl::Status s,
492 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800493 status = static_cast<c2_status_t>(s);
494 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800495 LOG(DEBUG) << "querySupportedParams -- call failed: "
496 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800497 return;
498 }
499 size_t i = params->size();
500 params->resize(i + p.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800501 for (const c2_hidl::ParamDescriptor& sp : p) {
502 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800503 LOG(ERROR) << "querySupportedParams -- "
504 << "invalid returned ParamDescriptor.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800505 return;
506 }
507 }
508 });
509 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800510 LOG(ERROR) << "querySupportedParams -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800511 return C2_TRANSACTION_FAILED;
512 }
513 return status;
514}
515
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800516c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800517 std::vector<C2FieldSupportedValuesQuery>& fields,
518 c2_blocking_t mayBlock) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800519 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800520 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800521 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800522 LOG(ERROR) << "querySupportedValues -- bad input";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800523 return C2_TRANSACTION_FAILED;
524 }
525 }
526
527 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800528 Return<void> transStatus = mBase->querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800529 inFields,
530 mayBlock == C2_MAY_BLOCK,
531 [&status, &inFields, &fields](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800532 c2_hidl::Status s,
533 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800534 status = static_cast<c2_status_t>(s);
535 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800536 LOG(DEBUG) << "querySupportedValues -- call failed: "
537 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800538 return;
539 }
540 if (r.size() != fields.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800541 LOG(ERROR) << "querySupportedValues -- "
542 "input and output lists "
543 "have different sizes.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800544 status = C2_CORRUPTED;
545 return;
546 }
547 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800548 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800549 LOG(ERROR) << "querySupportedValues -- "
550 "invalid returned value.";
551 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800552 return;
553 }
554 }
555 });
556 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800557 LOG(ERROR) << "querySupportedValues -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800558 return C2_TRANSACTION_FAILED;
559 }
560 return status;
561}
562
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800563// Codec2ConfigurableClient::AidlImpl
564
565struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase {
566 typedef c2_aidl::IConfigurable Base;
567
568 // base cannot be null.
569 explicit AidlImpl(const std::shared_ptr<Base>& base);
570
571 const C2String& getName() const override {
572 return mName;
573 }
574
575 c2_status_t query(
576 const std::vector<C2Param*>& stackParams,
577 const std::vector<C2Param::Index> &heapParamIndices,
578 c2_blocking_t mayBlock,
579 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
580
581 c2_status_t config(
582 const std::vector<C2Param*> &params,
583 c2_blocking_t mayBlock,
584 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
585
586 c2_status_t querySupportedParams(
587 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
588 ) const override;
589
590 c2_status_t querySupportedValues(
591 std::vector<C2FieldSupportedValuesQuery>& fields,
592 c2_blocking_t mayBlock) const override;
593
594private:
595 std::shared_ptr<Base> mBase;
596 const C2String mName;
597};
598
599Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base)
600 : mBase{base},
601 mName{[base]() -> C2String {
602 std::string outName;
603 ndk::ScopedAStatus status = base->getName(&outName);
604 return status.isOk() ? outName : "";
605 }()} {
606}
607
608c2_status_t Codec2ConfigurableClient::AidlImpl::query(
609 const std::vector<C2Param*> &stackParams,
610 const std::vector<C2Param::Index> &heapParamIndices,
611 c2_blocking_t mayBlock,
612 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800613 std::vector<int> indices(
614 stackParams.size() + heapParamIndices.size());
615 size_t numIndices = 0;
616 for (C2Param* const& stackParam : stackParams) {
617 if (!stackParam) {
618 LOG(WARNING) << "query -- null stack param encountered.";
619 continue;
620 }
621 indices[numIndices++] = int(stackParam->index());
622 }
623 size_t numStackIndices = numIndices;
624 for (const C2Param::Index& index : heapParamIndices) {
625 indices[numIndices++] = int(static_cast<uint32_t>(index));
626 }
627 indices.resize(numIndices);
628 if (heapParams) {
629 heapParams->reserve(heapParams->size() + numIndices);
630 }
631 c2_aidl::Params result;
632 ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800633 c2_status_t status = GetC2Status(transStatus, "query");
634 if (status != C2_OK) {
635 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800636 }
637
Wonsik Kim1caded02022-12-09 13:03:11 -0800638 std::vector<C2Param*> paramPointers;
639 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, result)) {
640 LOG(ERROR) << "query -- error while parsing params.";
641 return C2_CORRUPTED;
642 }
643 size_t i = 0;
644 for (auto it = paramPointers.begin();
645 it != paramPointers.end(); ) {
646 C2Param* paramPointer = *it;
647 if (numStackIndices > 0) {
648 --numStackIndices;
649 if (!paramPointer) {
650 LOG(DEBUG) << "query -- null stack param.";
651 ++it;
652 continue;
653 }
654 for (; i < stackParams.size() && !stackParams[i]; ) {
655 ++i;
656 }
657 if (i >= stackParams.size()) {
658 LOG(ERROR) << "query -- unexpected error.";
659 status = C2_CORRUPTED;
660 break;
661 }
662 if (stackParams[i]->index() != paramPointer->index()) {
663 LOG(DEBUG) << "query -- param skipped: "
664 "index = "
665 << stackParams[i]->index() << ".";
666 stackParams[i++]->invalidate();
667 // this means that the param could not be queried.
668 // signalling C2_BAD_INDEX to the client.
669 status = C2_BAD_INDEX;
670 continue;
671 }
672 if (!stackParams[i++]->updateFrom(*paramPointer)) {
673 LOG(WARNING) << "query -- param update failed: "
674 "index = "
675 << paramPointer->index() << ".";
676 }
677 } else {
678 if (!paramPointer) {
679 LOG(DEBUG) << "query -- null heap param.";
680 ++it;
681 continue;
682 }
683 if (!heapParams) {
684 LOG(WARNING) << "query -- "
685 "unexpected extra stack param.";
686 } else {
687 heapParams->emplace_back(C2Param::Copy(*paramPointer));
688 }
689 }
690 ++it;
691 }
692 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800693}
694
695c2_status_t Codec2ConfigurableClient::AidlImpl::config(
696 const std::vector<C2Param*> &params,
697 c2_blocking_t mayBlock,
698 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kim1caded02022-12-09 13:03:11 -0800699 c2_aidl::Params aidlParams;
700 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
701 LOG(ERROR) << "config -- bad input.";
702 return C2_TRANSACTION_FAILED;
703 }
704 c2_aidl::IConfigurable::ConfigResult result;
705 ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800706 c2_status_t status = GetC2Status(transStatus, "config");
707 if (status != C2_OK) {
708 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800709 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800710 size_t i = failures->size();
711 failures->resize(i + result.failures.size());
712 for (const c2_aidl::SettingResult& sf : result.failures) {
713 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
714 LOG(ERROR) << "config -- invalid SettingResult returned.";
715 return C2_CORRUPTED;
716 }
717 }
718 if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) {
719 LOG(ERROR) << "config -- "
720 << "failed to parse returned params.";
721 status = C2_CORRUPTED;
722 }
723 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800724}
725
726c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams(
727 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800728 // TODO: Cache and query properly!
729 std::vector<c2_aidl::ParamDescriptor> result;
730 ndk::ScopedAStatus transStatus = mBase->querySupportedParams(
731 std::numeric_limits<uint32_t>::min(),
732 std::numeric_limits<uint32_t>::max(),
733 &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800734 c2_status_t status = GetC2Status(transStatus, "querySupportedParams");
735 if (status != C2_OK) {
736 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800737 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800738 size_t i = params->size();
739 params->resize(i + result.size());
740 for (const c2_aidl::ParamDescriptor& sp : result) {
741 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
742 LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor.";
743 return C2_CORRUPTED;
744 }
745 }
746 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800747}
748
749c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues(
750 std::vector<C2FieldSupportedValuesQuery>& fields,
751 c2_blocking_t mayBlock) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800752 std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size());
753 for (size_t i = 0; i < fields.size(); ++i) {
754 if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) {
755 LOG(ERROR) << "querySupportedValues -- bad input";
756 return C2_TRANSACTION_FAILED;
757 }
758 }
759
760 std::vector<c2_aidl::FieldSupportedValuesQueryResult> result;
761 ndk::ScopedAStatus transStatus = mBase->querySupportedValues(
762 inFields, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800763 c2_status_t status = GetC2Status(transStatus, "querySupportedValues");
764 if (status != C2_OK) {
765 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800766 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800767 if (result.size() != fields.size()) {
768 LOG(ERROR) << "querySupportedValues -- "
769 "input and output lists "
770 "have different sizes.";
771 return C2_CORRUPTED;
772 }
773 for (size_t i = 0; i < fields.size(); ++i) {
774 if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) {
775 LOG(ERROR) << "querySupportedValues -- "
776 "invalid returned value.";
777 return C2_CORRUPTED;
778 }
779 }
780 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800781}
782
783// Codec2ConfigurableClient
784
785Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase)
786 : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) {
787}
788
789Codec2ConfigurableClient::Codec2ConfigurableClient(
790 const std::shared_ptr<AidlBase> &aidlBase)
791 : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) {
792}
793
794const C2String& Codec2ConfigurableClient::getName() const {
795 return mImpl->getName();
796}
797
798c2_status_t Codec2ConfigurableClient::query(
799 const std::vector<C2Param*>& stackParams,
800 const std::vector<C2Param::Index> &heapParamIndices,
801 c2_blocking_t mayBlock,
802 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
803 return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
804}
805
806c2_status_t Codec2ConfigurableClient::config(
807 const std::vector<C2Param*> &params,
808 c2_blocking_t mayBlock,
809 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
810 return mImpl->config(params, mayBlock, failures);
811}
812
813c2_status_t Codec2ConfigurableClient::querySupportedParams(
814 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
815 return mImpl->querySupportedParams(params);
816}
817
818c2_status_t Codec2ConfigurableClient::querySupportedValues(
819 std::vector<C2FieldSupportedValuesQuery>& fields,
820 c2_blocking_t mayBlock) const {
821 return mImpl->querySupportedValues(fields, mayBlock);
822}
823
824
Pawin Vongmasa36653902018-11-15 00:10:25 -0800825// Codec2Client::Component::HidlListener
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800826struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800827 std::weak_ptr<Component> component;
828 std::weak_ptr<Listener> base;
829
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800830 virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800831 std::list<std::unique_ptr<C2Work>> workItems;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800832 if (!c2_hidl::utils::objcpy(&workItems, workBundle)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800833 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800834 return Void();
835 }
836 // release input buffers potentially held by the component from queue
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800837 std::shared_ptr<Codec2Client::Component> strongComponent =
838 component.lock();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800839 if (strongComponent) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800840 strongComponent->handleOnWorkDone(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800841 }
842 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800843 listener->onWorkDone(component, workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800844 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800845 LOG(DEBUG) << "onWorkDone -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800846 }
847 return Void();
848 }
849
850 virtual Return<void> onTripped(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800851 const hidl_vec<c2_hidl::SettingResult>& settingResults) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800852 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
853 settingResults.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800854 for (size_t i = 0; i < settingResults.size(); ++i) {
855 std::unique_ptr<C2SettingResult> c2SettingResult;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800856 if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800857 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800858 return Void();
859 }
860 c2SettingResults[i] = std::move(c2SettingResult);
861 }
862 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
863 listener->onTripped(component, c2SettingResults);
864 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800865 LOG(DEBUG) << "onTripped -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800866 }
867 return Void();
868 }
869
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800870 virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800871 LOG(DEBUG) << "onError --"
872 << " status = " << s
873 << ", errorCode = " << errorCode
874 << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800875 if (std::shared_ptr<Listener> listener = base.lock()) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800876 listener->onError(component, s == c2_hidl::Status::OK ?
Pawin Vongmasa36653902018-11-15 00:10:25 -0800877 errorCode : static_cast<c2_status_t>(s));
878 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800879 LOG(DEBUG) << "onError -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800880 }
881 return Void();
882 }
883
884 virtual Return<void> onFramesRendered(
885 const hidl_vec<RenderedFrame>& renderedFrames) override {
886 std::shared_ptr<Listener> listener = base.lock();
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800887 if (!listener) {
888 LOG(DEBUG) << "onFramesRendered -- listener died.";
889 return Void();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800890 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800891 for (const RenderedFrame& renderedFrame : renderedFrames) {
892 listener->onFrameRendered(
893 renderedFrame.bufferQueueId,
894 renderedFrame.slotId,
895 renderedFrame.timestampNs);
896 }
897 return Void();
898 }
899
900 virtual Return<void> onInputBuffersReleased(
901 const hidl_vec<InputBuffer>& inputBuffers) override {
902 std::shared_ptr<Listener> listener = base.lock();
903 if (!listener) {
904 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
905 return Void();
906 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800907 for (const InputBuffer& inputBuffer : inputBuffers) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800908 LOG(VERBOSE) << "onInputBuffersReleased --"
909 " received death notification of"
910 " input buffer:"
911 " frameIndex = " << inputBuffer.frameIndex
912 << ", bufferIndex = " << inputBuffer.arrayIndex
913 << ".";
Wonsik Kimab34ed62019-01-31 15:28:46 -0800914 listener->onInputBufferDone(
915 inputBuffer.frameIndex, inputBuffer.arrayIndex);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800916 }
917 return Void();
918 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800919
Pawin Vongmasa36653902018-11-15 00:10:25 -0800920};
921
Wonsik Kime8e98152022-12-16 16:04:17 -0800922// Codec2Client::Component::AidlListener
923struct Codec2Client::Component::AidlListener : public c2_aidl::BnComponentListener {
924 std::weak_ptr<Component> component;
925 std::weak_ptr<Listener> base;
926
927 virtual ::ndk::ScopedAStatus onWorkDone(const c2_aidl::WorkBundle& workBundle) override {
928 std::list<std::unique_ptr<C2Work>> workItems;
929 if (!c2_aidl::utils::FromAidl(&workItems, workBundle)) {
930 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
931 return ::ndk::ScopedAStatus::ok();
932 }
933 // release input buffers potentially held by the component from queue
934 std::shared_ptr<Codec2Client::Component> strongComponent =
935 component.lock();
936 if (strongComponent) {
937 strongComponent->handleOnWorkDone(workItems);
938 }
939 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
940 listener->onWorkDone(component, workItems);
941 } else {
942 LOG(DEBUG) << "onWorkDone -- listener died.";
943 }
944 return ::ndk::ScopedAStatus::ok();
945 }
946
947 virtual ::ndk::ScopedAStatus onTripped(
948 const std::vector<c2_aidl::SettingResult>& settingResults) override {
949 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
950 settingResults.size());
951 for (size_t i = 0; i < settingResults.size(); ++i) {
952 std::unique_ptr<C2SettingResult> c2SettingResult;
953 if (!c2_aidl::utils::FromAidl(&c2SettingResult, settingResults[i])) {
954 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
955 return ::ndk::ScopedAStatus::ok();
956 }
957 c2SettingResults[i] = std::move(c2SettingResult);
958 }
959 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
960 listener->onTripped(component, c2SettingResults);
961 } else {
962 LOG(DEBUG) << "onTripped -- listener died.";
963 }
964 return ::ndk::ScopedAStatus::ok();
965 }
966
967 virtual ::ndk::ScopedAStatus onError(const c2_aidl::Status &s, int32_t errorCode) override {
968 LOG(DEBUG) << "onError --"
969 << " status = " << s.status
970 << ", errorCode = " << errorCode
971 << ".";
972 if (std::shared_ptr<Listener> listener = base.lock()) {
973 listener->onError(component, s.status == c2_aidl::Status::OK ?
974 errorCode : static_cast<c2_status_t>(s.status));
975 } else {
976 LOG(DEBUG) << "onError -- listener died.";
977 }
978 return ::ndk::ScopedAStatus::ok();
979 }
980
981 virtual ::ndk::ScopedAStatus onFramesRendered(
982 const std::vector<RenderedFrame>& renderedFrames) override {
983 std::shared_ptr<Listener> listener = base.lock();
984 if (!listener) {
985 LOG(DEBUG) << "onFramesRendered -- listener died.";
986 return ::ndk::ScopedAStatus::ok();
987 }
988 for (const RenderedFrame& renderedFrame : renderedFrames) {
989 listener->onFrameRendered(
990 renderedFrame.bufferQueueId,
991 renderedFrame.slotId,
992 renderedFrame.timestampNs);
993 }
994 return ::ndk::ScopedAStatus::ok();
995 }
996
997 virtual ::ndk::ScopedAStatus onInputBuffersReleased(
998 const std::vector<InputBuffer>& inputBuffers) override {
999 std::shared_ptr<Listener> listener = base.lock();
1000 if (!listener) {
1001 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
1002 return ::ndk::ScopedAStatus::ok();
1003 }
1004 for (const InputBuffer& inputBuffer : inputBuffers) {
1005 LOG(VERBOSE) << "onInputBuffersReleased --"
1006 " received death notification of"
1007 " input buffer:"
1008 " frameIndex = " << inputBuffer.frameIndex
1009 << ", bufferIndex = " << inputBuffer.arrayIndex
1010 << ".";
1011 listener->onInputBufferDone(
1012 inputBuffer.frameIndex, inputBuffer.arrayIndex);
1013 }
1014 return ::ndk::ScopedAStatus::ok();
1015 }
1016
1017};
1018
1019// Codec2Client::Component::HidlBufferPoolSender
1020struct Codec2Client::Component::HidlBufferPoolSender :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001021 hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
Wonsik Kime8e98152022-12-16 16:04:17 -08001022 HidlBufferPoolSender()
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001023 : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
1024 }
1025};
1026
Wonsik Kime8e98152022-12-16 16:04:17 -08001027// Codec2Client::Component::AidlBufferPoolSender
1028struct Codec2Client::Component::AidlBufferPoolSender :
1029 c2_aidl::utils::DefaultBufferPoolSender {
1030 AidlBufferPoolSender()
1031 : c2_aidl::utils::DefaultBufferPoolSender() {
1032 }
1033};
1034
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001035// Codec2Client::Component::OutputBufferQueue
1036struct Codec2Client::Component::OutputBufferQueue :
Sungtak Leea714f112021-03-16 05:40:03 -07001037 hardware::media::c2::OutputBufferQueue {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001038 OutputBufferQueue()
Sungtak Leea714f112021-03-16 05:40:03 -07001039 : hardware::media::c2::OutputBufferQueue() {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001040 }
1041};
1042
Pawin Vongmasa36653902018-11-15 00:10:25 -08001043// Codec2Client
Wonsik Kime8e98152022-12-16 16:04:17 -08001044Codec2Client::Codec2Client(sp<HidlBase> const& base,
Sungtak Leef4b39512023-05-10 07:17:22 +00001045 sp<c2_hidl::IConfigurable> const& configurable,
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001046 size_t serviceIndex)
Sungtak Leef4b39512023-05-10 07:17:22 +00001047 : Configurable{configurable},
Wonsik Kime8e98152022-12-16 16:04:17 -08001048 mHidlBase1_0{base},
1049 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1050 mHidlBase1_2{HidlBase1_2::castFrom(base)},
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001051 mServiceIndex{serviceIndex} {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001052 Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager();
Pawin Vongmasa36653902018-11-15 00:10:25 -08001053 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001054 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001055 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08001056 mHidlHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001057 }
1058}
1059
Wonsik Kime8e98152022-12-16 16:04:17 -08001060Codec2Client::Codec2Client(std::shared_ptr<AidlBase> const& base,
1061 std::shared_ptr<c2_aidl::IConfigurable> const& configurable,
1062 size_t serviceIndex)
1063 : Configurable{configurable},
1064 mAidlBase{base},
1065 mServiceIndex{serviceIndex} {
1066 ::ndk::ScopedAStatus transStatus = base->getPoolClientManager(&mAidlHostPoolManager);
1067 if (!transStatus.isOk()) {
1068 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
1069 mAidlHostPoolManager.reset();
1070 }
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001071}
1072
Wonsik Kime8e98152022-12-16 16:04:17 -08001073sp<Codec2Client::HidlBase> const& Codec2Client::getHidlBase() const {
1074 return mHidlBase1_0;
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001075}
1076
Wonsik Kime8e98152022-12-16 16:04:17 -08001077sp<Codec2Client::HidlBase1_0> const& Codec2Client::getHidlBase1_0() const {
1078 return mHidlBase1_0;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001079}
1080
Wonsik Kime8e98152022-12-16 16:04:17 -08001081sp<Codec2Client::HidlBase1_1> const& Codec2Client::getHidlBase1_1() const {
1082 return mHidlBase1_1;
1083}
1084
1085sp<Codec2Client::HidlBase1_2> const& Codec2Client::getHidlBase1_2() const {
1086 return mHidlBase1_2;
1087}
1088
1089::ndk::SpAIBinder Codec2Client::getAidlBase() const {
1090 return mAidlBase ? mAidlBase->asBinder() : nullptr;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001091}
1092
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001093std::string const& Codec2Client::getServiceName() const {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001094 return GetServiceNames()[mServiceIndex];
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001095}
1096
Pawin Vongmasa36653902018-11-15 00:10:25 -08001097c2_status_t Codec2Client::createComponent(
1098 const C2String& name,
1099 const std::shared_ptr<Codec2Client::Listener>& listener,
1100 std::shared_ptr<Codec2Client::Component>* const component) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001101 if (mAidlBase) {
1102 std::shared_ptr<Component::AidlListener> aidlListener =
1103 Component::AidlListener::make<Component::AidlListener>();
1104 aidlListener->base = listener;
1105 std::shared_ptr<c2_aidl::IComponent> aidlComponent;
1106 ::ndk::ScopedAStatus transStatus = mAidlBase->createComponent(
1107 name,
1108 aidlListener,
1109 bufferpool2_aidl::implementation::ClientManager::getInstance(),
1110 &aidlComponent);
1111 c2_status_t status = GetC2Status(transStatus, "createComponent");
1112 if (status != C2_OK) {
1113 return status;
1114 } else if (!aidlComponent) {
1115 LOG(ERROR) << "createComponent(" << name.c_str()
1116 << ") -- null component.";
1117 return C2_CORRUPTED;
1118 }
1119 *component = std::make_shared<Codec2Client::Component>(aidlComponent);
1120 status = (*component)->setDeathListener((*component), listener);
1121 if (status != C2_OK) {
1122 LOG(ERROR) << "createComponent(" << name.c_str()
1123 << ") -- failed to set up death listener: "
1124 << status << ".";
1125 }
1126 (*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager);
1127 return status;
1128 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001129
Pawin Vongmasa36653902018-11-15 00:10:25 -08001130 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001131 sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001132 hidlListener->base = listener;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001133 Return<void> transStatus;
Wonsik Kime8e98152022-12-16 16:04:17 -08001134 if (mHidlBase1_2) {
1135 transStatus = mHidlBase1_2->createComponent_1_2(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001136 name,
1137 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001138 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasa36653902018-11-15 00:10:25 -08001139 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001140 c2_hidl::Status s,
1141 const sp<c2_hidl::IComponent>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001142 status = static_cast<c2_status_t>(s);
1143 if (status != C2_OK) {
1144 return;
1145 }
1146 *component = std::make_shared<Codec2Client::Component>(c);
1147 hidlListener->component = *component;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001148 });
1149 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001150 else if (mHidlBase1_1) {
1151 transStatus = mHidlBase1_1->createComponent_1_1(
Sungtak Lee8577dab2021-03-12 02:25:50 -08001152 name,
1153 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001154 bufferpool_hidl::implementation::ClientManager::getInstance(),
Sungtak Lee8577dab2021-03-12 02:25:50 -08001155 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001156 c2_hidl::Status s,
1157 const sp<c2_hidl_base::V1_1::IComponent>& c) {
Sungtak Lee8577dab2021-03-12 02:25:50 -08001158 status = static_cast<c2_status_t>(s);
1159 if (status != C2_OK) {
1160 return;
1161 }
1162 *component = std::make_shared<Codec2Client::Component>(c);
1163 hidlListener->component = *component;
1164 });
Wonsik Kime8e98152022-12-16 16:04:17 -08001165 } else if (mHidlBase1_0) { // ver1_0
1166 transStatus = mHidlBase1_0->createComponent(
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001167 name,
1168 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001169 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001170 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001171 c2_hidl::Status s,
1172 const sp<c2_hidl_base::V1_0::IComponent>& c) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001173 status = static_cast<c2_status_t>(s);
1174 if (status != C2_OK) {
1175 return;
1176 }
1177 *component = std::make_shared<Codec2Client::Component>(c);
1178 hidlListener->component = *component;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001179 });
Sungtak Lee8577dab2021-03-12 02:25:50 -08001180 } else {
1181 status = C2_CORRUPTED;
1182 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001183 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001184 LOG(ERROR) << "createComponent(" << name.c_str()
1185 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001186 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001187 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001188 if (status == C2_NOT_FOUND) {
1189 LOG(VERBOSE) << "createComponent(" << name.c_str()
1190 << ") -- component not found.";
1191 } else {
1192 LOG(ERROR) << "createComponent(" << name.c_str()
1193 << ") -- call failed: " << status << ".";
1194 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001195 return status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001196 } else if (!*component) {
1197 LOG(ERROR) << "createComponent(" << name.c_str()
1198 << ") -- null component.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001199 return C2_CORRUPTED;
1200 }
1201
1202 status = (*component)->setDeathListener(*component, listener);
1203 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001204 LOG(ERROR) << "createComponent(" << name.c_str()
1205 << ") -- failed to set up death listener: "
1206 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001207 }
1208
Wonsik Kime8e98152022-12-16 16:04:17 -08001209 (*component)->mHidlBufferPoolSender->setReceiver(mHidlHostPoolManager);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001210 return status;
1211}
1212
1213c2_status_t Codec2Client::createInterface(
1214 const C2String& name,
1215 std::shared_ptr<Codec2Client::Interface>* const interface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001216 if (mAidlBase) {
1217 std::shared_ptr<c2_aidl::IComponentInterface> aidlInterface;
1218 ::ndk::ScopedAStatus transStatus = mAidlBase->createInterface(
1219 name,
1220 &aidlInterface);
1221 c2_status_t status = GetC2Status(transStatus, "createInterface");
1222 if (status != C2_OK) {
1223 return status;
1224 } else if (!aidlInterface) {
1225 LOG(ERROR) << "createInterface(" << name.c_str()
1226 << ") -- null interface.";
1227 return C2_CORRUPTED;
1228 }
1229 interface->reset(new Codec2Client::Interface(aidlInterface));
1230 return C2_OK;
1231 }
1232
Pawin Vongmasa36653902018-11-15 00:10:25 -08001233 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001234 Return<void> transStatus = mHidlBase1_0->createInterface(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001235 name,
1236 [&status, interface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001237 c2_hidl::Status s,
1238 const sp<c2_hidl::IComponentInterface>& i) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001239 status = static_cast<c2_status_t>(s);
1240 if (status != C2_OK) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001241 return;
1242 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001243 *interface = std::make_shared<Interface>(i);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001244 });
1245 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001246 LOG(ERROR) << "createInterface(" << name.c_str()
1247 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001248 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001249 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001250 if (status == C2_NOT_FOUND) {
1251 LOG(VERBOSE) << "createInterface(" << name.c_str()
1252 << ") -- component not found.";
1253 } else {
1254 LOG(ERROR) << "createInterface(" << name.c_str()
1255 << ") -- call failed: " << status << ".";
1256 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001257 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001258 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001259
Pawin Vongmasa36653902018-11-15 00:10:25 -08001260 return status;
1261}
1262
1263c2_status_t Codec2Client::createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001264 std::shared_ptr<InputSurface>* const inputSurface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001265 if (mAidlBase) {
1266 // FIXME
1267 return C2_OMITTED;
1268 }
1269
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001270 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001271 Return<void> transStatus = mHidlBase1_0->createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001272 [&status, inputSurface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001273 c2_hidl::Status s,
1274 const sp<c2_hidl::IInputSurface>& i) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001275 status = static_cast<c2_status_t>(s);
1276 if (status != C2_OK) {
1277 return;
1278 }
1279 *inputSurface = std::make_shared<InputSurface>(i);
1280 });
1281 if (!transStatus.isOk()) {
1282 LOG(ERROR) << "createInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001283 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001284 } else if (status != C2_OK) {
1285 LOG(DEBUG) << "createInputSurface -- call failed: "
1286 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001287 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001288 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001289}
1290
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001291std::vector<C2Component::Traits> const& Codec2Client::listComponents() const {
1292 return Cache::List()[mServiceIndex].getTraits();
1293}
1294
1295std::vector<C2Component::Traits> Codec2Client::_listComponents(
1296 bool* success) const {
1297 std::vector<C2Component::Traits> traits;
1298 std::string const& serviceName = getServiceName();
Wonsik Kime8e98152022-12-16 16:04:17 -08001299
1300 if (mAidlBase) {
1301 std::vector<c2_aidl::IComponentStore::ComponentTraits> aidlTraits;
1302 ::ndk::ScopedAStatus transStatus = mAidlBase->listComponents(&aidlTraits);
1303 if (!transStatus.isOk()) {
1304 LOG(ERROR) << "_listComponents -- transaction failed.";
1305 *success = false;
1306 } else {
1307 traits.resize(aidlTraits.size());
1308 *success = true;
1309 for (size_t i = 0; i < aidlTraits.size(); ++i) {
1310 if (!c2_aidl::utils::FromAidl(&traits[i], aidlTraits[i])) {
1311 LOG(ERROR) << "_listComponents -- corrupted output.";
1312 *success = false;
1313 traits.clear();
1314 break;
1315 }
1316 traits[i].owner = serviceName;
1317 }
1318 }
1319 return traits;
1320 }
1321 Return<void> transStatus = mHidlBase1_0->listComponents(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001322 [&traits, &serviceName](c2_hidl::Status s,
1323 const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) {
1324 if (s != c2_hidl::Status::OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001325 LOG(DEBUG) << "_listComponents -- call failed: "
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001326 << static_cast<c2_status_t>(s) << ".";
1327 return;
1328 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001329 traits.resize(t.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001330 for (size_t i = 0; i < t.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001331 if (!c2_hidl::utils::objcpy(&traits[i], t[i])) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001332 LOG(ERROR) << "_listComponents -- corrupted output.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001333 return;
1334 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001335 traits[i].owner = serviceName;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001336 }
1337 });
1338 if (!transStatus.isOk()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001339 LOG(ERROR) << "_listComponents -- transaction failed.";
1340 *success = false;
1341 } else {
1342 *success = true;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001343 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001344 return traits;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001345}
1346
1347c2_status_t Codec2Client::copyBuffer(
1348 const std::shared_ptr<C2Buffer>& src,
1349 const std::shared_ptr<C2Buffer>& dst) {
1350 // TODO: Implement?
1351 (void)src;
1352 (void)dst;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001353 LOG(ERROR) << "copyBuffer not implemented";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001354 return C2_OMITTED;
1355}
1356
Wonsik Kime8e98152022-12-16 16:04:17 -08001357std::shared_ptr<C2ParamReflector> Codec2Client::getParamReflector() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001358 // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it
1359 // should reflect the HAL API.
Wonsik Kime8e98152022-12-16 16:04:17 -08001360 struct HidlSimpleParamReflector : public C2ParamReflector {
1361 std::unique_ptr<C2StructDescriptor> describe(
1362 C2Param::CoreIndex coreIndex) const override {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001363 hidl_vec<c2_hidl::ParamIndex> indices(1);
1364 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001365 std::unique_ptr<C2StructDescriptor> descriptor;
1366 Return<void> transStatus = mBase->getStructDescriptors(
1367 indices,
1368 [&descriptor](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001369 c2_hidl::Status s,
1370 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001371 c2_status_t status = static_cast<c2_status_t>(s);
1372 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001373 LOG(DEBUG) << "SimpleParamReflector -- "
1374 "getStructDescriptors() failed: "
1375 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001376 descriptor.reset();
1377 return;
1378 }
1379 if (sd.size() != 1) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001380 LOG(DEBUG) << "SimpleParamReflector -- "
1381 "getStructDescriptors() "
1382 "returned vector of size "
1383 << sd.size() << ". "
1384 "It should be 1.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001385 descriptor.reset();
1386 return;
1387 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001388 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001389 LOG(DEBUG) << "SimpleParamReflector -- "
1390 "getStructDescriptors() returned "
1391 "corrupted data.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001392 descriptor.reset();
1393 return;
1394 }
1395 });
Wonsik Kim492fecd2020-11-19 11:14:11 -08001396 if (!transStatus.isOk()) {
1397 LOG(DEBUG) << "SimpleParamReflector -- transaction failed: "
1398 << transStatus.description();
1399 descriptor.reset();
1400 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001401 return descriptor;
1402 }
1403
Wonsik Kime8e98152022-12-16 16:04:17 -08001404 HidlSimpleParamReflector(sp<HidlBase> base)
Pawin Vongmasa36653902018-11-15 00:10:25 -08001405 : mBase(base) { }
1406
Wonsik Kime8e98152022-12-16 16:04:17 -08001407 sp<HidlBase> mBase;
1408 };
1409 struct AidlSimpleParamReflector : public C2ParamReflector {
1410 std::unique_ptr<C2StructDescriptor> describe(
1411 C2Param::CoreIndex coreIndex) const override {
1412 std::vector<c2_aidl::StructDescriptor> aidlDesc;
1413 std::unique_ptr<C2StructDescriptor> descriptor;
1414 ::ndk::ScopedAStatus transStatus = mBase->getStructDescriptors(
1415 {int32_t(coreIndex.coreIndex())},
1416 &aidlDesc);
1417 c2_status_t status = GetC2Status(transStatus, "describe");
1418 if (status != C2_OK) {
1419 descriptor.reset();
1420 } else if (!c2_aidl::utils::FromAidl(&descriptor, aidlDesc[0])) {
1421 LOG(ERROR) << "describe -- conversion failed.";
1422 descriptor.reset();
1423 }
1424 return descriptor;
1425 }
1426
1427 AidlSimpleParamReflector(const std::shared_ptr<AidlBase> &base)
1428 : mBase(base) { }
1429
1430 std::shared_ptr<AidlBase> mBase;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001431 };
1432
Wonsik Kime8e98152022-12-16 16:04:17 -08001433 if (mAidlBase) {
1434 return std::make_shared<AidlSimpleParamReflector>(mAidlBase);
1435 }
1436 return std::make_shared<HidlSimpleParamReflector>(mHidlBase1_0);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001437};
1438
Wonsik Kime8e98152022-12-16 16:04:17 -08001439std::vector<std::string> Codec2Client::CacheServiceNames() {
1440 std::vector<std::string> names;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001441
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001442 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim65febd22023-09-20 16:26:02 -07001443 if (__builtin_available(android __ANDROID_API_S__, *)) {
1444 // Get AIDL service names
1445 AServiceManager_forEachDeclaredInstance(
1446 AidlBase::descriptor, &names, [](const char *name, void *context) {
1447 std::vector<std::string> *names = (std::vector<std::string> *)context;
1448 names->emplace_back(name);
1449 });
1450 } else {
1451 LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35";
1452 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001453 } else {
1454 // Get HIDL service names
1455 using ::android::hardware::media::c2::V1_0::IComponentStore;
1456 using ::android::hidl::manager::V1_2::IServiceManager;
1457 while (true) {
1458 sp<IServiceManager> serviceManager = IServiceManager::getService();
1459 CHECK(serviceManager) << "Hardware service manager is not running.";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001460
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001461 Return<void> transResult;
1462 transResult = serviceManager->listManifestByInterface(
1463 IComponentStore::descriptor,
1464 [&names](
1465 hidl_vec<hidl_string> const& instanceNames) {
1466 names.insert(names.end(), instanceNames.begin(), instanceNames.end());
1467 });
1468 if (transResult.isOk()) {
1469 break;
1470 }
1471 LOG(ERROR) << "Could not retrieve the list of service instances of "
1472 << IComponentStore::descriptor
1473 << ". Retrying...";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001474 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001475 }
1476 // Sort service names in each category.
1477 std::stable_sort(
1478 names.begin(), names.end(),
1479 [](const std::string &a, const std::string &b) {
1480 // First compare by prefix: default -> vendor -> {everything else}
1481 constexpr int DEFAULT = 1;
1482 constexpr int VENDOR = 2;
1483 constexpr int OTHER = 3;
1484 int aPrefix = ((a.compare(0, 7, "default") == 0) ? DEFAULT :
1485 (a.compare(0, 6, "vendor") == 0) ? VENDOR :
1486 OTHER);
1487 int bPrefix = ((b.compare(0, 7, "default") == 0) ? DEFAULT :
1488 (b.compare(0, 6, "vendor") == 0) ? VENDOR :
1489 OTHER);
1490 if (aPrefix != bPrefix) {
1491 return aPrefix < bPrefix;
1492 }
1493 // If the prefix is the same, compare alphabetically
1494 return a < b;
1495 });
1496
1497 // Summarize to logcat.
1498 if (names.empty()) {
1499 LOG(INFO) << "No Codec2 services declared in the manifest.";
1500 } else {
1501 std::stringstream stringOutput;
1502 stringOutput << "Available Codec2 services:";
1503 for (std::string const& name : names) {
1504 stringOutput << " \"" << name << "\"";
1505 }
1506 LOG(INFO) << stringOutput.str();
1507 }
1508
1509 return names;
1510}
1511
1512std::vector<std::string> const& Codec2Client::GetServiceNames() {
1513 static std::vector<std::string> sServiceNames = CacheServiceNames();
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001514 return sServiceNames;
1515}
1516
Pawin Vongmasa36653902018-11-15 00:10:25 -08001517std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001518 const char* name,
1519 bool setAsPreferredCodec2ComponentStore) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001520 size_t index = getServiceIndex(name);
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001521 if (index == GetServiceNames().size()) {
1522 if (setAsPreferredCodec2ComponentStore) {
1523 LOG(WARNING) << "CreateFromService(" << name
1524 << ") -- preferred C2ComponentStore not set.";
1525 }
1526 return nullptr;
1527 }
1528 std::shared_ptr<Codec2Client> client = _CreateFromIndex(index);
1529 if (setAsPreferredCodec2ComponentStore) {
1530 SetPreferredCodec2ComponentStore(
1531 std::make_shared<Client2Store>(client));
1532 LOG(INFO) << "CreateFromService(" << name
1533 << ") -- service set as preferred C2ComponentStore.";
1534 }
1535 return client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001536}
1537
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001538std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
1539 CreateFromAllServices() {
1540 std::vector<std::shared_ptr<Codec2Client>> clients(
1541 GetServiceNames().size());
1542 for (size_t i = GetServiceNames().size(); i > 0; ) {
1543 --i;
1544 clients[i] = _CreateFromIndex(i);
1545 }
1546 return clients;
1547}
1548
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001549std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001550 std::string const& name = GetServiceNames()[index];
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001551 LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\"";
Wonsik Kime8e98152022-12-16 16:04:17 -08001552
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001553 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim65febd22023-09-20 16:26:02 -07001554 if (__builtin_available(android __ANDROID_API_S__, *)) {
1555 std::string instanceName =
1556 ::android::base::StringPrintf("%s/%s", AidlBase::descriptor, name.c_str());
1557 if (AServiceManager_isDeclared(instanceName.c_str())) {
1558 std::shared_ptr<AidlBase> baseStore = AidlBase::fromBinder(
1559 ::ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));
1560 CHECK(baseStore) << "Codec2 AIDL service \"" << name << "\""
1561 " inaccessible for unknown reasons.";
1562 LOG(VERBOSE) << "Client to Codec2 AIDL service \"" << name << "\" created";
1563 std::shared_ptr<c2_aidl::IConfigurable> configurable;
1564 ::ndk::ScopedAStatus transStatus = baseStore->getConfigurable(&configurable);
1565 CHECK(transStatus.isOk()) << "Codec2 AIDL service \"" << name << "\""
1566 "does not have IConfigurable.";
1567 return std::make_shared<Codec2Client>(baseStore, configurable, index);
1568 } else {
1569 LOG(ERROR) << "Codec2 AIDL service \"" << name << "\" is not declared";
1570 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001571 } else {
Wonsik Kim65febd22023-09-20 16:26:02 -07001572 LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35";
Wonsik Kime8e98152022-12-16 16:04:17 -08001573 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001574 } else {
1575 std::string instanceName = "android.hardware.media.c2/" + name;
1576 sp<HidlBase> baseStore = HidlBase::getService(name);
1577 CHECK(baseStore) << "Codec2 service \"" << name << "\""
1578 " inaccessible for unknown reasons.";
1579 LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created";
1580 Return<sp<c2_hidl::IConfigurable>> transResult = baseStore->getConfigurable();
1581 CHECK(transResult.isOk()) << "Codec2 service \"" << name << "\""
1582 "does not have IConfigurable.";
1583 sp<c2_hidl::IConfigurable> configurable =
1584 static_cast<sp<c2_hidl::IConfigurable>>(transResult);
1585 return std::make_shared<Codec2Client>(baseStore, configurable, index);
Wonsik Kime8e98152022-12-16 16:04:17 -08001586 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001587 return nullptr;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001588}
1589
1590c2_status_t Codec2Client::ForAllServices(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001591 const std::string &key,
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001592 size_t numberOfAttempts,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001593 std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
1594 predicate) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001595 c2_status_t status = C2_NO_INIT; // no IComponentStores present
1596
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001597 // Cache the mapping key -> index of Codec2Client in Cache::List().
Pawin Vongmasa36653902018-11-15 00:10:25 -08001598 static std::mutex key2IndexMutex;
1599 static std::map<std::string, size_t> key2Index;
1600
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001601 // By default try all stores. However, try the last known client first. If
1602 // the last known client fails, retry once. We do this by pushing the last
1603 // known client in front of the list of all clients.
Pawin Vongmasa36653902018-11-15 00:10:25 -08001604 std::deque<size_t> indices;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001605 for (size_t index = Cache::List().size(); index > 0; ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001606 indices.push_front(--index);
1607 }
1608
1609 bool wasMapped = false;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001610 {
1611 std::scoped_lock lock{key2IndexMutex};
1612 auto it = key2Index.find(key);
1613 if (it != key2Index.end()) {
1614 indices.push_front(it->second);
1615 wasMapped = true;
1616 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001617 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001618
1619 for (size_t index : indices) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001620 Cache& cache = Cache::List()[index];
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001621 for (size_t tries = numberOfAttempts; tries > 0; --tries) {
1622 std::shared_ptr<Codec2Client> client{cache.getClient()};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001623 status = predicate(client);
1624 if (status == C2_OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001625 std::scoped_lock lock{key2IndexMutex};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001626 key2Index[key] = index; // update last known client index
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001627 return C2_OK;
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001628 } else if (status == C2_NO_MEMORY) {
1629 return C2_NO_MEMORY;
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001630 } else if (status == C2_TRANSACTION_FAILED) {
1631 LOG(WARNING) << "\"" << key << "\" failed for service \""
1632 << client->getName()
1633 << "\" due to transaction failure. "
1634 << "(Service may have crashed.)"
1635 << (tries > 1 ? " Retrying..." : "");
1636 cache.invalidate();
1637 continue;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001638 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001639 if (wasMapped) {
1640 LOG(INFO) << "\"" << key << "\" became invalid in service \""
1641 << client->getName() << "\". Retrying...";
1642 wasMapped = false;
1643 }
1644 break;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001645 }
1646 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001647 return status; // return the last status from a valid client
Pawin Vongmasa36653902018-11-15 00:10:25 -08001648}
1649
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001650c2_status_t Codec2Client::CreateComponentByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001651 const char* componentName,
1652 const std::shared_ptr<Listener>& listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001653 std::shared_ptr<Component>* component,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001654 std::shared_ptr<Codec2Client>* owner,
1655 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001656 std::string key{"create:"};
1657 key.append(componentName);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001658 c2_status_t status = ForAllServices(
1659 key,
1660 numberOfAttempts,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001661 [owner, component, componentName, &listener](
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001662 const std::shared_ptr<Codec2Client> &client)
1663 -> c2_status_t {
1664 c2_status_t status = client->createComponent(componentName,
1665 listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001666 component);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001667 if (status == C2_OK) {
1668 if (owner) {
1669 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001670 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001671 } else if (status != C2_NOT_FOUND) {
1672 LOG(DEBUG) << "IComponentStore("
1673 << client->getServiceName()
1674 << ")::createComponent(\"" << componentName
1675 << "\") returned status = "
1676 << status << ".";
1677 }
1678 return status;
1679 });
1680 if (status != C2_OK) {
1681 LOG(DEBUG) << "Failed to create component \"" << componentName
1682 << "\" from all known services. "
1683 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001684 }
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001685 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001686}
1687
Wonsik Kime8e98152022-12-16 16:04:17 -08001688std::shared_ptr<Codec2Client::Interface> Codec2Client::CreateInterfaceByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001689 const char* interfaceName,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001690 std::shared_ptr<Codec2Client>* owner,
1691 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001692 std::string key{"create:"};
1693 key.append(interfaceName);
1694 std::shared_ptr<Interface> interface;
1695 c2_status_t status = ForAllServices(
1696 key,
1697 numberOfAttempts,
1698 [owner, &interface, interfaceName](
1699 const std::shared_ptr<Codec2Client> &client)
1700 -> c2_status_t {
1701 c2_status_t status = client->createInterface(interfaceName,
1702 &interface);
1703 if (status == C2_OK) {
1704 if (owner) {
1705 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001706 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001707 } else if (status != C2_NOT_FOUND) {
1708 LOG(DEBUG) << "IComponentStore("
1709 << client->getServiceName()
1710 << ")::createInterface(\"" << interfaceName
1711 << "\") returned status = "
1712 << status << ".";
1713 }
1714 return status;
1715 });
1716 if (status != C2_OK) {
1717 LOG(DEBUG) << "Failed to create interface \"" << interfaceName
1718 << "\" from all known services. "
1719 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001720 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001721 return interface;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001722}
1723
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001724std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
1725 static std::vector<C2Component::Traits> sList{[]() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001726 std::vector<C2Component::Traits> list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001727 for (Cache& cache : Cache::List()) {
1728 std::vector<C2Component::Traits> const& traits = cache.getTraits();
1729 list.insert(list.end(), traits.begin(), traits.end());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001730 }
1731 return list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001732 }()};
1733 return sList;
1734}
Pawin Vongmasa36653902018-11-15 00:10:25 -08001735
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001736std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
1737 char const* serviceName) {
Pawin Vongmasa18588322019-05-18 01:52:13 -07001738 int32_t inputSurfaceSetting = ::android::base::GetIntProperty(
1739 "debug.stagefright.c2inputsurface", int32_t(0));
1740 if (inputSurfaceSetting <= 0) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001741 return nullptr;
1742 }
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001743 size_t index = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001744 if (serviceName) {
1745 index = getServiceIndex(serviceName);
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001746 if (index == GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001747 LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
1748 << serviceName << "\"";
1749 }
1750 }
1751
1752 std::shared_ptr<Codec2Client::InputSurface> inputSurface;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001753 if (index != GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001754 std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
1755 if (client->createInputSurface(&inputSurface) == C2_OK) {
1756 return inputSurface;
1757 }
1758 }
1759 LOG(INFO) << "CreateInputSurface -- attempting to create an input surface "
1760 "from all services...";
1761 for (Cache& cache : Cache::List()) {
1762 std::shared_ptr<Codec2Client> client = cache.getClient();
1763 if (client->createInputSurface(&inputSurface) == C2_OK) {
1764 LOG(INFO) << "CreateInputSurface -- input surface obtained from "
1765 "service \"" << client->getServiceName() << "\"";
1766 return inputSurface;
1767 }
1768 }
1769 LOG(WARNING) << "CreateInputSurface -- failed to create an input surface "
1770 "from all services";
1771 return nullptr;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001772}
1773
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001774// Codec2Client::Interface
Wonsik Kime8e98152022-12-16 16:04:17 -08001775Codec2Client::Interface::Interface(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001776 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001777 [base]() -> sp<c2_hidl::IConfigurable> {
1778 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001779 base->getConfigurable();
1780 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001781 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001782 nullptr;
1783 }()
1784 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001785 mHidlBase{base} {
1786}
1787
1788Codec2Client::Interface::Interface(const std::shared_ptr<AidlBase>& base)
1789 : Configurable{
1790 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1791 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1792 ::ndk::ScopedAStatus transStatus =
1793 base->getConfigurable(&aidlConfigurable);
1794 return transStatus.isOk() ? aidlConfigurable : nullptr;
1795 }()
1796 },
1797 mAidlBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001798}
1799
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001800// Codec2Client::Component
Wonsik Kime8e98152022-12-16 16:04:17 -08001801
1802class Codec2Client::Component::AidlDeathManager {
1803public:
1804 AidlDeathManager()
1805 : mSeq(0),
1806 mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) {
1807 }
1808
1809 ~AidlDeathManager() = default;
1810
1811 bool linkToDeath(
1812 const std::shared_ptr<Component> &comp,
1813 const std::shared_ptr<Listener> &listener,
1814 size_t *seqPtr) {
1815 std::unique_lock lock(mMutex);
1816 size_t seq = mSeq++;
1817 if (!mMap.try_emplace(seq, comp, listener).second) {
1818 return false;
1819 }
1820 if (STATUS_OK != AIBinder_linkToDeath(
1821 comp->mAidlBase->asBinder().get(), mDeathRecipient.get(), (void *)seq)) {
1822 mMap.erase(seq);
1823 return false;
1824 }
1825 *seqPtr = seq;
1826 return true;
1827 }
1828
1829 void unlinkToDeath(size_t seq, const std::shared_ptr<AidlBase> &base) {
1830 std::unique_lock lock(mMutex);
1831 AIBinder_unlinkToDeath(base->asBinder().get(), mDeathRecipient.get(), (void *)seq);
1832 mMap.erase(seq);
1833 }
1834
1835private:
1836 std::mutex mMutex;
1837 size_t mSeq;
1838 typedef std::tuple<std::weak_ptr<Component>, std::weak_ptr<Listener>> Context;
1839 std::map<size_t, Context> mMap;
1840 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
1841
1842 bool extractContext(size_t seq, Context *context) {
1843 std::unique_lock lock(mMutex);
1844 auto node = mMap.extract(seq);
1845 if (!node) {
1846 return false;
1847 }
1848 *context = node.mapped();
1849 return true;
1850 }
1851
1852 static void OnBinderDied(void *cookie) {
1853 size_t seq = size_t(cookie);
1854 Context context;
1855 if (!Component::GetAidlDeathManager()->extractContext(seq, &context)) {
1856 return;
1857 }
1858 std::weak_ptr<Component> weakComponent;
1859 std::weak_ptr<Listener> weakListener;
1860 std::tie(weakComponent, weakListener) = context;
1861 if (std::shared_ptr<Listener> listener = weakListener.lock()) {
1862 listener->onDeath(weakComponent);
1863 } else {
1864 LOG(DEBUG) << "onDeath -- listener died.";
1865 }
1866 }
1867};
1868
1869Codec2Client::Component::Component(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001870 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001871 [base]() -> sp<c2_hidl::IConfigurable> {
1872 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001873 base->getInterface();
1874 if (!transResult1.isOk()) {
1875 return nullptr;
1876 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001877 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1878 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001879 getConfigurable();
1880 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001881 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001882 nullptr;
1883 }()
1884 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001885 mHidlBase1_0{base},
1886 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1887 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1888 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001889 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1890}
1891
Wonsik Kime8e98152022-12-16 16:04:17 -08001892Codec2Client::Component::Component(const sp<HidlBase1_1>& base)
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001893 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001894 [base]() -> sp<c2_hidl::IConfigurable> {
1895 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001896 base->getInterface();
1897 if (!transResult1.isOk()) {
1898 return nullptr;
1899 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001900 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1901 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001902 getConfigurable();
1903 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001904 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001905 nullptr;
1906 }()
1907 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001908 mHidlBase1_0{base},
1909 mHidlBase1_1{base},
1910 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1911 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Sungtak Lee8577dab2021-03-12 02:25:50 -08001912 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1913}
1914
Wonsik Kime8e98152022-12-16 16:04:17 -08001915Codec2Client::Component::Component(const sp<HidlBase1_2>& base)
Sungtak Lee8577dab2021-03-12 02:25:50 -08001916 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001917 [base]() -> sp<c2_hidl::IConfigurable> {
1918 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Sungtak Lee8577dab2021-03-12 02:25:50 -08001919 base->getInterface();
1920 if (!transResult1.isOk()) {
1921 return nullptr;
1922 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001923 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1924 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Sungtak Lee8577dab2021-03-12 02:25:50 -08001925 getConfigurable();
1926 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001927 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Sungtak Lee8577dab2021-03-12 02:25:50 -08001928 nullptr;
1929 }()
1930 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001931 mHidlBase1_0{base},
1932 mHidlBase1_1{base},
1933 mHidlBase1_2{base},
1934 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
1935 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1936}
1937
1938Codec2Client::Component::Component(const std::shared_ptr<AidlBase> &base)
1939 : Configurable{
1940 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1941 std::shared_ptr<c2_aidl::IComponentInterface> aidlIntf;
1942 ::ndk::ScopedAStatus transStatus = base->getInterface(&aidlIntf);
1943 if (!transStatus.isOk()) {
1944 return nullptr;
1945 }
1946 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1947 transStatus = aidlIntf->getConfigurable(&aidlConfigurable);
1948 return transStatus.isOk() ? aidlConfigurable : nullptr;
1949 }()
1950 },
1951 mAidlBase{base},
1952 mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001953 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001954}
1955
1956Codec2Client::Component::~Component() {
Wonsik Kime8e98152022-12-16 16:04:17 -08001957 if (mAidlDeathSeq) {
1958 GetAidlDeathManager()->unlinkToDeath(*mAidlDeathSeq, mAidlBase);
1959 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001960}
1961
1962c2_status_t Codec2Client::Component::createBlockPool(
1963 C2Allocator::id_t id,
1964 C2BlockPool::local_id_t* blockPoolId,
1965 std::shared_ptr<Codec2Client::Configurable>* configurable) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001966 if (mAidlBase) {
1967 c2_aidl::IComponent::BlockPool aidlBlockPool;
Ryan Prichard8d37bb02023-09-13 20:23:15 -07001968 ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id),
1969 &aidlBlockPool);
Wonsik Kime8e98152022-12-16 16:04:17 -08001970 c2_status_t status = GetC2Status(transStatus, "createBlockPool");
1971 if (status != C2_OK) {
1972 return status;
1973 }
1974 *blockPoolId = aidlBlockPool.blockPoolId;
1975 *configurable = std::make_shared<Configurable>(aidlBlockPool.configurable);
1976 return C2_OK;
1977 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001978 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001979 Return<void> transStatus = mHidlBase1_0->createBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001980 static_cast<uint32_t>(id),
1981 [&status, blockPoolId, configurable](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001982 c2_hidl::Status s,
Pawin Vongmasa36653902018-11-15 00:10:25 -08001983 uint64_t pId,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001984 const sp<c2_hidl::IConfigurable>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001985 status = static_cast<c2_status_t>(s);
1986 configurable->reset();
1987 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001988 LOG(DEBUG) << "createBlockPool -- call failed: "
1989 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001990 return;
1991 }
1992 *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001993 *configurable = std::make_shared<Configurable>(c);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001994 });
1995 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001996 LOG(ERROR) << "createBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001997 return C2_TRANSACTION_FAILED;
1998 }
1999 return status;
2000}
2001
2002c2_status_t Codec2Client::Component::destroyBlockPool(
2003 C2BlockPool::local_id_t localId) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002004 if (mAidlBase) {
2005 ::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId);
2006 return GetC2Status(transStatus, "destroyBlockPool");
2007 }
2008 Return<c2_hidl::Status> transResult = mHidlBase1_0->destroyBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002009 static_cast<uint64_t>(localId));
2010 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002011 LOG(ERROR) << "destroyBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002012 return C2_TRANSACTION_FAILED;
2013 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002014 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002015}
2016
Wonsik Kimab34ed62019-01-31 15:28:46 -08002017void Codec2Client::Component::handleOnWorkDone(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002018 const std::list<std::unique_ptr<C2Work>> &workItems) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002019 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002020 mOutputBufferQueue->holdBufferQueueBlocks(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002021}
2022
2023c2_status_t Codec2Client::Component::queue(
2024 std::list<std::unique_ptr<C2Work>>* const items) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002025 if (mAidlBase) {
2026 c2_aidl::WorkBundle workBundle;
2027 if (!c2_aidl::utils::ToAidl(&workBundle, *items, mAidlBufferPoolSender.get())) {
2028 LOG(ERROR) << "queue -- bad input.";
2029 return C2_TRANSACTION_FAILED;
2030 }
2031 ::ndk::ScopedAStatus transStatus = mAidlBase->queue(workBundle);
2032 return GetC2Status(transStatus, "queue");
2033 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002034 c2_hidl::WorkBundle workBundle;
Wonsik Kime8e98152022-12-16 16:04:17 -08002035 if (!c2_hidl::utils::objcpy(&workBundle, *items, mHidlBufferPoolSender.get())) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002036 LOG(ERROR) << "queue -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002037 return C2_TRANSACTION_FAILED;
2038 }
Wonsik Kime8e98152022-12-16 16:04:17 -08002039 Return<c2_hidl::Status> transStatus = mHidlBase1_0->queue(workBundle);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002040 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002041 LOG(ERROR) << "queue -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002042 return C2_TRANSACTION_FAILED;
2043 }
2044 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002045 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002046 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002047 LOG(DEBUG) << "queue -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002048 }
2049 return status;
2050}
2051
2052c2_status_t Codec2Client::Component::flush(
2053 C2Component::flush_mode_t mode,
2054 std::list<std::unique_ptr<C2Work>>* const flushedWork) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002055 (void)mode; // Flush mode isn't supported in HIDL/AIDL yet.
2056 c2_status_t status = C2_OK;
2057 if (mAidlBase) {
2058 c2_aidl::WorkBundle workBundle;
2059 ::ndk::ScopedAStatus transStatus = mAidlBase->flush(&workBundle);
2060 c2_status_t status = GetC2Status(transStatus, "flush");
2061 if (status != C2_OK) {
2062 return status;
2063 }
2064 if (!c2_aidl::utils::FromAidl(flushedWork, workBundle)) {
2065 LOG(DEBUG) << "flush -- flushedWork corrupted.";
2066 return C2_CORRUPTED;
2067 }
2068 } else {
2069 Return<void> transStatus = mHidlBase1_0->flush(
2070 [&status, flushedWork](
2071 c2_hidl::Status s, const c2_hidl::WorkBundle& wb) {
2072 status = static_cast<c2_status_t>(s);
2073 if (status != C2_OK) {
2074 LOG(DEBUG) << "flush -- call failed: " << status << ".";
2075 return;
2076 }
2077 if (!c2_hidl::utils::objcpy(flushedWork, wb)) {
2078 status = C2_CORRUPTED;
2079 } else {
2080 status = C2_OK;
2081 }
2082 });
2083 if (!transStatus.isOk()) {
2084 LOG(ERROR) << "flush -- transaction failed.";
2085 return C2_TRANSACTION_FAILED;
2086 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002087 }
2088
2089 // Indices of flushed work items.
2090 std::vector<uint64_t> flushedIndices;
2091 for (const std::unique_ptr<C2Work> &work : *flushedWork) {
2092 if (work) {
2093 if (work->worklets.empty()
2094 || !work->worklets.back()
2095 || (work->worklets.back()->output.flags &
2096 C2FrameData::FLAG_INCOMPLETE) == 0) {
2097 // input is complete
2098 flushedIndices.emplace_back(
2099 work->input.ordinal.frameIndex.peeku());
2100 }
2101 }
2102 }
2103
Pawin Vongmasa36653902018-11-15 00:10:25 -08002104 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002105 mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002106
2107 return status;
2108}
2109
2110c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002111 if (mAidlBase) {
2112 ::ndk::ScopedAStatus transStatus = mAidlBase->drain(
2113 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2114 return GetC2Status(transStatus, "drain");
2115 }
2116 Return<c2_hidl::Status> transStatus = mHidlBase1_0->drain(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002117 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2118 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002119 LOG(ERROR) << "drain -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002120 return C2_TRANSACTION_FAILED;
2121 }
2122 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002123 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002124 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002125 LOG(DEBUG) << "drain -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002126 }
2127 return status;
2128}
2129
2130c2_status_t Codec2Client::Component::start() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002131 if (mAidlBase) {
2132 ::ndk::ScopedAStatus transStatus = mAidlBase->start();
2133 return GetC2Status(transStatus, "start");
2134 }
2135 Return<c2_hidl::Status> transStatus = mHidlBase1_0->start();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002136 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002137 LOG(ERROR) << "start -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002138 return C2_TRANSACTION_FAILED;
2139 }
2140 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002141 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002142 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002143 LOG(DEBUG) << "start -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002144 }
2145 return status;
2146}
2147
2148c2_status_t Codec2Client::Component::stop() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002149 if (mAidlBase) {
2150 ::ndk::ScopedAStatus transStatus = mAidlBase->stop();
2151 return GetC2Status(transStatus, "stop");
2152 }
2153 Return<c2_hidl::Status> transStatus = mHidlBase1_0->stop();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002154 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002155 LOG(ERROR) << "stop -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002156 return C2_TRANSACTION_FAILED;
2157 }
2158 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002159 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002160 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002161 LOG(DEBUG) << "stop -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002162 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002163 return status;
2164}
2165
2166c2_status_t Codec2Client::Component::reset() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002167 if (mAidlBase) {
2168 ::ndk::ScopedAStatus transStatus = mAidlBase->reset();
2169 return GetC2Status(transStatus, "reset");
2170 }
2171 Return<c2_hidl::Status> transStatus = mHidlBase1_0->reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002172 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002173 LOG(ERROR) << "reset -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002174 return C2_TRANSACTION_FAILED;
2175 }
2176 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002177 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002178 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002179 LOG(DEBUG) << "reset -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002180 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002181 return status;
2182}
2183
2184c2_status_t Codec2Client::Component::release() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002185 if (mAidlBase) {
2186 ::ndk::ScopedAStatus transStatus = mAidlBase->release();
2187 return GetC2Status(transStatus, "release");
2188 }
2189 Return<c2_hidl::Status> transStatus = mHidlBase1_0->release();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002190 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002191 LOG(ERROR) << "release -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002192 return C2_TRANSACTION_FAILED;
2193 }
2194 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002195 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002196 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002197 LOG(DEBUG) << "release -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002198 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002199 return status;
2200}
2201
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002202c2_status_t Codec2Client::Component::configureVideoTunnel(
2203 uint32_t avSyncHwId,
2204 native_handle_t** sidebandHandle) {
2205 *sidebandHandle = nullptr;
Wonsik Kime8e98152022-12-16 16:04:17 -08002206 if (mAidlBase) {
2207 ::aidl::android::hardware::common::NativeHandle handle;
2208 ::ndk::ScopedAStatus transStatus = mAidlBase->configureVideoTunnel(avSyncHwId, &handle);
2209 c2_status_t status = GetC2Status(transStatus, "configureVideoTunnel");
2210 if (status != C2_OK) {
2211 return status;
2212 }
2213 if (isAidlNativeHandleEmpty(handle)) {
2214 LOG(DEBUG) << "configureVideoTunnel -- empty handle returned";
2215 } else {
2216 *sidebandHandle = dupFromAidl(handle);
2217 }
2218 return C2_OK;
2219 }
2220 if (!mHidlBase1_1) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002221 return C2_OMITTED;
2222 }
2223 c2_status_t status{};
Wonsik Kime8e98152022-12-16 16:04:17 -08002224 Return<void> transStatus = mHidlBase1_1->configureVideoTunnel(avSyncHwId,
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002225 [&status, sidebandHandle](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002226 c2_hidl::Status s, hardware::hidl_handle const& h) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002227 status = static_cast<c2_status_t>(s);
2228 if (h.getNativeHandle()) {
2229 *sidebandHandle = native_handle_clone(h.getNativeHandle());
2230 }
2231 });
2232 if (!transStatus.isOk()) {
2233 LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
2234 return C2_TRANSACTION_FAILED;
2235 }
2236 return status;
2237}
2238
Pawin Vongmasa36653902018-11-15 00:10:25 -08002239c2_status_t Codec2Client::Component::setOutputSurface(
2240 C2BlockPool::local_id_t blockPoolId,
2241 const sp<IGraphicBufferProducer>& surface,
Sungtak Leedb14cba2021-04-10 00:50:23 -07002242 uint32_t generation,
2243 int maxDequeueCount) {
Sungtak Lee08515812019-06-05 11:16:32 -07002244 uint64_t bqId = 0;
2245 sp<IGraphicBufferProducer> nullIgbp;
2246 sp<HGraphicBufferProducer2> nullHgbp;
Pawin Vongmasa3866c7e2019-01-31 05:21:29 -08002247
Sungtak Lee08515812019-06-05 11:16:32 -07002248 sp<HGraphicBufferProducer2> igbp = surface ?
2249 surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp;
2250 if (surface && !igbp) {
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002251 igbp = new B2HGraphicBufferProducer2(surface);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002252 }
2253
Sungtak Leefb579022022-05-10 06:36:15 +00002254 std::scoped_lock lock(mOutputMutex);
Sungtak Leea714f112021-03-16 05:40:03 -07002255 std::shared_ptr<SurfaceSyncObj> syncObj;
2256
Sungtak Lee08515812019-06-05 11:16:32 -07002257 if (!surface) {
Sungtak Leedb14cba2021-04-10 00:50:23 -07002258 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002259 } else if (surface->getUniqueId(&bqId) != OK) {
2260 LOG(ERROR) << "setOutputSurface -- "
2261 "cannot obtain bufferqueue id.";
2262 bqId = 0;
Sungtak Leedb14cba2021-04-10 00:50:23 -07002263 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002264 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08002265 mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount,
2266 mHidlBase1_2 ? &syncObj : nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002267 }
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002268
2269 // set consumer bits
2270 // TODO: should this get incorporated into setOutputSurface method so that consumer bits
2271 // can be set atomically?
2272 uint64_t consumerUsage = kDefaultConsumerUsage;
2273 {
2274 if (surface) {
Sungtak Lee46a69d62023-08-12 07:24:24 +00002275 uint64_t usage = 0;
2276 status_t err = surface->getConsumerUsage(&usage);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002277 if (err != NO_ERROR) {
2278 ALOGD("setOutputSurface -- failed to get consumer usage bits (%d/%s). ignoring",
2279 err, asString(err));
2280 } else {
2281 // Note: we are adding the default usage because components must support
2282 // producing output frames that can be displayed an all output surfaces.
2283
2284 // TODO: do not set usage for tunneled scenario. It is unclear if consumer usage
2285 // is meaningful in a tunneled scenario; on one hand output buffers exist, but
2286 // they do not exist inside of C2 scope. Any buffer usage shall be communicated
2287 // through the sideband channel.
2288
Sungtak Lee46a69d62023-08-12 07:24:24 +00002289 consumerUsage = usage | kDefaultConsumerUsage;
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002290 }
2291 }
2292
2293 C2StreamUsageTuning::output outputUsage{
2294 0u, C2AndroidMemoryUsage::FromGrallocUsage(consumerUsage).expected};
2295 std::vector<std::unique_ptr<C2SettingResult>> failures;
2296 c2_status_t err = config({&outputUsage}, C2_MAY_BLOCK, &failures);
2297 if (err != C2_OK) {
2298 ALOGD("setOutputSurface -- failed to set consumer usage (%d/%s)",
2299 err, asString(err));
2300 }
2301 }
2302 ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
2303 generation, (long long)consumerUsage, syncObj ? " sync" : "");
Sungtak Lee08515812019-06-05 11:16:32 -07002304
Wonsik Kime8e98152022-12-16 16:04:17 -08002305 if (mAidlBase) {
2306 // FIXME
2307 return C2_OMITTED;
2308 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002309 Return<c2_hidl::Status> transStatus = syncObj ?
Wonsik Kime8e98152022-12-16 16:04:17 -08002310 mHidlBase1_2->setOutputSurfaceWithSyncObj(
Sungtak Leea714f112021-03-16 05:40:03 -07002311 static_cast<uint64_t>(blockPoolId),
2312 bqId == 0 ? nullHgbp : igbp, *syncObj) :
Wonsik Kime8e98152022-12-16 16:04:17 -08002313 mHidlBase1_0->setOutputSurface(
Sungtak Leea714f112021-03-16 05:40:03 -07002314 static_cast<uint64_t>(blockPoolId),
2315 bqId == 0 ? nullHgbp : igbp);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002316
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002317 mOutputBufferQueue->expireOldWaiters();
2318
Pawin Vongmasa36653902018-11-15 00:10:25 -08002319 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002320 LOG(ERROR) << "setOutputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002321 return C2_TRANSACTION_FAILED;
2322 }
2323 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002324 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002325 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002326 LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002327 }
Sungtak Leea714f112021-03-16 05:40:03 -07002328 ALOGD("Surface configure completed");
Pawin Vongmasa36653902018-11-15 00:10:25 -08002329 return status;
2330}
2331
2332status_t Codec2Client::Component::queueToOutputSurface(
2333 const C2ConstGraphicBlock& block,
2334 const QueueBufferInput& input,
2335 QueueBufferOutput* output) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002336 return mOutputBufferQueue->outputBuffer(block, input, output);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002337}
2338
Brian Lindahlc953b462023-01-27 16:21:43 -07002339void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
2340 mOutputBufferQueue->pollForRenderedFrames(delta);
2341}
2342
Sungtak Leea714f112021-03-16 05:40:03 -07002343void Codec2Client::Component::setOutputSurfaceMaxDequeueCount(
2344 int maxDequeueCount) {
2345 mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount);
2346}
2347
Sungtak Leec7da7a02022-05-05 08:45:33 +00002348void Codec2Client::Component::stopUsingOutputSurface(
2349 C2BlockPool::local_id_t blockPoolId) {
Sungtak Leefb579022022-05-10 06:36:15 +00002350 std::scoped_lock lock(mOutputMutex);
Sungtak Leec7da7a02022-05-05 08:45:33 +00002351 mOutputBufferQueue->stop();
Wonsik Kime8e98152022-12-16 16:04:17 -08002352 if (mAidlBase) {
2353 // FIXME
2354 return;
2355 }
2356 Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface(
Sungtak Leec7da7a02022-05-05 08:45:33 +00002357 static_cast<uint64_t>(blockPoolId), nullptr);
2358 if (!transStatus.isOk()) {
2359 LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed.";
2360 } else {
2361 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002362 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Sungtak Leec7da7a02022-05-05 08:45:33 +00002363 if (status != C2_OK) {
2364 LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: "
2365 << status << ".";
2366 }
2367 }
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002368 mOutputBufferQueue->expireOldWaiters();
Sungtak Leec7da7a02022-05-05 08:45:33 +00002369}
2370
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002371c2_status_t Codec2Client::Component::connectToInputSurface(
2372 const std::shared_ptr<InputSurface>& inputSurface,
2373 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002374 if (mAidlBase) {
2375 // FIXME
2376 return C2_OMITTED;
2377 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002378 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002379 Return<void> transStatus = mHidlBase1_0->connectToInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002380 inputSurface->mBase,
2381 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002382 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002383 status = static_cast<c2_status_t>(s);
2384 if (status != C2_OK) {
2385 LOG(DEBUG) << "connectToInputSurface -- call failed: "
2386 << status << ".";
2387 return;
2388 }
2389 *connection = std::make_shared<InputSurfaceConnection>(c);
2390 });
Pawin Vongmasa36653902018-11-15 00:10:25 -08002391 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002392 LOG(ERROR) << "connectToInputSurface -- transaction failed";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002393 return C2_TRANSACTION_FAILED;
2394 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002395 return status;
2396}
2397
2398c2_status_t Codec2Client::Component::connectToOmxInputSurface(
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002399 const sp<HGraphicBufferProducer1>& producer,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002400 const sp<HGraphicBufferSource>& source,
2401 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002402 if (mAidlBase) {
2403 LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL";
2404 return C2_OMITTED;
2405 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002406 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002407 Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002408 producer, source,
2409 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002410 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002411 status = static_cast<c2_status_t>(s);
2412 if (status != C2_OK) {
2413 LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
2414 << status << ".";
2415 return;
2416 }
2417 *connection = std::make_shared<InputSurfaceConnection>(c);
2418 });
2419 if (!transStatus.isOk()) {
2420 LOG(ERROR) << "connectToOmxInputSurface -- transaction failed.";
2421 return C2_TRANSACTION_FAILED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08002422 }
2423 return status;
2424}
2425
2426c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002427 if (mAidlBase) {
2428 // FIXME
2429 return C2_OMITTED;
2430 }
2431 Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002432 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002433 LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002434 return C2_TRANSACTION_FAILED;
2435 }
2436 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002437 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002438 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002439 LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
2440 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002441 }
2442 return status;
2443}
2444
Wonsik Kime8e98152022-12-16 16:04:17 -08002445Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() {
2446 // This object never gets destructed
2447 static AidlDeathManager *sManager = new AidlDeathManager();
2448 return sManager;
2449}
2450
Pawin Vongmasa36653902018-11-15 00:10:25 -08002451c2_status_t Codec2Client::Component::setDeathListener(
2452 const std::shared_ptr<Component>& component,
2453 const std::shared_ptr<Listener>& listener) {
2454
2455 struct HidlDeathRecipient : public hardware::hidl_death_recipient {
2456 std::weak_ptr<Component> component;
2457 std::weak_ptr<Listener> base;
2458
2459 virtual void serviceDied(
2460 uint64_t /* cookie */,
2461 const wp<::android::hidl::base::V1_0::IBase>& /* who */
2462 ) override {
2463 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
2464 listener->onDeath(component);
2465 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002466 LOG(DEBUG) << "onDeath -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002467 }
2468 }
2469 };
2470
Wonsik Kime8e98152022-12-16 16:04:17 -08002471 if (component->mAidlBase) {
2472 size_t seq;
2473 if (GetAidlDeathManager()->linkToDeath(component, listener, &seq)) {
2474 component->mAidlDeathSeq = seq;
2475 }
2476 return C2_OK;
2477 }
2478
Pawin Vongmasa36653902018-11-15 00:10:25 -08002479 sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient();
2480 deathRecipient->base = listener;
2481 deathRecipient->component = component;
2482
2483 component->mDeathRecipient = deathRecipient;
Wonsik Kime8e98152022-12-16 16:04:17 -08002484 Return<bool> transResult = component->mHidlBase1_0->linkToDeath(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002485 component->mDeathRecipient, 0);
2486 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002487 LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002488 return C2_TRANSACTION_FAILED;
2489 }
2490 if (!static_cast<bool>(transResult)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002491 LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002492 return C2_CORRUPTED;
2493 }
2494 return C2_OK;
2495}
2496
2497// Codec2Client::InputSurface
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002498Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002499 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002500 [base]() -> sp<c2_hidl::IConfigurable> {
2501 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002502 base->getConfigurable();
2503 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002504 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002505 nullptr;
2506 }()
2507 },
2508 mBase{base},
2509 mGraphicBufferProducer{new
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002510 H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> {
2511 Return<sp<HGraphicBufferProducer2>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002512 base->getGraphicBufferProducer();
2513 return transResult.isOk() ?
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002514 static_cast<sp<HGraphicBufferProducer2>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002515 nullptr;
2516 }())} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002517}
2518
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002519sp<IGraphicBufferProducer>
Pawin Vongmasa36653902018-11-15 00:10:25 -08002520 Codec2Client::InputSurface::getGraphicBufferProducer() const {
2521 return mGraphicBufferProducer;
2522}
2523
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002524sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002525 return mBase;
2526}
2527
2528// Codec2Client::InputSurfaceConnection
Pawin Vongmasa36653902018-11-15 00:10:25 -08002529Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002530 const sp<c2_hidl::IInputSurfaceConnection>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002531 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002532 [base]() -> sp<c2_hidl::IConfigurable> {
2533 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002534 base->getConfigurable();
2535 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002536 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002537 nullptr;
2538 }()
2539 },
2540 mBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002541}
2542
2543c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002544 Return<c2_hidl::Status> transResult = mBase->disconnect();
2545 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002546}
2547
2548} // namespace android