blob: ce1010981b9e07d7c38c00f1adb6118cfdad8444 [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"
Arun Johnson7ba67072023-11-06 22:23:04 +000019#define ATRACE_TAG ATRACE_TAG_VIDEO
Pawin Vongmasa1c75a232019-01-09 04:41:52 -080020#include <android-base/logging.h>
Arun Johnson7ba67072023-11-06 22:23:04 +000021#include <utils/Trace.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080022#include <codec2/hidl/client.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070023#include <C2Debug.h>
24#include <C2BufferPriv.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080025#include <C2Config.h> // for C2StreamUsageTuning
Pawin Vongmasabf69de92019-10-29 06:21:27 -070026#include <C2PlatformSupport.h>
27
28#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
29#include <android/hardware/media/c2/1.0/IComponent.h>
30#include <android/hardware/media/c2/1.0/IComponentInterface.h>
31#include <android/hardware/media/c2/1.0/IComponentListener.h>
32#include <android/hardware/media/c2/1.0/IComponentStore.h>
33#include <android/hardware/media/c2/1.0/IConfigurable.h>
34#include <android/hidl/manager/1.2/IServiceManager.h>
35
Wonsik Kime8e98152022-12-16 16:04:17 -080036#include <aidl/android/hardware/media/bufferpool2/IClientManager.h>
37#include <aidl/android/hardware/media/c2/BnComponentListener.h>
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080038#include <aidl/android/hardware/media/c2/FieldSupportedValues.h>
39#include <aidl/android/hardware/media/c2/FieldSupportedValuesQuery.h>
40#include <aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.h>
41#include <aidl/android/hardware/media/c2/IComponent.h>
42#include <aidl/android/hardware/media/c2/IComponentInterface.h>
43#include <aidl/android/hardware/media/c2/IComponentStore.h>
44#include <aidl/android/hardware/media/c2/IConfigurable.h>
45#include <aidl/android/hardware/media/c2/ParamDescriptor.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080046#include <aidl/android/hardware/media/c2/StructDescriptor.h>
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080047
Wonsik Kime8e98152022-12-16 16:04:17 -080048#include <aidlcommonsupport/NativeHandle.h>
Wonsik Kim138db0d2023-11-02 16:02:01 -070049#include <android/api-level.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080050#include <android/binder_auto_utils.h>
51#include <android/binder_ibinder.h>
52#include <android/binder_manager.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070053#include <android-base/properties.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080054#include <android-base/stringprintf.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070055#include <bufferpool/ClientManager.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080056#include <bufferpool2/ClientManager.h>
57#include <codec2/aidl/BufferTypes.h>
Wonsik Kim1caded02022-12-09 13:03:11 -080058#include <codec2/aidl/ParamTypes.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070059#include <codec2/hidl/1.0/types.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070060#include <codec2/hidl/1.1/types.h>
Sungtak Lee8577dab2021-03-12 02:25:50 -080061#include <codec2/hidl/1.2/types.h>
Sungtak Leea714f112021-03-16 05:40:03 -070062#include <codec2/hidl/output.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070063
64#include <cutils/native_handle.h>
65#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
66#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080067#include <hardware/gralloc.h> // for GRALLOC_USAGE_*
Pawin Vongmasabf69de92019-10-29 06:21:27 -070068#include <hidl/HidlSupport.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080069#include <system/window.h> // for NATIVE_WINDOW_QUERY_*
70#include <media/stagefright/foundation/ADebug.h> // for asString(status_t)
Pawin Vongmasa36653902018-11-15 00:10:25 -080071
72#include <deque>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070073#include <iterator>
Pawin Vongmasa36653902018-11-15 00:10:25 -080074#include <limits>
75#include <map>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070076#include <mutex>
77#include <sstream>
78#include <thread>
Pawin Vongmasa36653902018-11-15 00:10:25 -080079#include <type_traits>
80#include <vector>
81
Pawin Vongmasa36653902018-11-15 00:10:25 -080082namespace android {
83
84using ::android::hardware::hidl_vec;
85using ::android::hardware::hidl_string;
86using ::android::hardware::Return;
87using ::android::hardware::Void;
Pawin Vongmasa36653902018-11-15 00:10:25 -080088
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080089using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
90 V1_0::IGraphicBufferProducer;
91using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
92 V2_0::IGraphicBufferProducer;
93using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
94 V2_0::utils::B2HGraphicBufferProducer;
95using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
96 V2_0::utils::H2BGraphicBufferProducer;
Sungtak Leea714f112021-03-16 05:40:03 -070097using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080098
Wonsik Kime8e98152022-12-16 16:04:17 -080099namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800100namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
101namespace c2_aidl = ::aidl::android::hardware::media::c2;
102namespace c2_hidl_base = ::android::hardware::media::c2;
103namespace c2_hidl = ::android::hardware::media::c2::V1_2;
104
105using c2_hidl::utils::operator<<;
106
Pawin Vongmasa36653902018-11-15 00:10:25 -0800107namespace /* unnamed */ {
108
109// c2_status_t value that corresponds to hwbinder transaction failure.
110constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
111
Lajos Molnar78aa7c92021-02-18 21:39:01 -0800112// By default prepare buffer to be displayed on any of the common surfaces
113constexpr uint64_t kDefaultConsumerUsage =
114 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER);
115
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700116// Searches for a name in GetServiceNames() and returns the index found. If the
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700117// name is not found, the returned index will be equal to
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700118// GetServiceNames().size().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700119size_t getServiceIndex(char const* name) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700120 std::vector<std::string> const& names = Codec2Client::GetServiceNames();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700121 size_t i = 0;
122 for (; i < names.size(); ++i) {
123 if (name == names[i]) {
124 break;
125 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800126 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700127 return i;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800128}
129
Pawin Vongmasa83d2c552020-03-05 04:36:08 -0800130class Client2Store : public C2ComponentStore {
131 std::shared_ptr<Codec2Client> mClient;
132
133public:
134 Client2Store(std::shared_ptr<Codec2Client> const& client)
135 : mClient(client) { }
136
137 virtual ~Client2Store() = default;
138
139 virtual c2_status_t config_sm(
140 std::vector<C2Param*> const &params,
141 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
142 return mClient->config(params, C2_MAY_BLOCK, failures);
143 };
144
145 virtual c2_status_t copyBuffer(
146 std::shared_ptr<C2GraphicBuffer>,
147 std::shared_ptr<C2GraphicBuffer>) {
148 return C2_OMITTED;
149 }
150
151 virtual c2_status_t createComponent(
152 C2String, std::shared_ptr<C2Component>* const component) {
153 component->reset();
154 return C2_OMITTED;
155 }
156
157 virtual c2_status_t createInterface(
158 C2String, std::shared_ptr<C2ComponentInterface>* const interface) {
159 interface->reset();
160 return C2_OMITTED;
161 }
162
163 virtual c2_status_t query_sm(
164 std::vector<C2Param*> const& stackParams,
165 std::vector<C2Param::Index> const& heapParamIndices,
166 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
167 return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
168 }
169
170 virtual c2_status_t querySupportedParams_nb(
171 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
172 return mClient->querySupportedParams(params);
173 }
174
175 virtual c2_status_t querySupportedValues_sm(
176 std::vector<C2FieldSupportedValuesQuery>& fields) const {
177 return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
178 }
179
180 virtual C2String getName() const {
181 return mClient->getName();
182 }
183
184 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
185 return mClient->getParamReflector();
186 }
187
188 virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() {
189 return std::vector<std::shared_ptr<C2Component::Traits const>>();
190 }
191};
192
Wonsik Kime8e98152022-12-16 16:04:17 -0800193c2_status_t GetC2Status(const ::ndk::ScopedAStatus &transStatus, const char *method) {
194 if (!transStatus.isOk()) {
195 if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
196 c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
197 LOG(DEBUG) << method << " -- call failed: " << status << ".";
198 return status;
199 } else {
200 LOG(ERROR) << method << " -- transaction failed.";
201 return C2_TRANSACTION_FAILED;
202 }
203 }
204 return C2_OK;
205}
206
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700207} // unnamed namespace
208
209// This class caches a Codec2Client object and its component traits. The client
210// will be created the first time it is needed, and it can be refreshed if the
211// service dies (by calling invalidate()). The first time listComponents() is
212// called from the client, the result will be cached.
213class Codec2Client::Cache {
214 // Cached client
215 std::shared_ptr<Codec2Client> mClient;
216 mutable std::mutex mClientMutex;
217
218 // Cached component traits
219 std::vector<C2Component::Traits> mTraits;
220 std::once_flag mTraitsInitializationFlag;
221
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700222 // The index of the service. This is based on GetServiceNames().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700223 size_t mIndex;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700224 // Called by s() exactly once to initialize the cache. The index must be a
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700225 // valid index into the vector returned by GetServiceNames(). Calling
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700226 // init(index) will associate the cache to the service with name
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700227 // GetServiceNames()[index].
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700228 void init(size_t index) {
229 mIndex = index;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700230 }
231
232public:
233 Cache() = default;
234
235 // Initializes mClient if needed, then returns mClient.
236 // If the service is unavailable but listed in the manifest, this function
237 // will block indefinitely.
238 std::shared_ptr<Codec2Client> getClient() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700239 std::scoped_lock lock{mClientMutex};
240 if (!mClient) {
241 mClient = Codec2Client::_CreateFromIndex(mIndex);
242 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -0700243 CHECK(mClient) << "Failed to create Codec2Client to service \""
244 << GetServiceNames()[mIndex] << "\". (Index = "
245 << mIndex << ").";
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700246 return mClient;
247 }
248
249 // Causes a subsequent call to getClient() to create a new client. This
250 // function should be called after the service dies.
251 //
252 // Note: This function is called only by ForAllServices().
253 void invalidate() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700254 std::scoped_lock lock{mClientMutex};
255 mClient = nullptr;
256 }
257
258 // Returns a list of traits for components supported by the service. This
259 // list is cached.
260 std::vector<C2Component::Traits> const& getTraits() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700261 std::call_once(mTraitsInitializationFlag, [this]() {
262 bool success{false};
263 // Spin until _listComponents() is successful.
264 while (true) {
265 std::shared_ptr<Codec2Client> client = getClient();
266 mTraits = client->_listComponents(&success);
267 if (success) {
268 break;
269 }
Pawin Vongmasa21617db2020-04-24 06:16:42 -0700270 invalidate();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700271 using namespace std::chrono_literals;
272 static constexpr auto kServiceRetryPeriod = 5s;
273 LOG(INFO) << "Failed to retrieve component traits from service "
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700274 "\"" << GetServiceNames()[mIndex] << "\". "
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700275 "Retrying...";
276 std::this_thread::sleep_for(kServiceRetryPeriod);
277 }
278 });
279 return mTraits;
280 }
281
282 // List() returns the list of all caches.
283 static std::vector<Cache>& List() {
284 static std::vector<Cache> sCaches{[]() {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700285 size_t numServices = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700286 std::vector<Cache> caches(numServices);
287 for (size_t i = 0; i < numServices; ++i) {
288 caches[i].init(i);
289 }
290 return caches;
291 }()};
292 return sCaches;
293 }
294};
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800295// Codec2ConfigurableClient::HidlImpl
Pawin Vongmasa36653902018-11-15 00:10:25 -0800296
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800297struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase {
298 typedef c2_hidl::IConfigurable Base;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800299
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800300 // base cannot be null.
301 explicit HidlImpl(const sp<Base>& base);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800302
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800303 const C2String& getName() const override {
304 return mName;
305 }
306
307 c2_status_t query(
308 const std::vector<C2Param*>& stackParams,
309 const std::vector<C2Param::Index> &heapParamIndices,
310 c2_blocking_t mayBlock,
311 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
312
313 c2_status_t config(
314 const std::vector<C2Param*> &params,
315 c2_blocking_t mayBlock,
316 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
317
318 c2_status_t querySupportedParams(
319 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
320 ) const override;
321
322 c2_status_t querySupportedValues(
323 std::vector<C2FieldSupportedValuesQuery>& fields,
324 c2_blocking_t mayBlock) const override;
325
326private:
327 sp<Base> mBase;
328 const C2String mName;
329};
330
331Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800332 : mBase{base},
333 mName{[base]() -> C2String {
334 C2String outName;
335 Return<void> transStatus = base->getName(
336 [&outName](const hidl_string& name) {
337 outName = name.c_str();
338 });
339 return transStatus.isOk() ? outName : "";
340 }()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800341}
342
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800343c2_status_t Codec2ConfigurableClient::HidlImpl::query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800344 const std::vector<C2Param*> &stackParams,
345 const std::vector<C2Param::Index> &heapParamIndices,
346 c2_blocking_t mayBlock,
347 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800348 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800349 stackParams.size() + heapParamIndices.size());
350 size_t numIndices = 0;
351 for (C2Param* const& stackParam : stackParams) {
352 if (!stackParam) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800353 LOG(WARNING) << "query -- null stack param encountered.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800354 continue;
355 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800356 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800357 }
358 size_t numStackIndices = numIndices;
359 for (const C2Param::Index& index : heapParamIndices) {
360 indices[numIndices++] =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800361 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800362 }
363 indices.resize(numIndices);
364 if (heapParams) {
365 heapParams->reserve(heapParams->size() + numIndices);
366 }
367 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800368 Return<void> transStatus = mBase->query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800369 indices,
370 mayBlock == C2_MAY_BLOCK,
371 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800372 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800373 status = static_cast<c2_status_t>(s);
374 if (status != C2_OK && status != C2_BAD_INDEX) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800375 LOG(DEBUG) << "query -- call failed: "
376 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800377 return;
378 }
379 std::vector<C2Param*> paramPointers;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800380 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800381 LOG(ERROR) << "query -- error while parsing params.";
382 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800383 return;
384 }
385 size_t i = 0;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800386 for (auto it = paramPointers.begin();
387 it != paramPointers.end(); ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800388 C2Param* paramPointer = *it;
389 if (numStackIndices > 0) {
390 --numStackIndices;
391 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800392 LOG(WARNING) << "query -- null stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800393 ++it;
394 continue;
395 }
396 for (; i < stackParams.size() && !stackParams[i]; ) {
397 ++i;
398 }
399 if (i >= stackParams.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800400 LOG(ERROR) << "query -- unexpected error.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800401 status = C2_CORRUPTED;
402 return;
403 }
404 if (stackParams[i]->index() != paramPointer->index()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800405 LOG(WARNING) << "query -- param skipped: "
406 "index = "
407 << stackParams[i]->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800408 stackParams[i++]->invalidate();
409 continue;
410 }
411 if (!stackParams[i++]->updateFrom(*paramPointer)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800412 LOG(WARNING) << "query -- param update failed: "
413 "index = "
414 << paramPointer->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800415 }
416 } else {
417 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800418 LOG(WARNING) << "query -- null heap param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800419 ++it;
420 continue;
421 }
422 if (!heapParams) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800423 LOG(WARNING) << "query -- "
424 "unexpected extra stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800425 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800426 heapParams->emplace_back(
427 C2Param::Copy(*paramPointer));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800428 }
429 }
430 ++it;
431 }
432 });
433 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800434 LOG(ERROR) << "query -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800435 return C2_TRANSACTION_FAILED;
436 }
437 return status;
438}
439
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800440c2_status_t Codec2ConfigurableClient::HidlImpl::config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800441 const std::vector<C2Param*> &params,
442 c2_blocking_t mayBlock,
443 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800444 c2_hidl::Params hidlParams;
445 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800446 LOG(ERROR) << "config -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800447 return C2_TRANSACTION_FAILED;
448 }
449 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800450 Return<void> transStatus = mBase->config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800451 hidlParams,
452 mayBlock == C2_MAY_BLOCK,
453 [&status, &params, failures](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800454 c2_hidl::Status s,
455 const hidl_vec<c2_hidl::SettingResult> f,
456 const c2_hidl::Params& o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800457 status = static_cast<c2_status_t>(s);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800458 if (status != C2_OK && status != C2_BAD_INDEX) {
459 LOG(DEBUG) << "config -- call failed: "
460 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800461 }
462 size_t i = failures->size();
463 failures->resize(i + f.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800464 for (const c2_hidl::SettingResult& sf : f) {
465 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800466 LOG(ERROR) << "config -- "
467 << "invalid SettingResult returned.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800468 return;
469 }
470 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800471 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800472 LOG(ERROR) << "config -- "
473 << "failed to parse returned params.";
474 status = C2_CORRUPTED;
475 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800476 });
477 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800478 LOG(ERROR) << "config -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800479 return C2_TRANSACTION_FAILED;
480 }
481 return status;
482}
483
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800484c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800485 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
486 // TODO: Cache and query properly!
487 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800488 Return<void> transStatus = mBase->querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800489 std::numeric_limits<uint32_t>::min(),
490 std::numeric_limits<uint32_t>::max(),
491 [&status, params](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800492 c2_hidl::Status s,
493 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800494 status = static_cast<c2_status_t>(s);
495 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800496 LOG(DEBUG) << "querySupportedParams -- call failed: "
497 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800498 return;
499 }
500 size_t i = params->size();
501 params->resize(i + p.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800502 for (const c2_hidl::ParamDescriptor& sp : p) {
503 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800504 LOG(ERROR) << "querySupportedParams -- "
505 << "invalid returned ParamDescriptor.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800506 return;
507 }
508 }
509 });
510 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800511 LOG(ERROR) << "querySupportedParams -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800512 return C2_TRANSACTION_FAILED;
513 }
514 return status;
515}
516
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800517c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800518 std::vector<C2FieldSupportedValuesQuery>& fields,
519 c2_blocking_t mayBlock) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800520 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800521 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800522 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800523 LOG(ERROR) << "querySupportedValues -- bad input";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800524 return C2_TRANSACTION_FAILED;
525 }
526 }
527
528 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800529 Return<void> transStatus = mBase->querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800530 inFields,
531 mayBlock == C2_MAY_BLOCK,
532 [&status, &inFields, &fields](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800533 c2_hidl::Status s,
534 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800535 status = static_cast<c2_status_t>(s);
536 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800537 LOG(DEBUG) << "querySupportedValues -- call failed: "
538 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800539 return;
540 }
541 if (r.size() != fields.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800542 LOG(ERROR) << "querySupportedValues -- "
543 "input and output lists "
544 "have different sizes.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800545 status = C2_CORRUPTED;
546 return;
547 }
548 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800549 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800550 LOG(ERROR) << "querySupportedValues -- "
551 "invalid returned value.";
552 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800553 return;
554 }
555 }
556 });
557 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800558 LOG(ERROR) << "querySupportedValues -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800559 return C2_TRANSACTION_FAILED;
560 }
561 return status;
562}
563
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800564// Codec2ConfigurableClient::AidlImpl
565
566struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase {
567 typedef c2_aidl::IConfigurable Base;
568
569 // base cannot be null.
570 explicit AidlImpl(const std::shared_ptr<Base>& base);
571
572 const C2String& getName() const override {
573 return mName;
574 }
575
576 c2_status_t query(
577 const std::vector<C2Param*>& stackParams,
578 const std::vector<C2Param::Index> &heapParamIndices,
579 c2_blocking_t mayBlock,
580 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
581
582 c2_status_t config(
583 const std::vector<C2Param*> &params,
584 c2_blocking_t mayBlock,
585 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
586
587 c2_status_t querySupportedParams(
588 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
589 ) const override;
590
591 c2_status_t querySupportedValues(
592 std::vector<C2FieldSupportedValuesQuery>& fields,
593 c2_blocking_t mayBlock) const override;
594
595private:
596 std::shared_ptr<Base> mBase;
597 const C2String mName;
598};
599
600Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base)
601 : mBase{base},
602 mName{[base]() -> C2String {
603 std::string outName;
604 ndk::ScopedAStatus status = base->getName(&outName);
605 return status.isOk() ? outName : "";
606 }()} {
607}
608
609c2_status_t Codec2ConfigurableClient::AidlImpl::query(
610 const std::vector<C2Param*> &stackParams,
611 const std::vector<C2Param::Index> &heapParamIndices,
612 c2_blocking_t mayBlock,
613 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800614 std::vector<int> indices(
615 stackParams.size() + heapParamIndices.size());
616 size_t numIndices = 0;
617 for (C2Param* const& stackParam : stackParams) {
618 if (!stackParam) {
619 LOG(WARNING) << "query -- null stack param encountered.";
620 continue;
621 }
622 indices[numIndices++] = int(stackParam->index());
623 }
624 size_t numStackIndices = numIndices;
625 for (const C2Param::Index& index : heapParamIndices) {
626 indices[numIndices++] = int(static_cast<uint32_t>(index));
627 }
628 indices.resize(numIndices);
629 if (heapParams) {
630 heapParams->reserve(heapParams->size() + numIndices);
631 }
632 c2_aidl::Params result;
633 ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800634 c2_status_t status = GetC2Status(transStatus, "query");
635 if (status != C2_OK) {
636 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800637 }
638
Wonsik Kim1caded02022-12-09 13:03:11 -0800639 std::vector<C2Param*> paramPointers;
640 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, result)) {
641 LOG(ERROR) << "query -- error while parsing params.";
642 return C2_CORRUPTED;
643 }
644 size_t i = 0;
645 for (auto it = paramPointers.begin();
646 it != paramPointers.end(); ) {
647 C2Param* paramPointer = *it;
648 if (numStackIndices > 0) {
649 --numStackIndices;
650 if (!paramPointer) {
651 LOG(DEBUG) << "query -- null stack param.";
652 ++it;
653 continue;
654 }
655 for (; i < stackParams.size() && !stackParams[i]; ) {
656 ++i;
657 }
658 if (i >= stackParams.size()) {
659 LOG(ERROR) << "query -- unexpected error.";
660 status = C2_CORRUPTED;
661 break;
662 }
663 if (stackParams[i]->index() != paramPointer->index()) {
664 LOG(DEBUG) << "query -- param skipped: "
665 "index = "
666 << stackParams[i]->index() << ".";
667 stackParams[i++]->invalidate();
668 // this means that the param could not be queried.
669 // signalling C2_BAD_INDEX to the client.
670 status = C2_BAD_INDEX;
671 continue;
672 }
673 if (!stackParams[i++]->updateFrom(*paramPointer)) {
674 LOG(WARNING) << "query -- param update failed: "
675 "index = "
676 << paramPointer->index() << ".";
677 }
678 } else {
679 if (!paramPointer) {
680 LOG(DEBUG) << "query -- null heap param.";
681 ++it;
682 continue;
683 }
684 if (!heapParams) {
685 LOG(WARNING) << "query -- "
686 "unexpected extra stack param.";
687 } else {
688 heapParams->emplace_back(C2Param::Copy(*paramPointer));
689 }
690 }
691 ++it;
692 }
693 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800694}
695
696c2_status_t Codec2ConfigurableClient::AidlImpl::config(
697 const std::vector<C2Param*> &params,
698 c2_blocking_t mayBlock,
699 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kim1caded02022-12-09 13:03:11 -0800700 c2_aidl::Params aidlParams;
701 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
702 LOG(ERROR) << "config -- bad input.";
703 return C2_TRANSACTION_FAILED;
704 }
705 c2_aidl::IConfigurable::ConfigResult result;
706 ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800707 c2_status_t status = GetC2Status(transStatus, "config");
708 if (status != C2_OK) {
709 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800710 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800711 size_t i = failures->size();
712 failures->resize(i + result.failures.size());
713 for (const c2_aidl::SettingResult& sf : result.failures) {
714 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
715 LOG(ERROR) << "config -- invalid SettingResult returned.";
716 return C2_CORRUPTED;
717 }
718 }
719 if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) {
720 LOG(ERROR) << "config -- "
721 << "failed to parse returned params.";
722 status = C2_CORRUPTED;
723 }
724 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800725}
726
727c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams(
728 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800729 // TODO: Cache and query properly!
730 std::vector<c2_aidl::ParamDescriptor> result;
731 ndk::ScopedAStatus transStatus = mBase->querySupportedParams(
732 std::numeric_limits<uint32_t>::min(),
733 std::numeric_limits<uint32_t>::max(),
734 &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800735 c2_status_t status = GetC2Status(transStatus, "querySupportedParams");
736 if (status != C2_OK) {
737 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800738 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800739 size_t i = params->size();
740 params->resize(i + result.size());
741 for (const c2_aidl::ParamDescriptor& sp : result) {
742 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
743 LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor.";
744 return C2_CORRUPTED;
745 }
746 }
747 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800748}
749
750c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues(
751 std::vector<C2FieldSupportedValuesQuery>& fields,
752 c2_blocking_t mayBlock) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800753 std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size());
754 for (size_t i = 0; i < fields.size(); ++i) {
755 if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) {
756 LOG(ERROR) << "querySupportedValues -- bad input";
757 return C2_TRANSACTION_FAILED;
758 }
759 }
760
761 std::vector<c2_aidl::FieldSupportedValuesQueryResult> result;
762 ndk::ScopedAStatus transStatus = mBase->querySupportedValues(
763 inFields, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800764 c2_status_t status = GetC2Status(transStatus, "querySupportedValues");
765 if (status != C2_OK) {
766 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800767 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800768 if (result.size() != fields.size()) {
769 LOG(ERROR) << "querySupportedValues -- "
770 "input and output lists "
771 "have different sizes.";
772 return C2_CORRUPTED;
773 }
774 for (size_t i = 0; i < fields.size(); ++i) {
775 if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) {
776 LOG(ERROR) << "querySupportedValues -- "
777 "invalid returned value.";
778 return C2_CORRUPTED;
779 }
780 }
781 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800782}
783
784// Codec2ConfigurableClient
785
786Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase)
787 : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) {
788}
789
790Codec2ConfigurableClient::Codec2ConfigurableClient(
791 const std::shared_ptr<AidlBase> &aidlBase)
792 : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) {
793}
794
795const C2String& Codec2ConfigurableClient::getName() const {
796 return mImpl->getName();
797}
798
799c2_status_t Codec2ConfigurableClient::query(
800 const std::vector<C2Param*>& stackParams,
801 const std::vector<C2Param::Index> &heapParamIndices,
802 c2_blocking_t mayBlock,
803 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
804 return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
805}
806
807c2_status_t Codec2ConfigurableClient::config(
808 const std::vector<C2Param*> &params,
809 c2_blocking_t mayBlock,
810 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
811 return mImpl->config(params, mayBlock, failures);
812}
813
814c2_status_t Codec2ConfigurableClient::querySupportedParams(
815 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
816 return mImpl->querySupportedParams(params);
817}
818
819c2_status_t Codec2ConfigurableClient::querySupportedValues(
820 std::vector<C2FieldSupportedValuesQuery>& fields,
821 c2_blocking_t mayBlock) const {
822 return mImpl->querySupportedValues(fields, mayBlock);
823}
824
825
Pawin Vongmasa36653902018-11-15 00:10:25 -0800826// Codec2Client::Component::HidlListener
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800827struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800828 std::weak_ptr<Component> component;
829 std::weak_ptr<Listener> base;
830
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800831 virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800832 std::list<std::unique_ptr<C2Work>> workItems;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800833 if (!c2_hidl::utils::objcpy(&workItems, workBundle)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800834 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800835 return Void();
836 }
837 // release input buffers potentially held by the component from queue
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800838 std::shared_ptr<Codec2Client::Component> strongComponent =
839 component.lock();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800840 if (strongComponent) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800841 strongComponent->handleOnWorkDone(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800842 }
843 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800844 listener->onWorkDone(component, workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800845 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800846 LOG(DEBUG) << "onWorkDone -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800847 }
848 return Void();
849 }
850
851 virtual Return<void> onTripped(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800852 const hidl_vec<c2_hidl::SettingResult>& settingResults) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800853 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
854 settingResults.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800855 for (size_t i = 0; i < settingResults.size(); ++i) {
856 std::unique_ptr<C2SettingResult> c2SettingResult;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800857 if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800858 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800859 return Void();
860 }
861 c2SettingResults[i] = std::move(c2SettingResult);
862 }
863 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
864 listener->onTripped(component, c2SettingResults);
865 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800866 LOG(DEBUG) << "onTripped -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800867 }
868 return Void();
869 }
870
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800871 virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800872 LOG(DEBUG) << "onError --"
873 << " status = " << s
874 << ", errorCode = " << errorCode
875 << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800876 if (std::shared_ptr<Listener> listener = base.lock()) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800877 listener->onError(component, s == c2_hidl::Status::OK ?
Pawin Vongmasa36653902018-11-15 00:10:25 -0800878 errorCode : static_cast<c2_status_t>(s));
879 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800880 LOG(DEBUG) << "onError -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800881 }
882 return Void();
883 }
884
885 virtual Return<void> onFramesRendered(
886 const hidl_vec<RenderedFrame>& renderedFrames) override {
887 std::shared_ptr<Listener> listener = base.lock();
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800888 if (!listener) {
889 LOG(DEBUG) << "onFramesRendered -- listener died.";
890 return Void();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800891 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800892 for (const RenderedFrame& renderedFrame : renderedFrames) {
893 listener->onFrameRendered(
894 renderedFrame.bufferQueueId,
895 renderedFrame.slotId,
896 renderedFrame.timestampNs);
897 }
898 return Void();
899 }
900
901 virtual Return<void> onInputBuffersReleased(
902 const hidl_vec<InputBuffer>& inputBuffers) override {
903 std::shared_ptr<Listener> listener = base.lock();
904 if (!listener) {
905 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
906 return Void();
907 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800908 for (const InputBuffer& inputBuffer : inputBuffers) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800909 LOG(VERBOSE) << "onInputBuffersReleased --"
910 " received death notification of"
911 " input buffer:"
912 " frameIndex = " << inputBuffer.frameIndex
913 << ", bufferIndex = " << inputBuffer.arrayIndex
914 << ".";
Wonsik Kimab34ed62019-01-31 15:28:46 -0800915 listener->onInputBufferDone(
916 inputBuffer.frameIndex, inputBuffer.arrayIndex);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800917 }
918 return Void();
919 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800920
Pawin Vongmasa36653902018-11-15 00:10:25 -0800921};
922
Wonsik Kime8e98152022-12-16 16:04:17 -0800923// Codec2Client::Component::AidlListener
924struct Codec2Client::Component::AidlListener : public c2_aidl::BnComponentListener {
925 std::weak_ptr<Component> component;
926 std::weak_ptr<Listener> base;
927
928 virtual ::ndk::ScopedAStatus onWorkDone(const c2_aidl::WorkBundle& workBundle) override {
929 std::list<std::unique_ptr<C2Work>> workItems;
930 if (!c2_aidl::utils::FromAidl(&workItems, workBundle)) {
931 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
932 return ::ndk::ScopedAStatus::ok();
933 }
934 // release input buffers potentially held by the component from queue
935 std::shared_ptr<Codec2Client::Component> strongComponent =
936 component.lock();
937 if (strongComponent) {
938 strongComponent->handleOnWorkDone(workItems);
939 }
940 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
941 listener->onWorkDone(component, workItems);
942 } else {
943 LOG(DEBUG) << "onWorkDone -- listener died.";
944 }
945 return ::ndk::ScopedAStatus::ok();
946 }
947
948 virtual ::ndk::ScopedAStatus onTripped(
949 const std::vector<c2_aidl::SettingResult>& settingResults) override {
950 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
951 settingResults.size());
952 for (size_t i = 0; i < settingResults.size(); ++i) {
953 std::unique_ptr<C2SettingResult> c2SettingResult;
954 if (!c2_aidl::utils::FromAidl(&c2SettingResult, settingResults[i])) {
955 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
956 return ::ndk::ScopedAStatus::ok();
957 }
958 c2SettingResults[i] = std::move(c2SettingResult);
959 }
960 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
961 listener->onTripped(component, c2SettingResults);
962 } else {
963 LOG(DEBUG) << "onTripped -- listener died.";
964 }
965 return ::ndk::ScopedAStatus::ok();
966 }
967
968 virtual ::ndk::ScopedAStatus onError(const c2_aidl::Status &s, int32_t errorCode) override {
969 LOG(DEBUG) << "onError --"
970 << " status = " << s.status
971 << ", errorCode = " << errorCode
972 << ".";
973 if (std::shared_ptr<Listener> listener = base.lock()) {
974 listener->onError(component, s.status == c2_aidl::Status::OK ?
975 errorCode : static_cast<c2_status_t>(s.status));
976 } else {
977 LOG(DEBUG) << "onError -- listener died.";
978 }
979 return ::ndk::ScopedAStatus::ok();
980 }
981
982 virtual ::ndk::ScopedAStatus onFramesRendered(
983 const std::vector<RenderedFrame>& renderedFrames) override {
984 std::shared_ptr<Listener> listener = base.lock();
985 if (!listener) {
986 LOG(DEBUG) << "onFramesRendered -- listener died.";
987 return ::ndk::ScopedAStatus::ok();
988 }
989 for (const RenderedFrame& renderedFrame : renderedFrames) {
990 listener->onFrameRendered(
991 renderedFrame.bufferQueueId,
992 renderedFrame.slotId,
993 renderedFrame.timestampNs);
994 }
995 return ::ndk::ScopedAStatus::ok();
996 }
997
998 virtual ::ndk::ScopedAStatus onInputBuffersReleased(
999 const std::vector<InputBuffer>& inputBuffers) override {
1000 std::shared_ptr<Listener> listener = base.lock();
1001 if (!listener) {
1002 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
1003 return ::ndk::ScopedAStatus::ok();
1004 }
1005 for (const InputBuffer& inputBuffer : inputBuffers) {
1006 LOG(VERBOSE) << "onInputBuffersReleased --"
1007 " received death notification of"
1008 " input buffer:"
1009 " frameIndex = " << inputBuffer.frameIndex
1010 << ", bufferIndex = " << inputBuffer.arrayIndex
1011 << ".";
1012 listener->onInputBufferDone(
1013 inputBuffer.frameIndex, inputBuffer.arrayIndex);
1014 }
1015 return ::ndk::ScopedAStatus::ok();
1016 }
1017
1018};
1019
1020// Codec2Client::Component::HidlBufferPoolSender
1021struct Codec2Client::Component::HidlBufferPoolSender :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001022 hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
Wonsik Kime8e98152022-12-16 16:04:17 -08001023 HidlBufferPoolSender()
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001024 : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
1025 }
1026};
1027
Wonsik Kime8e98152022-12-16 16:04:17 -08001028// Codec2Client::Component::AidlBufferPoolSender
1029struct Codec2Client::Component::AidlBufferPoolSender :
1030 c2_aidl::utils::DefaultBufferPoolSender {
1031 AidlBufferPoolSender()
1032 : c2_aidl::utils::DefaultBufferPoolSender() {
1033 }
1034};
1035
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001036// Codec2Client::Component::OutputBufferQueue
1037struct Codec2Client::Component::OutputBufferQueue :
Sungtak Leea714f112021-03-16 05:40:03 -07001038 hardware::media::c2::OutputBufferQueue {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001039 OutputBufferQueue()
Sungtak Leea714f112021-03-16 05:40:03 -07001040 : hardware::media::c2::OutputBufferQueue() {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001041 }
1042};
1043
Pawin Vongmasa36653902018-11-15 00:10:25 -08001044// Codec2Client
Wonsik Kime8e98152022-12-16 16:04:17 -08001045Codec2Client::Codec2Client(sp<HidlBase> const& base,
Sungtak Leef4b39512023-05-10 07:17:22 +00001046 sp<c2_hidl::IConfigurable> const& configurable,
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001047 size_t serviceIndex)
Sungtak Leef4b39512023-05-10 07:17:22 +00001048 : Configurable{configurable},
Wonsik Kime8e98152022-12-16 16:04:17 -08001049 mHidlBase1_0{base},
1050 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1051 mHidlBase1_2{HidlBase1_2::castFrom(base)},
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001052 mServiceIndex{serviceIndex} {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001053 Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager();
Pawin Vongmasa36653902018-11-15 00:10:25 -08001054 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001055 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001056 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08001057 mHidlHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001058 }
1059}
1060
Wonsik Kime8e98152022-12-16 16:04:17 -08001061Codec2Client::Codec2Client(std::shared_ptr<AidlBase> const& base,
1062 std::shared_ptr<c2_aidl::IConfigurable> const& configurable,
1063 size_t serviceIndex)
1064 : Configurable{configurable},
1065 mAidlBase{base},
1066 mServiceIndex{serviceIndex} {
1067 ::ndk::ScopedAStatus transStatus = base->getPoolClientManager(&mAidlHostPoolManager);
1068 if (!transStatus.isOk()) {
1069 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
1070 mAidlHostPoolManager.reset();
1071 }
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001072}
1073
Wonsik Kime8e98152022-12-16 16:04:17 -08001074sp<Codec2Client::HidlBase> const& Codec2Client::getHidlBase() const {
1075 return mHidlBase1_0;
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001076}
1077
Wonsik Kime8e98152022-12-16 16:04:17 -08001078sp<Codec2Client::HidlBase1_0> const& Codec2Client::getHidlBase1_0() const {
1079 return mHidlBase1_0;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001080}
1081
Wonsik Kime8e98152022-12-16 16:04:17 -08001082sp<Codec2Client::HidlBase1_1> const& Codec2Client::getHidlBase1_1() const {
1083 return mHidlBase1_1;
1084}
1085
1086sp<Codec2Client::HidlBase1_2> const& Codec2Client::getHidlBase1_2() const {
1087 return mHidlBase1_2;
1088}
1089
1090::ndk::SpAIBinder Codec2Client::getAidlBase() const {
1091 return mAidlBase ? mAidlBase->asBinder() : nullptr;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001092}
1093
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001094std::string const& Codec2Client::getServiceName() const {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001095 return GetServiceNames()[mServiceIndex];
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001096}
1097
Pawin Vongmasa36653902018-11-15 00:10:25 -08001098c2_status_t Codec2Client::createComponent(
1099 const C2String& name,
1100 const std::shared_ptr<Codec2Client::Listener>& listener,
1101 std::shared_ptr<Codec2Client::Component>* const component) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001102 if (mAidlBase) {
1103 std::shared_ptr<Component::AidlListener> aidlListener =
1104 Component::AidlListener::make<Component::AidlListener>();
1105 aidlListener->base = listener;
1106 std::shared_ptr<c2_aidl::IComponent> aidlComponent;
1107 ::ndk::ScopedAStatus transStatus = mAidlBase->createComponent(
1108 name,
1109 aidlListener,
1110 bufferpool2_aidl::implementation::ClientManager::getInstance(),
1111 &aidlComponent);
1112 c2_status_t status = GetC2Status(transStatus, "createComponent");
1113 if (status != C2_OK) {
1114 return status;
1115 } else if (!aidlComponent) {
1116 LOG(ERROR) << "createComponent(" << name.c_str()
1117 << ") -- null component.";
1118 return C2_CORRUPTED;
1119 }
1120 *component = std::make_shared<Codec2Client::Component>(aidlComponent);
1121 status = (*component)->setDeathListener((*component), listener);
1122 if (status != C2_OK) {
1123 LOG(ERROR) << "createComponent(" << name.c_str()
1124 << ") -- failed to set up death listener: "
1125 << status << ".";
1126 }
1127 (*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager);
1128 return status;
1129 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001130
Pawin Vongmasa36653902018-11-15 00:10:25 -08001131 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001132 sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001133 hidlListener->base = listener;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001134 Return<void> transStatus;
Wonsik Kime8e98152022-12-16 16:04:17 -08001135 if (mHidlBase1_2) {
1136 transStatus = mHidlBase1_2->createComponent_1_2(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001137 name,
1138 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001139 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasa36653902018-11-15 00:10:25 -08001140 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001141 c2_hidl::Status s,
1142 const sp<c2_hidl::IComponent>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001143 status = static_cast<c2_status_t>(s);
1144 if (status != C2_OK) {
1145 return;
1146 }
1147 *component = std::make_shared<Codec2Client::Component>(c);
1148 hidlListener->component = *component;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001149 });
1150 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001151 else if (mHidlBase1_1) {
1152 transStatus = mHidlBase1_1->createComponent_1_1(
Sungtak Lee8577dab2021-03-12 02:25:50 -08001153 name,
1154 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001155 bufferpool_hidl::implementation::ClientManager::getInstance(),
Sungtak Lee8577dab2021-03-12 02:25:50 -08001156 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001157 c2_hidl::Status s,
1158 const sp<c2_hidl_base::V1_1::IComponent>& c) {
Sungtak Lee8577dab2021-03-12 02:25:50 -08001159 status = static_cast<c2_status_t>(s);
1160 if (status != C2_OK) {
1161 return;
1162 }
1163 *component = std::make_shared<Codec2Client::Component>(c);
1164 hidlListener->component = *component;
1165 });
Wonsik Kime8e98152022-12-16 16:04:17 -08001166 } else if (mHidlBase1_0) { // ver1_0
1167 transStatus = mHidlBase1_0->createComponent(
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001168 name,
1169 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001170 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001171 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001172 c2_hidl::Status s,
1173 const sp<c2_hidl_base::V1_0::IComponent>& c) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001174 status = static_cast<c2_status_t>(s);
1175 if (status != C2_OK) {
1176 return;
1177 }
1178 *component = std::make_shared<Codec2Client::Component>(c);
1179 hidlListener->component = *component;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001180 });
Sungtak Lee8577dab2021-03-12 02:25:50 -08001181 } else {
1182 status = C2_CORRUPTED;
1183 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001184 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001185 LOG(ERROR) << "createComponent(" << name.c_str()
1186 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001187 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001188 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001189 if (status == C2_NOT_FOUND) {
1190 LOG(VERBOSE) << "createComponent(" << name.c_str()
1191 << ") -- component not found.";
1192 } else {
1193 LOG(ERROR) << "createComponent(" << name.c_str()
1194 << ") -- call failed: " << status << ".";
1195 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001196 return status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001197 } else if (!*component) {
1198 LOG(ERROR) << "createComponent(" << name.c_str()
1199 << ") -- null component.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001200 return C2_CORRUPTED;
1201 }
1202
1203 status = (*component)->setDeathListener(*component, listener);
1204 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001205 LOG(ERROR) << "createComponent(" << name.c_str()
1206 << ") -- failed to set up death listener: "
1207 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001208 }
1209
Wonsik Kime8e98152022-12-16 16:04:17 -08001210 (*component)->mHidlBufferPoolSender->setReceiver(mHidlHostPoolManager);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001211 return status;
1212}
1213
1214c2_status_t Codec2Client::createInterface(
1215 const C2String& name,
1216 std::shared_ptr<Codec2Client::Interface>* const interface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001217 if (mAidlBase) {
1218 std::shared_ptr<c2_aidl::IComponentInterface> aidlInterface;
1219 ::ndk::ScopedAStatus transStatus = mAidlBase->createInterface(
1220 name,
1221 &aidlInterface);
1222 c2_status_t status = GetC2Status(transStatus, "createInterface");
1223 if (status != C2_OK) {
1224 return status;
1225 } else if (!aidlInterface) {
1226 LOG(ERROR) << "createInterface(" << name.c_str()
1227 << ") -- null interface.";
1228 return C2_CORRUPTED;
1229 }
1230 interface->reset(new Codec2Client::Interface(aidlInterface));
1231 return C2_OK;
1232 }
1233
Pawin Vongmasa36653902018-11-15 00:10:25 -08001234 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001235 Return<void> transStatus = mHidlBase1_0->createInterface(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001236 name,
1237 [&status, interface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001238 c2_hidl::Status s,
1239 const sp<c2_hidl::IComponentInterface>& i) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001240 status = static_cast<c2_status_t>(s);
1241 if (status != C2_OK) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001242 return;
1243 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001244 *interface = std::make_shared<Interface>(i);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001245 });
1246 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001247 LOG(ERROR) << "createInterface(" << name.c_str()
1248 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001249 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001250 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001251 if (status == C2_NOT_FOUND) {
1252 LOG(VERBOSE) << "createInterface(" << name.c_str()
1253 << ") -- component not found.";
1254 } else {
1255 LOG(ERROR) << "createInterface(" << name.c_str()
1256 << ") -- call failed: " << status << ".";
1257 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001258 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001259 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001260
Pawin Vongmasa36653902018-11-15 00:10:25 -08001261 return status;
1262}
1263
1264c2_status_t Codec2Client::createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001265 std::shared_ptr<InputSurface>* const inputSurface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001266 if (mAidlBase) {
1267 // FIXME
1268 return C2_OMITTED;
1269 }
1270
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001271 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001272 Return<void> transStatus = mHidlBase1_0->createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001273 [&status, inputSurface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001274 c2_hidl::Status s,
1275 const sp<c2_hidl::IInputSurface>& i) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001276 status = static_cast<c2_status_t>(s);
1277 if (status != C2_OK) {
1278 return;
1279 }
1280 *inputSurface = std::make_shared<InputSurface>(i);
1281 });
1282 if (!transStatus.isOk()) {
1283 LOG(ERROR) << "createInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001284 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001285 } else if (status != C2_OK) {
1286 LOG(DEBUG) << "createInputSurface -- call failed: "
1287 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001288 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001289 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001290}
1291
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001292std::vector<C2Component::Traits> const& Codec2Client::listComponents() const {
1293 return Cache::List()[mServiceIndex].getTraits();
1294}
1295
1296std::vector<C2Component::Traits> Codec2Client::_listComponents(
1297 bool* success) const {
1298 std::vector<C2Component::Traits> traits;
1299 std::string const& serviceName = getServiceName();
Wonsik Kime8e98152022-12-16 16:04:17 -08001300
1301 if (mAidlBase) {
1302 std::vector<c2_aidl::IComponentStore::ComponentTraits> aidlTraits;
1303 ::ndk::ScopedAStatus transStatus = mAidlBase->listComponents(&aidlTraits);
1304 if (!transStatus.isOk()) {
1305 LOG(ERROR) << "_listComponents -- transaction failed.";
1306 *success = false;
1307 } else {
1308 traits.resize(aidlTraits.size());
1309 *success = true;
1310 for (size_t i = 0; i < aidlTraits.size(); ++i) {
1311 if (!c2_aidl::utils::FromAidl(&traits[i], aidlTraits[i])) {
1312 LOG(ERROR) << "_listComponents -- corrupted output.";
1313 *success = false;
1314 traits.clear();
1315 break;
1316 }
1317 traits[i].owner = serviceName;
1318 }
1319 }
1320 return traits;
1321 }
1322 Return<void> transStatus = mHidlBase1_0->listComponents(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001323 [&traits, &serviceName](c2_hidl::Status s,
1324 const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) {
1325 if (s != c2_hidl::Status::OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001326 LOG(DEBUG) << "_listComponents -- call failed: "
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001327 << static_cast<c2_status_t>(s) << ".";
1328 return;
1329 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001330 traits.resize(t.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001331 for (size_t i = 0; i < t.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001332 if (!c2_hidl::utils::objcpy(&traits[i], t[i])) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001333 LOG(ERROR) << "_listComponents -- corrupted output.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001334 return;
1335 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001336 traits[i].owner = serviceName;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001337 }
1338 });
1339 if (!transStatus.isOk()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001340 LOG(ERROR) << "_listComponents -- transaction failed.";
1341 *success = false;
1342 } else {
1343 *success = true;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001344 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001345 return traits;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001346}
1347
1348c2_status_t Codec2Client::copyBuffer(
1349 const std::shared_ptr<C2Buffer>& src,
1350 const std::shared_ptr<C2Buffer>& dst) {
1351 // TODO: Implement?
1352 (void)src;
1353 (void)dst;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001354 LOG(ERROR) << "copyBuffer not implemented";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001355 return C2_OMITTED;
1356}
1357
Wonsik Kime8e98152022-12-16 16:04:17 -08001358std::shared_ptr<C2ParamReflector> Codec2Client::getParamReflector() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001359 // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it
1360 // should reflect the HAL API.
Wonsik Kime8e98152022-12-16 16:04:17 -08001361 struct HidlSimpleParamReflector : public C2ParamReflector {
1362 std::unique_ptr<C2StructDescriptor> describe(
1363 C2Param::CoreIndex coreIndex) const override {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001364 hidl_vec<c2_hidl::ParamIndex> indices(1);
1365 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001366 std::unique_ptr<C2StructDescriptor> descriptor;
1367 Return<void> transStatus = mBase->getStructDescriptors(
1368 indices,
1369 [&descriptor](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001370 c2_hidl::Status s,
1371 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001372 c2_status_t status = static_cast<c2_status_t>(s);
1373 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001374 LOG(DEBUG) << "SimpleParamReflector -- "
1375 "getStructDescriptors() failed: "
1376 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001377 descriptor.reset();
1378 return;
1379 }
1380 if (sd.size() != 1) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001381 LOG(DEBUG) << "SimpleParamReflector -- "
1382 "getStructDescriptors() "
1383 "returned vector of size "
1384 << sd.size() << ". "
1385 "It should be 1.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001386 descriptor.reset();
1387 return;
1388 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001389 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001390 LOG(DEBUG) << "SimpleParamReflector -- "
1391 "getStructDescriptors() returned "
1392 "corrupted data.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001393 descriptor.reset();
1394 return;
1395 }
1396 });
Wonsik Kim492fecd2020-11-19 11:14:11 -08001397 if (!transStatus.isOk()) {
1398 LOG(DEBUG) << "SimpleParamReflector -- transaction failed: "
1399 << transStatus.description();
1400 descriptor.reset();
1401 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001402 return descriptor;
1403 }
1404
Wonsik Kime8e98152022-12-16 16:04:17 -08001405 HidlSimpleParamReflector(sp<HidlBase> base)
Pawin Vongmasa36653902018-11-15 00:10:25 -08001406 : mBase(base) { }
1407
Wonsik Kime8e98152022-12-16 16:04:17 -08001408 sp<HidlBase> mBase;
1409 };
1410 struct AidlSimpleParamReflector : public C2ParamReflector {
1411 std::unique_ptr<C2StructDescriptor> describe(
1412 C2Param::CoreIndex coreIndex) const override {
1413 std::vector<c2_aidl::StructDescriptor> aidlDesc;
1414 std::unique_ptr<C2StructDescriptor> descriptor;
1415 ::ndk::ScopedAStatus transStatus = mBase->getStructDescriptors(
1416 {int32_t(coreIndex.coreIndex())},
1417 &aidlDesc);
1418 c2_status_t status = GetC2Status(transStatus, "describe");
1419 if (status != C2_OK) {
1420 descriptor.reset();
1421 } else if (!c2_aidl::utils::FromAidl(&descriptor, aidlDesc[0])) {
1422 LOG(ERROR) << "describe -- conversion failed.";
1423 descriptor.reset();
1424 }
1425 return descriptor;
1426 }
1427
1428 AidlSimpleParamReflector(const std::shared_ptr<AidlBase> &base)
1429 : mBase(base) { }
1430
1431 std::shared_ptr<AidlBase> mBase;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001432 };
1433
Wonsik Kime8e98152022-12-16 16:04:17 -08001434 if (mAidlBase) {
1435 return std::make_shared<AidlSimpleParamReflector>(mAidlBase);
1436 }
1437 return std::make_shared<HidlSimpleParamReflector>(mHidlBase1_0);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001438};
1439
Wonsik Kime8e98152022-12-16 16:04:17 -08001440std::vector<std::string> Codec2Client::CacheServiceNames() {
1441 std::vector<std::string> names;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001442
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001443 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim138db0d2023-11-02 16:02:01 -07001444 if (__builtin_available(android __ANDROID_API_S__, *)) {
1445 // Get AIDL service names
1446 AServiceManager_forEachDeclaredInstance(
1447 AidlBase::descriptor, &names, [](const char *name, void *context) {
1448 std::vector<std::string> *names = (std::vector<std::string> *)context;
1449 names->emplace_back(name);
1450 });
1451 } else {
1452 LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35";
1453 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001454 } else {
1455 // Get HIDL service names
1456 using ::android::hardware::media::c2::V1_0::IComponentStore;
1457 using ::android::hidl::manager::V1_2::IServiceManager;
1458 while (true) {
1459 sp<IServiceManager> serviceManager = IServiceManager::getService();
1460 CHECK(serviceManager) << "Hardware service manager is not running.";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001461
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001462 Return<void> transResult;
1463 transResult = serviceManager->listManifestByInterface(
1464 IComponentStore::descriptor,
1465 [&names](
1466 hidl_vec<hidl_string> const& instanceNames) {
1467 names.insert(names.end(), instanceNames.begin(), instanceNames.end());
1468 });
1469 if (transResult.isOk()) {
1470 break;
1471 }
1472 LOG(ERROR) << "Could not retrieve the list of service instances of "
1473 << IComponentStore::descriptor
1474 << ". Retrying...";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001475 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001476 }
1477 // Sort service names in each category.
1478 std::stable_sort(
1479 names.begin(), names.end(),
1480 [](const std::string &a, const std::string &b) {
1481 // First compare by prefix: default -> vendor -> {everything else}
1482 constexpr int DEFAULT = 1;
1483 constexpr int VENDOR = 2;
1484 constexpr int OTHER = 3;
1485 int aPrefix = ((a.compare(0, 7, "default") == 0) ? DEFAULT :
1486 (a.compare(0, 6, "vendor") == 0) ? VENDOR :
1487 OTHER);
1488 int bPrefix = ((b.compare(0, 7, "default") == 0) ? DEFAULT :
1489 (b.compare(0, 6, "vendor") == 0) ? VENDOR :
1490 OTHER);
1491 if (aPrefix != bPrefix) {
1492 return aPrefix < bPrefix;
1493 }
1494 // If the prefix is the same, compare alphabetically
1495 return a < b;
1496 });
1497
1498 // Summarize to logcat.
1499 if (names.empty()) {
1500 LOG(INFO) << "No Codec2 services declared in the manifest.";
1501 } else {
1502 std::stringstream stringOutput;
1503 stringOutput << "Available Codec2 services:";
1504 for (std::string const& name : names) {
1505 stringOutput << " \"" << name << "\"";
1506 }
1507 LOG(INFO) << stringOutput.str();
1508 }
1509
1510 return names;
1511}
1512
1513std::vector<std::string> const& Codec2Client::GetServiceNames() {
1514 static std::vector<std::string> sServiceNames = CacheServiceNames();
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001515 return sServiceNames;
1516}
1517
Pawin Vongmasa36653902018-11-15 00:10:25 -08001518std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001519 const char* name,
1520 bool setAsPreferredCodec2ComponentStore) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001521 size_t index = getServiceIndex(name);
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001522 if (index == GetServiceNames().size()) {
1523 if (setAsPreferredCodec2ComponentStore) {
1524 LOG(WARNING) << "CreateFromService(" << name
1525 << ") -- preferred C2ComponentStore not set.";
1526 }
1527 return nullptr;
1528 }
1529 std::shared_ptr<Codec2Client> client = _CreateFromIndex(index);
1530 if (setAsPreferredCodec2ComponentStore) {
1531 SetPreferredCodec2ComponentStore(
1532 std::make_shared<Client2Store>(client));
1533 LOG(INFO) << "CreateFromService(" << name
1534 << ") -- service set as preferred C2ComponentStore.";
1535 }
1536 return client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001537}
1538
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001539std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
1540 CreateFromAllServices() {
1541 std::vector<std::shared_ptr<Codec2Client>> clients(
1542 GetServiceNames().size());
1543 for (size_t i = GetServiceNames().size(); i > 0; ) {
1544 --i;
1545 clients[i] = _CreateFromIndex(i);
1546 }
1547 return clients;
1548}
1549
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001550std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001551 std::string const& name = GetServiceNames()[index];
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001552 LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\"";
Wonsik Kime8e98152022-12-16 16:04:17 -08001553
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001554 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim138db0d2023-11-02 16:02:01 -07001555 if (__builtin_available(android __ANDROID_API_S__, *)) {
1556 std::string instanceName =
1557 ::android::base::StringPrintf("%s/%s", AidlBase::descriptor, name.c_str());
1558 if (AServiceManager_isDeclared(instanceName.c_str())) {
1559 std::shared_ptr<AidlBase> baseStore = AidlBase::fromBinder(
1560 ::ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));
1561 CHECK(baseStore) << "Codec2 AIDL service \"" << name << "\""
1562 " inaccessible for unknown reasons.";
1563 LOG(VERBOSE) << "Client to Codec2 AIDL service \"" << name << "\" created";
1564 std::shared_ptr<c2_aidl::IConfigurable> configurable;
1565 ::ndk::ScopedAStatus transStatus = baseStore->getConfigurable(&configurable);
1566 CHECK(transStatus.isOk()) << "Codec2 AIDL service \"" << name << "\""
1567 "does not have IConfigurable.";
1568 return std::make_shared<Codec2Client>(baseStore, configurable, index);
1569 } else {
1570 LOG(ERROR) << "Codec2 AIDL service \"" << name << "\" is not declared";
1571 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001572 } else {
Wonsik Kim138db0d2023-11-02 16:02:01 -07001573 LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35";
Wonsik Kime8e98152022-12-16 16:04:17 -08001574 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001575 } else {
1576 std::string instanceName = "android.hardware.media.c2/" + name;
1577 sp<HidlBase> baseStore = HidlBase::getService(name);
1578 CHECK(baseStore) << "Codec2 service \"" << name << "\""
1579 " inaccessible for unknown reasons.";
1580 LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created";
1581 Return<sp<c2_hidl::IConfigurable>> transResult = baseStore->getConfigurable();
1582 CHECK(transResult.isOk()) << "Codec2 service \"" << name << "\""
1583 "does not have IConfigurable.";
1584 sp<c2_hidl::IConfigurable> configurable =
1585 static_cast<sp<c2_hidl::IConfigurable>>(transResult);
1586 return std::make_shared<Codec2Client>(baseStore, configurable, index);
Wonsik Kime8e98152022-12-16 16:04:17 -08001587 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001588 return nullptr;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001589}
1590
1591c2_status_t Codec2Client::ForAllServices(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001592 const std::string &key,
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001593 size_t numberOfAttempts,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001594 std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
1595 predicate) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001596 c2_status_t status = C2_NO_INIT; // no IComponentStores present
1597
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001598 // Cache the mapping key -> index of Codec2Client in Cache::List().
Pawin Vongmasa36653902018-11-15 00:10:25 -08001599 static std::mutex key2IndexMutex;
1600 static std::map<std::string, size_t> key2Index;
1601
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001602 // By default try all stores. However, try the last known client first. If
1603 // the last known client fails, retry once. We do this by pushing the last
1604 // known client in front of the list of all clients.
Pawin Vongmasa36653902018-11-15 00:10:25 -08001605 std::deque<size_t> indices;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001606 for (size_t index = Cache::List().size(); index > 0; ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001607 indices.push_front(--index);
1608 }
1609
1610 bool wasMapped = false;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001611 {
1612 std::scoped_lock lock{key2IndexMutex};
1613 auto it = key2Index.find(key);
1614 if (it != key2Index.end()) {
1615 indices.push_front(it->second);
1616 wasMapped = true;
1617 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001618 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001619
1620 for (size_t index : indices) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001621 Cache& cache = Cache::List()[index];
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001622 for (size_t tries = numberOfAttempts; tries > 0; --tries) {
1623 std::shared_ptr<Codec2Client> client{cache.getClient()};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001624 status = predicate(client);
1625 if (status == C2_OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001626 std::scoped_lock lock{key2IndexMutex};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001627 key2Index[key] = index; // update last known client index
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001628 return C2_OK;
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001629 } else if (status == C2_NO_MEMORY) {
1630 return C2_NO_MEMORY;
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001631 } else if (status == C2_TRANSACTION_FAILED) {
1632 LOG(WARNING) << "\"" << key << "\" failed for service \""
1633 << client->getName()
1634 << "\" due to transaction failure. "
1635 << "(Service may have crashed.)"
1636 << (tries > 1 ? " Retrying..." : "");
1637 cache.invalidate();
1638 continue;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001639 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001640 if (wasMapped) {
1641 LOG(INFO) << "\"" << key << "\" became invalid in service \""
1642 << client->getName() << "\". Retrying...";
1643 wasMapped = false;
1644 }
1645 break;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001646 }
1647 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001648 return status; // return the last status from a valid client
Pawin Vongmasa36653902018-11-15 00:10:25 -08001649}
1650
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001651c2_status_t Codec2Client::CreateComponentByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001652 const char* componentName,
1653 const std::shared_ptr<Listener>& listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001654 std::shared_ptr<Component>* component,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001655 std::shared_ptr<Codec2Client>* owner,
1656 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001657 std::string key{"create:"};
1658 key.append(componentName);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001659 c2_status_t status = ForAllServices(
1660 key,
1661 numberOfAttempts,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001662 [owner, component, componentName, &listener](
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001663 const std::shared_ptr<Codec2Client> &client)
1664 -> c2_status_t {
1665 c2_status_t status = client->createComponent(componentName,
1666 listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001667 component);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001668 if (status == C2_OK) {
1669 if (owner) {
1670 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001671 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001672 } else if (status != C2_NOT_FOUND) {
1673 LOG(DEBUG) << "IComponentStore("
1674 << client->getServiceName()
1675 << ")::createComponent(\"" << componentName
1676 << "\") returned status = "
1677 << status << ".";
1678 }
1679 return status;
1680 });
1681 if (status != C2_OK) {
1682 LOG(DEBUG) << "Failed to create component \"" << componentName
1683 << "\" from all known services. "
1684 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001685 }
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001686 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001687}
1688
Wonsik Kime8e98152022-12-16 16:04:17 -08001689std::shared_ptr<Codec2Client::Interface> Codec2Client::CreateInterfaceByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001690 const char* interfaceName,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001691 std::shared_ptr<Codec2Client>* owner,
1692 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001693 std::string key{"create:"};
1694 key.append(interfaceName);
1695 std::shared_ptr<Interface> interface;
1696 c2_status_t status = ForAllServices(
1697 key,
1698 numberOfAttempts,
1699 [owner, &interface, interfaceName](
1700 const std::shared_ptr<Codec2Client> &client)
1701 -> c2_status_t {
1702 c2_status_t status = client->createInterface(interfaceName,
1703 &interface);
1704 if (status == C2_OK) {
1705 if (owner) {
1706 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001707 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001708 } else if (status != C2_NOT_FOUND) {
1709 LOG(DEBUG) << "IComponentStore("
1710 << client->getServiceName()
1711 << ")::createInterface(\"" << interfaceName
1712 << "\") returned status = "
1713 << status << ".";
1714 }
1715 return status;
1716 });
1717 if (status != C2_OK) {
1718 LOG(DEBUG) << "Failed to create interface \"" << interfaceName
1719 << "\" from all known services. "
1720 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001721 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001722 return interface;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001723}
1724
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001725std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
1726 static std::vector<C2Component::Traits> sList{[]() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001727 std::vector<C2Component::Traits> list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001728 for (Cache& cache : Cache::List()) {
1729 std::vector<C2Component::Traits> const& traits = cache.getTraits();
1730 list.insert(list.end(), traits.begin(), traits.end());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001731 }
1732 return list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001733 }()};
1734 return sList;
1735}
Pawin Vongmasa36653902018-11-15 00:10:25 -08001736
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001737std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
1738 char const* serviceName) {
Pawin Vongmasa18588322019-05-18 01:52:13 -07001739 int32_t inputSurfaceSetting = ::android::base::GetIntProperty(
1740 "debug.stagefright.c2inputsurface", int32_t(0));
1741 if (inputSurfaceSetting <= 0) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001742 return nullptr;
1743 }
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001744 size_t index = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001745 if (serviceName) {
1746 index = getServiceIndex(serviceName);
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001747 if (index == GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001748 LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
1749 << serviceName << "\"";
1750 }
1751 }
1752
1753 std::shared_ptr<Codec2Client::InputSurface> inputSurface;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001754 if (index != GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001755 std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
1756 if (client->createInputSurface(&inputSurface) == C2_OK) {
1757 return inputSurface;
1758 }
1759 }
1760 LOG(INFO) << "CreateInputSurface -- attempting to create an input surface "
1761 "from all services...";
1762 for (Cache& cache : Cache::List()) {
1763 std::shared_ptr<Codec2Client> client = cache.getClient();
1764 if (client->createInputSurface(&inputSurface) == C2_OK) {
1765 LOG(INFO) << "CreateInputSurface -- input surface obtained from "
1766 "service \"" << client->getServiceName() << "\"";
1767 return inputSurface;
1768 }
1769 }
1770 LOG(WARNING) << "CreateInputSurface -- failed to create an input surface "
1771 "from all services";
1772 return nullptr;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001773}
1774
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001775// Codec2Client::Interface
Wonsik Kime8e98152022-12-16 16:04:17 -08001776Codec2Client::Interface::Interface(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001777 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001778 [base]() -> sp<c2_hidl::IConfigurable> {
1779 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001780 base->getConfigurable();
1781 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001782 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001783 nullptr;
1784 }()
1785 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001786 mHidlBase{base} {
1787}
1788
1789Codec2Client::Interface::Interface(const std::shared_ptr<AidlBase>& base)
1790 : Configurable{
1791 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1792 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1793 ::ndk::ScopedAStatus transStatus =
1794 base->getConfigurable(&aidlConfigurable);
1795 return transStatus.isOk() ? aidlConfigurable : nullptr;
1796 }()
1797 },
1798 mAidlBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001799}
1800
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001801// Codec2Client::Component
Wonsik Kime8e98152022-12-16 16:04:17 -08001802
1803class Codec2Client::Component::AidlDeathManager {
1804public:
1805 AidlDeathManager()
1806 : mSeq(0),
1807 mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) {
1808 }
1809
1810 ~AidlDeathManager() = default;
1811
1812 bool linkToDeath(
1813 const std::shared_ptr<Component> &comp,
1814 const std::shared_ptr<Listener> &listener,
1815 size_t *seqPtr) {
1816 std::unique_lock lock(mMutex);
1817 size_t seq = mSeq++;
1818 if (!mMap.try_emplace(seq, comp, listener).second) {
1819 return false;
1820 }
1821 if (STATUS_OK != AIBinder_linkToDeath(
1822 comp->mAidlBase->asBinder().get(), mDeathRecipient.get(), (void *)seq)) {
1823 mMap.erase(seq);
1824 return false;
1825 }
1826 *seqPtr = seq;
1827 return true;
1828 }
1829
1830 void unlinkToDeath(size_t seq, const std::shared_ptr<AidlBase> &base) {
1831 std::unique_lock lock(mMutex);
1832 AIBinder_unlinkToDeath(base->asBinder().get(), mDeathRecipient.get(), (void *)seq);
1833 mMap.erase(seq);
1834 }
1835
1836private:
1837 std::mutex mMutex;
1838 size_t mSeq;
1839 typedef std::tuple<std::weak_ptr<Component>, std::weak_ptr<Listener>> Context;
1840 std::map<size_t, Context> mMap;
1841 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
1842
1843 bool extractContext(size_t seq, Context *context) {
1844 std::unique_lock lock(mMutex);
1845 auto node = mMap.extract(seq);
1846 if (!node) {
1847 return false;
1848 }
1849 *context = node.mapped();
1850 return true;
1851 }
1852
1853 static void OnBinderDied(void *cookie) {
1854 size_t seq = size_t(cookie);
1855 Context context;
1856 if (!Component::GetAidlDeathManager()->extractContext(seq, &context)) {
1857 return;
1858 }
1859 std::weak_ptr<Component> weakComponent;
1860 std::weak_ptr<Listener> weakListener;
1861 std::tie(weakComponent, weakListener) = context;
1862 if (std::shared_ptr<Listener> listener = weakListener.lock()) {
1863 listener->onDeath(weakComponent);
1864 } else {
1865 LOG(DEBUG) << "onDeath -- listener died.";
1866 }
1867 }
1868};
1869
1870Codec2Client::Component::Component(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001871 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001872 [base]() -> sp<c2_hidl::IConfigurable> {
1873 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001874 base->getInterface();
1875 if (!transResult1.isOk()) {
1876 return nullptr;
1877 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001878 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1879 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001880 getConfigurable();
1881 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001882 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001883 nullptr;
1884 }()
1885 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001886 mHidlBase1_0{base},
1887 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1888 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1889 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001890 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1891}
1892
Wonsik Kime8e98152022-12-16 16:04:17 -08001893Codec2Client::Component::Component(const sp<HidlBase1_1>& base)
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001894 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001895 [base]() -> sp<c2_hidl::IConfigurable> {
1896 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001897 base->getInterface();
1898 if (!transResult1.isOk()) {
1899 return nullptr;
1900 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001901 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1902 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001903 getConfigurable();
1904 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001905 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001906 nullptr;
1907 }()
1908 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001909 mHidlBase1_0{base},
1910 mHidlBase1_1{base},
1911 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1912 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Sungtak Lee8577dab2021-03-12 02:25:50 -08001913 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1914}
1915
Wonsik Kime8e98152022-12-16 16:04:17 -08001916Codec2Client::Component::Component(const sp<HidlBase1_2>& base)
Sungtak Lee8577dab2021-03-12 02:25:50 -08001917 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001918 [base]() -> sp<c2_hidl::IConfigurable> {
1919 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Sungtak Lee8577dab2021-03-12 02:25:50 -08001920 base->getInterface();
1921 if (!transResult1.isOk()) {
1922 return nullptr;
1923 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001924 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1925 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Sungtak Lee8577dab2021-03-12 02:25:50 -08001926 getConfigurable();
1927 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001928 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Sungtak Lee8577dab2021-03-12 02:25:50 -08001929 nullptr;
1930 }()
1931 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001932 mHidlBase1_0{base},
1933 mHidlBase1_1{base},
1934 mHidlBase1_2{base},
1935 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
1936 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1937}
1938
1939Codec2Client::Component::Component(const std::shared_ptr<AidlBase> &base)
1940 : Configurable{
1941 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1942 std::shared_ptr<c2_aidl::IComponentInterface> aidlIntf;
1943 ::ndk::ScopedAStatus transStatus = base->getInterface(&aidlIntf);
1944 if (!transStatus.isOk()) {
1945 return nullptr;
1946 }
1947 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1948 transStatus = aidlIntf->getConfigurable(&aidlConfigurable);
1949 return transStatus.isOk() ? aidlConfigurable : nullptr;
1950 }()
1951 },
1952 mAidlBase{base},
1953 mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001954 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001955}
1956
1957Codec2Client::Component::~Component() {
Wonsik Kime8e98152022-12-16 16:04:17 -08001958 if (mAidlDeathSeq) {
1959 GetAidlDeathManager()->unlinkToDeath(*mAidlDeathSeq, mAidlBase);
1960 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001961}
1962
1963c2_status_t Codec2Client::Component::createBlockPool(
1964 C2Allocator::id_t id,
1965 C2BlockPool::local_id_t* blockPoolId,
1966 std::shared_ptr<Codec2Client::Configurable>* configurable) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001967 if (mAidlBase) {
1968 c2_aidl::IComponent::BlockPool aidlBlockPool;
Ryan Prichard8d37bb02023-09-13 20:23:15 -07001969 ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id),
1970 &aidlBlockPool);
Wonsik Kime8e98152022-12-16 16:04:17 -08001971 c2_status_t status = GetC2Status(transStatus, "createBlockPool");
1972 if (status != C2_OK) {
1973 return status;
1974 }
1975 *blockPoolId = aidlBlockPool.blockPoolId;
1976 *configurable = std::make_shared<Configurable>(aidlBlockPool.configurable);
1977 return C2_OK;
1978 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001979 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001980 Return<void> transStatus = mHidlBase1_0->createBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001981 static_cast<uint32_t>(id),
1982 [&status, blockPoolId, configurable](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001983 c2_hidl::Status s,
Pawin Vongmasa36653902018-11-15 00:10:25 -08001984 uint64_t pId,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001985 const sp<c2_hidl::IConfigurable>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001986 status = static_cast<c2_status_t>(s);
1987 configurable->reset();
1988 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001989 LOG(DEBUG) << "createBlockPool -- call failed: "
1990 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001991 return;
1992 }
1993 *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001994 *configurable = std::make_shared<Configurable>(c);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001995 });
1996 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001997 LOG(ERROR) << "createBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001998 return C2_TRANSACTION_FAILED;
1999 }
2000 return status;
2001}
2002
2003c2_status_t Codec2Client::Component::destroyBlockPool(
2004 C2BlockPool::local_id_t localId) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002005 if (mAidlBase) {
2006 ::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId);
2007 return GetC2Status(transStatus, "destroyBlockPool");
2008 }
2009 Return<c2_hidl::Status> transResult = mHidlBase1_0->destroyBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002010 static_cast<uint64_t>(localId));
2011 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002012 LOG(ERROR) << "destroyBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002013 return C2_TRANSACTION_FAILED;
2014 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002015 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002016}
2017
Wonsik Kimab34ed62019-01-31 15:28:46 -08002018void Codec2Client::Component::handleOnWorkDone(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002019 const std::list<std::unique_ptr<C2Work>> &workItems) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002020 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002021 mOutputBufferQueue->holdBufferQueueBlocks(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002022}
2023
2024c2_status_t Codec2Client::Component::queue(
2025 std::list<std::unique_ptr<C2Work>>* const items) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002026 if (mAidlBase) {
2027 c2_aidl::WorkBundle workBundle;
2028 if (!c2_aidl::utils::ToAidl(&workBundle, *items, mAidlBufferPoolSender.get())) {
2029 LOG(ERROR) << "queue -- bad input.";
2030 return C2_TRANSACTION_FAILED;
2031 }
2032 ::ndk::ScopedAStatus transStatus = mAidlBase->queue(workBundle);
2033 return GetC2Status(transStatus, "queue");
2034 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002035 c2_hidl::WorkBundle workBundle;
Wonsik Kime8e98152022-12-16 16:04:17 -08002036 if (!c2_hidl::utils::objcpy(&workBundle, *items, mHidlBufferPoolSender.get())) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002037 LOG(ERROR) << "queue -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002038 return C2_TRANSACTION_FAILED;
2039 }
Wonsik Kime8e98152022-12-16 16:04:17 -08002040 Return<c2_hidl::Status> transStatus = mHidlBase1_0->queue(workBundle);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002041 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002042 LOG(ERROR) << "queue -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002043 return C2_TRANSACTION_FAILED;
2044 }
2045 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002046 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002047 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002048 LOG(DEBUG) << "queue -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002049 }
2050 return status;
2051}
2052
2053c2_status_t Codec2Client::Component::flush(
2054 C2Component::flush_mode_t mode,
2055 std::list<std::unique_ptr<C2Work>>* const flushedWork) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002056 (void)mode; // Flush mode isn't supported in HIDL/AIDL yet.
2057 c2_status_t status = C2_OK;
2058 if (mAidlBase) {
2059 c2_aidl::WorkBundle workBundle;
2060 ::ndk::ScopedAStatus transStatus = mAidlBase->flush(&workBundle);
2061 c2_status_t status = GetC2Status(transStatus, "flush");
2062 if (status != C2_OK) {
2063 return status;
2064 }
2065 if (!c2_aidl::utils::FromAidl(flushedWork, workBundle)) {
2066 LOG(DEBUG) << "flush -- flushedWork corrupted.";
2067 return C2_CORRUPTED;
2068 }
2069 } else {
2070 Return<void> transStatus = mHidlBase1_0->flush(
2071 [&status, flushedWork](
2072 c2_hidl::Status s, const c2_hidl::WorkBundle& wb) {
2073 status = static_cast<c2_status_t>(s);
2074 if (status != C2_OK) {
2075 LOG(DEBUG) << "flush -- call failed: " << status << ".";
2076 return;
2077 }
2078 if (!c2_hidl::utils::objcpy(flushedWork, wb)) {
2079 status = C2_CORRUPTED;
2080 } else {
2081 status = C2_OK;
2082 }
2083 });
2084 if (!transStatus.isOk()) {
2085 LOG(ERROR) << "flush -- transaction failed.";
2086 return C2_TRANSACTION_FAILED;
2087 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002088 }
2089
2090 // Indices of flushed work items.
2091 std::vector<uint64_t> flushedIndices;
2092 for (const std::unique_ptr<C2Work> &work : *flushedWork) {
2093 if (work) {
2094 if (work->worklets.empty()
2095 || !work->worklets.back()
2096 || (work->worklets.back()->output.flags &
2097 C2FrameData::FLAG_INCOMPLETE) == 0) {
2098 // input is complete
2099 flushedIndices.emplace_back(
2100 work->input.ordinal.frameIndex.peeku());
2101 }
2102 }
2103 }
2104
Pawin Vongmasa36653902018-11-15 00:10:25 -08002105 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002106 mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002107
2108 return status;
2109}
2110
2111c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002112 if (mAidlBase) {
2113 ::ndk::ScopedAStatus transStatus = mAidlBase->drain(
2114 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2115 return GetC2Status(transStatus, "drain");
2116 }
2117 Return<c2_hidl::Status> transStatus = mHidlBase1_0->drain(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002118 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2119 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002120 LOG(ERROR) << "drain -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002121 return C2_TRANSACTION_FAILED;
2122 }
2123 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002124 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002125 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002126 LOG(DEBUG) << "drain -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002127 }
2128 return status;
2129}
2130
2131c2_status_t Codec2Client::Component::start() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002132 if (mAidlBase) {
2133 ::ndk::ScopedAStatus transStatus = mAidlBase->start();
2134 return GetC2Status(transStatus, "start");
2135 }
2136 Return<c2_hidl::Status> transStatus = mHidlBase1_0->start();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002137 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002138 LOG(ERROR) << "start -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002139 return C2_TRANSACTION_FAILED;
2140 }
2141 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002142 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002143 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002144 LOG(DEBUG) << "start -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002145 }
2146 return status;
2147}
2148
2149c2_status_t Codec2Client::Component::stop() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002150 if (mAidlBase) {
2151 ::ndk::ScopedAStatus transStatus = mAidlBase->stop();
2152 return GetC2Status(transStatus, "stop");
2153 }
2154 Return<c2_hidl::Status> transStatus = mHidlBase1_0->stop();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002155 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002156 LOG(ERROR) << "stop -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002157 return C2_TRANSACTION_FAILED;
2158 }
2159 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002160 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002161 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002162 LOG(DEBUG) << "stop -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002163 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002164 return status;
2165}
2166
2167c2_status_t Codec2Client::Component::reset() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002168 if (mAidlBase) {
2169 ::ndk::ScopedAStatus transStatus = mAidlBase->reset();
2170 return GetC2Status(transStatus, "reset");
2171 }
2172 Return<c2_hidl::Status> transStatus = mHidlBase1_0->reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002173 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002174 LOG(ERROR) << "reset -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002175 return C2_TRANSACTION_FAILED;
2176 }
2177 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002178 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002179 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002180 LOG(DEBUG) << "reset -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002181 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002182 return status;
2183}
2184
2185c2_status_t Codec2Client::Component::release() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002186 if (mAidlBase) {
2187 ::ndk::ScopedAStatus transStatus = mAidlBase->release();
2188 return GetC2Status(transStatus, "release");
2189 }
2190 Return<c2_hidl::Status> transStatus = mHidlBase1_0->release();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002191 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002192 LOG(ERROR) << "release -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002193 return C2_TRANSACTION_FAILED;
2194 }
2195 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002196 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002197 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002198 LOG(DEBUG) << "release -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002199 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002200 return status;
2201}
2202
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002203c2_status_t Codec2Client::Component::configureVideoTunnel(
2204 uint32_t avSyncHwId,
2205 native_handle_t** sidebandHandle) {
2206 *sidebandHandle = nullptr;
Wonsik Kime8e98152022-12-16 16:04:17 -08002207 if (mAidlBase) {
2208 ::aidl::android::hardware::common::NativeHandle handle;
2209 ::ndk::ScopedAStatus transStatus = mAidlBase->configureVideoTunnel(avSyncHwId, &handle);
2210 c2_status_t status = GetC2Status(transStatus, "configureVideoTunnel");
2211 if (status != C2_OK) {
2212 return status;
2213 }
2214 if (isAidlNativeHandleEmpty(handle)) {
2215 LOG(DEBUG) << "configureVideoTunnel -- empty handle returned";
2216 } else {
2217 *sidebandHandle = dupFromAidl(handle);
2218 }
2219 return C2_OK;
2220 }
2221 if (!mHidlBase1_1) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002222 return C2_OMITTED;
2223 }
2224 c2_status_t status{};
Wonsik Kime8e98152022-12-16 16:04:17 -08002225 Return<void> transStatus = mHidlBase1_1->configureVideoTunnel(avSyncHwId,
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002226 [&status, sidebandHandle](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002227 c2_hidl::Status s, hardware::hidl_handle const& h) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002228 status = static_cast<c2_status_t>(s);
2229 if (h.getNativeHandle()) {
2230 *sidebandHandle = native_handle_clone(h.getNativeHandle());
2231 }
2232 });
2233 if (!transStatus.isOk()) {
2234 LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
2235 return C2_TRANSACTION_FAILED;
2236 }
2237 return status;
2238}
2239
Pawin Vongmasa36653902018-11-15 00:10:25 -08002240c2_status_t Codec2Client::Component::setOutputSurface(
2241 C2BlockPool::local_id_t blockPoolId,
2242 const sp<IGraphicBufferProducer>& surface,
Sungtak Leedb14cba2021-04-10 00:50:23 -07002243 uint32_t generation,
2244 int maxDequeueCount) {
Sungtak Lee08515812019-06-05 11:16:32 -07002245 uint64_t bqId = 0;
2246 sp<IGraphicBufferProducer> nullIgbp;
2247 sp<HGraphicBufferProducer2> nullHgbp;
Pawin Vongmasa3866c7e2019-01-31 05:21:29 -08002248
Sungtak Lee08515812019-06-05 11:16:32 -07002249 sp<HGraphicBufferProducer2> igbp = surface ?
2250 surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp;
2251 if (surface && !igbp) {
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002252 igbp = new B2HGraphicBufferProducer2(surface);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002253 }
2254
Sungtak Leefb579022022-05-10 06:36:15 +00002255 std::scoped_lock lock(mOutputMutex);
Sungtak Leea714f112021-03-16 05:40:03 -07002256 std::shared_ptr<SurfaceSyncObj> syncObj;
2257
Sungtak Lee08515812019-06-05 11:16:32 -07002258 if (!surface) {
Sungtak Leedb14cba2021-04-10 00:50:23 -07002259 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002260 } else if (surface->getUniqueId(&bqId) != OK) {
2261 LOG(ERROR) << "setOutputSurface -- "
2262 "cannot obtain bufferqueue id.";
2263 bqId = 0;
Sungtak Leedb14cba2021-04-10 00:50:23 -07002264 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002265 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08002266 mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount,
2267 mHidlBase1_2 ? &syncObj : nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002268 }
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002269
2270 // set consumer bits
2271 // TODO: should this get incorporated into setOutputSurface method so that consumer bits
2272 // can be set atomically?
2273 uint64_t consumerUsage = kDefaultConsumerUsage;
2274 {
2275 if (surface) {
Sungtak Lee46a69d62023-08-12 07:24:24 +00002276 uint64_t usage = 0;
2277 status_t err = surface->getConsumerUsage(&usage);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002278 if (err != NO_ERROR) {
2279 ALOGD("setOutputSurface -- failed to get consumer usage bits (%d/%s). ignoring",
2280 err, asString(err));
2281 } else {
2282 // Note: we are adding the default usage because components must support
2283 // producing output frames that can be displayed an all output surfaces.
2284
2285 // TODO: do not set usage for tunneled scenario. It is unclear if consumer usage
2286 // is meaningful in a tunneled scenario; on one hand output buffers exist, but
2287 // they do not exist inside of C2 scope. Any buffer usage shall be communicated
2288 // through the sideband channel.
2289
Sungtak Lee46a69d62023-08-12 07:24:24 +00002290 consumerUsage = usage | kDefaultConsumerUsage;
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002291 }
2292 }
2293
2294 C2StreamUsageTuning::output outputUsage{
2295 0u, C2AndroidMemoryUsage::FromGrallocUsage(consumerUsage).expected};
2296 std::vector<std::unique_ptr<C2SettingResult>> failures;
2297 c2_status_t err = config({&outputUsage}, C2_MAY_BLOCK, &failures);
2298 if (err != C2_OK) {
2299 ALOGD("setOutputSurface -- failed to set consumer usage (%d/%s)",
2300 err, asString(err));
2301 }
2302 }
2303 ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
2304 generation, (long long)consumerUsage, syncObj ? " sync" : "");
Sungtak Lee08515812019-06-05 11:16:32 -07002305
Wonsik Kime8e98152022-12-16 16:04:17 -08002306 if (mAidlBase) {
2307 // FIXME
2308 return C2_OMITTED;
2309 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002310 Return<c2_hidl::Status> transStatus = syncObj ?
Wonsik Kime8e98152022-12-16 16:04:17 -08002311 mHidlBase1_2->setOutputSurfaceWithSyncObj(
Sungtak Leea714f112021-03-16 05:40:03 -07002312 static_cast<uint64_t>(blockPoolId),
2313 bqId == 0 ? nullHgbp : igbp, *syncObj) :
Wonsik Kime8e98152022-12-16 16:04:17 -08002314 mHidlBase1_0->setOutputSurface(
Sungtak Leea714f112021-03-16 05:40:03 -07002315 static_cast<uint64_t>(blockPoolId),
2316 bqId == 0 ? nullHgbp : igbp);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002317
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002318 mOutputBufferQueue->expireOldWaiters();
2319
Pawin Vongmasa36653902018-11-15 00:10:25 -08002320 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002321 LOG(ERROR) << "setOutputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002322 return C2_TRANSACTION_FAILED;
2323 }
2324 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002325 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002326 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002327 LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002328 }
Sungtak Leea714f112021-03-16 05:40:03 -07002329 ALOGD("Surface configure completed");
Pawin Vongmasa36653902018-11-15 00:10:25 -08002330 return status;
2331}
2332
2333status_t Codec2Client::Component::queueToOutputSurface(
2334 const C2ConstGraphicBlock& block,
2335 const QueueBufferInput& input,
2336 QueueBufferOutput* output) {
Arun Johnson7ba67072023-11-06 22:23:04 +00002337 ScopedTrace trace(ATRACE_TAG,"Codec2Client::Component::queueToOutputSurface");
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002338 return mOutputBufferQueue->outputBuffer(block, input, output);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002339}
2340
Brian Lindahlc953b462023-01-27 16:21:43 -07002341void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
2342 mOutputBufferQueue->pollForRenderedFrames(delta);
2343}
2344
Sungtak Leea714f112021-03-16 05:40:03 -07002345void Codec2Client::Component::setOutputSurfaceMaxDequeueCount(
2346 int maxDequeueCount) {
2347 mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount);
2348}
2349
Sungtak Leec7da7a02022-05-05 08:45:33 +00002350void Codec2Client::Component::stopUsingOutputSurface(
2351 C2BlockPool::local_id_t blockPoolId) {
Sungtak Leefb579022022-05-10 06:36:15 +00002352 std::scoped_lock lock(mOutputMutex);
Sungtak Leec7da7a02022-05-05 08:45:33 +00002353 mOutputBufferQueue->stop();
Wonsik Kime8e98152022-12-16 16:04:17 -08002354 if (mAidlBase) {
2355 // FIXME
2356 return;
2357 }
2358 Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface(
Sungtak Leec7da7a02022-05-05 08:45:33 +00002359 static_cast<uint64_t>(blockPoolId), nullptr);
2360 if (!transStatus.isOk()) {
2361 LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed.";
2362 } else {
2363 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002364 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Sungtak Leec7da7a02022-05-05 08:45:33 +00002365 if (status != C2_OK) {
2366 LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: "
2367 << status << ".";
2368 }
2369 }
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002370 mOutputBufferQueue->expireOldWaiters();
Sungtak Leec7da7a02022-05-05 08:45:33 +00002371}
2372
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002373c2_status_t Codec2Client::Component::connectToInputSurface(
2374 const std::shared_ptr<InputSurface>& inputSurface,
2375 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002376 if (mAidlBase) {
2377 // FIXME
2378 return C2_OMITTED;
2379 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002380 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002381 Return<void> transStatus = mHidlBase1_0->connectToInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002382 inputSurface->mBase,
2383 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002384 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002385 status = static_cast<c2_status_t>(s);
2386 if (status != C2_OK) {
2387 LOG(DEBUG) << "connectToInputSurface -- call failed: "
2388 << status << ".";
2389 return;
2390 }
2391 *connection = std::make_shared<InputSurfaceConnection>(c);
2392 });
Pawin Vongmasa36653902018-11-15 00:10:25 -08002393 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002394 LOG(ERROR) << "connectToInputSurface -- transaction failed";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002395 return C2_TRANSACTION_FAILED;
2396 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002397 return status;
2398}
2399
2400c2_status_t Codec2Client::Component::connectToOmxInputSurface(
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002401 const sp<HGraphicBufferProducer1>& producer,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002402 const sp<HGraphicBufferSource>& source,
2403 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002404 if (mAidlBase) {
2405 LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL";
2406 return C2_OMITTED;
2407 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002408 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002409 Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002410 producer, source,
2411 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002412 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002413 status = static_cast<c2_status_t>(s);
2414 if (status != C2_OK) {
2415 LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
2416 << status << ".";
2417 return;
2418 }
2419 *connection = std::make_shared<InputSurfaceConnection>(c);
2420 });
2421 if (!transStatus.isOk()) {
2422 LOG(ERROR) << "connectToOmxInputSurface -- transaction failed.";
2423 return C2_TRANSACTION_FAILED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08002424 }
2425 return status;
2426}
2427
2428c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002429 if (mAidlBase) {
2430 // FIXME
2431 return C2_OMITTED;
2432 }
2433 Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002434 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002435 LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002436 return C2_TRANSACTION_FAILED;
2437 }
2438 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002439 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002440 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002441 LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
2442 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002443 }
2444 return status;
2445}
2446
Wonsik Kime8e98152022-12-16 16:04:17 -08002447Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() {
2448 // This object never gets destructed
2449 static AidlDeathManager *sManager = new AidlDeathManager();
2450 return sManager;
2451}
2452
Pawin Vongmasa36653902018-11-15 00:10:25 -08002453c2_status_t Codec2Client::Component::setDeathListener(
2454 const std::shared_ptr<Component>& component,
2455 const std::shared_ptr<Listener>& listener) {
2456
2457 struct HidlDeathRecipient : public hardware::hidl_death_recipient {
2458 std::weak_ptr<Component> component;
2459 std::weak_ptr<Listener> base;
2460
2461 virtual void serviceDied(
2462 uint64_t /* cookie */,
2463 const wp<::android::hidl::base::V1_0::IBase>& /* who */
2464 ) override {
2465 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
2466 listener->onDeath(component);
2467 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002468 LOG(DEBUG) << "onDeath -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002469 }
2470 }
2471 };
2472
Wonsik Kime8e98152022-12-16 16:04:17 -08002473 if (component->mAidlBase) {
2474 size_t seq;
2475 if (GetAidlDeathManager()->linkToDeath(component, listener, &seq)) {
2476 component->mAidlDeathSeq = seq;
2477 }
2478 return C2_OK;
2479 }
2480
Pawin Vongmasa36653902018-11-15 00:10:25 -08002481 sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient();
2482 deathRecipient->base = listener;
2483 deathRecipient->component = component;
2484
2485 component->mDeathRecipient = deathRecipient;
Wonsik Kime8e98152022-12-16 16:04:17 -08002486 Return<bool> transResult = component->mHidlBase1_0->linkToDeath(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002487 component->mDeathRecipient, 0);
2488 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002489 LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002490 return C2_TRANSACTION_FAILED;
2491 }
2492 if (!static_cast<bool>(transResult)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002493 LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002494 return C2_CORRUPTED;
2495 }
2496 return C2_OK;
2497}
2498
2499// Codec2Client::InputSurface
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002500Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002501 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002502 [base]() -> sp<c2_hidl::IConfigurable> {
2503 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002504 base->getConfigurable();
2505 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002506 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002507 nullptr;
2508 }()
2509 },
2510 mBase{base},
2511 mGraphicBufferProducer{new
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002512 H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> {
2513 Return<sp<HGraphicBufferProducer2>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002514 base->getGraphicBufferProducer();
2515 return transResult.isOk() ?
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002516 static_cast<sp<HGraphicBufferProducer2>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002517 nullptr;
2518 }())} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002519}
2520
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002521sp<IGraphicBufferProducer>
Pawin Vongmasa36653902018-11-15 00:10:25 -08002522 Codec2Client::InputSurface::getGraphicBufferProducer() const {
2523 return mGraphicBufferProducer;
2524}
2525
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002526sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002527 return mBase;
2528}
2529
2530// Codec2Client::InputSurfaceConnection
Pawin Vongmasa36653902018-11-15 00:10:25 -08002531Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002532 const sp<c2_hidl::IInputSurfaceConnection>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002533 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002534 [base]() -> sp<c2_hidl::IConfigurable> {
2535 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002536 base->getConfigurable();
2537 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002538 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002539 nullptr;
2540 }()
2541 },
2542 mBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002543}
2544
2545c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002546 Return<c2_hidl::Status> transResult = mBase->disconnect();
2547 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002548}
2549
2550} // namespace android