blob: 1e9aa7f631e0a40df7bfc77a0be6f812dc63f979 [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>
49#include <android/binder_auto_utils.h>
50#include <android/binder_ibinder.h>
51#include <android/binder_manager.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070052#include <android-base/properties.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080053#include <android-base/stringprintf.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070054#include <bufferpool/ClientManager.h>
Wonsik Kime8e98152022-12-16 16:04:17 -080055#include <bufferpool2/ClientManager.h>
56#include <codec2/aidl/BufferTypes.h>
Wonsik Kim1caded02022-12-09 13:03:11 -080057#include <codec2/aidl/ParamTypes.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070058#include <codec2/hidl/1.0/types.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070059#include <codec2/hidl/1.1/types.h>
Sungtak Lee8577dab2021-03-12 02:25:50 -080060#include <codec2/hidl/1.2/types.h>
Sungtak Leea714f112021-03-16 05:40:03 -070061#include <codec2/hidl/output.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070062
63#include <cutils/native_handle.h>
64#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
65#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080066#include <hardware/gralloc.h> // for GRALLOC_USAGE_*
Pawin Vongmasabf69de92019-10-29 06:21:27 -070067#include <hidl/HidlSupport.h>
Lajos Molnar78aa7c92021-02-18 21:39:01 -080068#include <system/window.h> // for NATIVE_WINDOW_QUERY_*
69#include <media/stagefright/foundation/ADebug.h> // for asString(status_t)
Pawin Vongmasa36653902018-11-15 00:10:25 -080070
71#include <deque>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070072#include <iterator>
Pawin Vongmasa36653902018-11-15 00:10:25 -080073#include <limits>
74#include <map>
Pawin Vongmasa892c81d2019-03-12 00:56:50 -070075#include <mutex>
76#include <sstream>
77#include <thread>
Pawin Vongmasa36653902018-11-15 00:10:25 -080078#include <type_traits>
79#include <vector>
80
Pawin Vongmasa36653902018-11-15 00:10:25 -080081namespace android {
82
83using ::android::hardware::hidl_vec;
84using ::android::hardware::hidl_string;
85using ::android::hardware::Return;
86using ::android::hardware::Void;
Pawin Vongmasa36653902018-11-15 00:10:25 -080087
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080088using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
89 V1_0::IGraphicBufferProducer;
90using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
91 V2_0::IGraphicBufferProducer;
92using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
93 V2_0::utils::B2HGraphicBufferProducer;
94using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
95 V2_0::utils::H2BGraphicBufferProducer;
Sungtak Leea714f112021-03-16 05:40:03 -070096using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
Pawin Vongmasaef939bf2019-03-03 04:44:59 -080097
Wonsik Kime8e98152022-12-16 16:04:17 -080098namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -080099namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
100namespace c2_aidl = ::aidl::android::hardware::media::c2;
101namespace c2_hidl_base = ::android::hardware::media::c2;
102namespace c2_hidl = ::android::hardware::media::c2::V1_2;
103
104using c2_hidl::utils::operator<<;
105
Pawin Vongmasa36653902018-11-15 00:10:25 -0800106namespace /* unnamed */ {
107
108// c2_status_t value that corresponds to hwbinder transaction failure.
109constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
110
Lajos Molnar78aa7c92021-02-18 21:39:01 -0800111// By default prepare buffer to be displayed on any of the common surfaces
112constexpr uint64_t kDefaultConsumerUsage =
113 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER);
114
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700115// Searches for a name in GetServiceNames() and returns the index found. If the
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700116// name is not found, the returned index will be equal to
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700117// GetServiceNames().size().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700118size_t getServiceIndex(char const* name) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700119 std::vector<std::string> const& names = Codec2Client::GetServiceNames();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700120 size_t i = 0;
121 for (; i < names.size(); ++i) {
122 if (name == names[i]) {
123 break;
124 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800125 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700126 return i;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800127}
128
Pawin Vongmasa83d2c552020-03-05 04:36:08 -0800129class Client2Store : public C2ComponentStore {
130 std::shared_ptr<Codec2Client> mClient;
131
132public:
133 Client2Store(std::shared_ptr<Codec2Client> const& client)
134 : mClient(client) { }
135
136 virtual ~Client2Store() = default;
137
138 virtual c2_status_t config_sm(
139 std::vector<C2Param*> const &params,
140 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
141 return mClient->config(params, C2_MAY_BLOCK, failures);
142 };
143
144 virtual c2_status_t copyBuffer(
145 std::shared_ptr<C2GraphicBuffer>,
146 std::shared_ptr<C2GraphicBuffer>) {
147 return C2_OMITTED;
148 }
149
150 virtual c2_status_t createComponent(
151 C2String, std::shared_ptr<C2Component>* const component) {
152 component->reset();
153 return C2_OMITTED;
154 }
155
156 virtual c2_status_t createInterface(
157 C2String, std::shared_ptr<C2ComponentInterface>* const interface) {
158 interface->reset();
159 return C2_OMITTED;
160 }
161
162 virtual c2_status_t query_sm(
163 std::vector<C2Param*> const& stackParams,
164 std::vector<C2Param::Index> const& heapParamIndices,
165 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
166 return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
167 }
168
169 virtual c2_status_t querySupportedParams_nb(
170 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
171 return mClient->querySupportedParams(params);
172 }
173
174 virtual c2_status_t querySupportedValues_sm(
175 std::vector<C2FieldSupportedValuesQuery>& fields) const {
176 return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
177 }
178
179 virtual C2String getName() const {
180 return mClient->getName();
181 }
182
183 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
184 return mClient->getParamReflector();
185 }
186
187 virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() {
188 return std::vector<std::shared_ptr<C2Component::Traits const>>();
189 }
190};
191
Wonsik Kime8e98152022-12-16 16:04:17 -0800192c2_status_t GetC2Status(const ::ndk::ScopedAStatus &transStatus, const char *method) {
193 if (!transStatus.isOk()) {
194 if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
195 c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
196 LOG(DEBUG) << method << " -- call failed: " << status << ".";
197 return status;
198 } else {
199 LOG(ERROR) << method << " -- transaction failed.";
200 return C2_TRANSACTION_FAILED;
201 }
202 }
203 return C2_OK;
204}
205
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700206} // unnamed namespace
207
208// This class caches a Codec2Client object and its component traits. The client
209// will be created the first time it is needed, and it can be refreshed if the
210// service dies (by calling invalidate()). The first time listComponents() is
211// called from the client, the result will be cached.
212class Codec2Client::Cache {
213 // Cached client
214 std::shared_ptr<Codec2Client> mClient;
215 mutable std::mutex mClientMutex;
216
217 // Cached component traits
218 std::vector<C2Component::Traits> mTraits;
219 std::once_flag mTraitsInitializationFlag;
220
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700221 // The index of the service. This is based on GetServiceNames().
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700222 size_t mIndex;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700223 // Called by s() exactly once to initialize the cache. The index must be a
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700224 // valid index into the vector returned by GetServiceNames(). Calling
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700225 // init(index) will associate the cache to the service with name
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700226 // GetServiceNames()[index].
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700227 void init(size_t index) {
228 mIndex = index;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700229 }
230
231public:
232 Cache() = default;
233
234 // Initializes mClient if needed, then returns mClient.
235 // If the service is unavailable but listed in the manifest, this function
236 // will block indefinitely.
237 std::shared_ptr<Codec2Client> getClient() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700238 std::scoped_lock lock{mClientMutex};
239 if (!mClient) {
240 mClient = Codec2Client::_CreateFromIndex(mIndex);
241 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -0700242 CHECK(mClient) << "Failed to create Codec2Client to service \""
243 << GetServiceNames()[mIndex] << "\". (Index = "
244 << mIndex << ").";
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700245 return mClient;
246 }
247
248 // Causes a subsequent call to getClient() to create a new client. This
249 // function should be called after the service dies.
250 //
251 // Note: This function is called only by ForAllServices().
252 void invalidate() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700253 std::scoped_lock lock{mClientMutex};
254 mClient = nullptr;
255 }
256
257 // Returns a list of traits for components supported by the service. This
258 // list is cached.
259 std::vector<C2Component::Traits> const& getTraits() {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700260 std::call_once(mTraitsInitializationFlag, [this]() {
261 bool success{false};
262 // Spin until _listComponents() is successful.
263 while (true) {
264 std::shared_ptr<Codec2Client> client = getClient();
265 mTraits = client->_listComponents(&success);
266 if (success) {
267 break;
268 }
Pawin Vongmasa21617db2020-04-24 06:16:42 -0700269 invalidate();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700270 using namespace std::chrono_literals;
271 static constexpr auto kServiceRetryPeriod = 5s;
272 LOG(INFO) << "Failed to retrieve component traits from service "
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700273 "\"" << GetServiceNames()[mIndex] << "\". "
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700274 "Retrying...";
275 std::this_thread::sleep_for(kServiceRetryPeriod);
276 }
277 });
278 return mTraits;
279 }
280
281 // List() returns the list of all caches.
282 static std::vector<Cache>& List() {
283 static std::vector<Cache> sCaches{[]() {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -0700284 size_t numServices = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -0700285 std::vector<Cache> caches(numServices);
286 for (size_t i = 0; i < numServices; ++i) {
287 caches[i].init(i);
288 }
289 return caches;
290 }()};
291 return sCaches;
292 }
293};
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800294// Codec2ConfigurableClient::HidlImpl
Pawin Vongmasa36653902018-11-15 00:10:25 -0800295
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800296struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase {
297 typedef c2_hidl::IConfigurable Base;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800298
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800299 // base cannot be null.
300 explicit HidlImpl(const sp<Base>& base);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800301
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800302 const C2String& getName() const override {
303 return mName;
304 }
305
306 c2_status_t query(
307 const std::vector<C2Param*>& stackParams,
308 const std::vector<C2Param::Index> &heapParamIndices,
309 c2_blocking_t mayBlock,
310 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
311
312 c2_status_t config(
313 const std::vector<C2Param*> &params,
314 c2_blocking_t mayBlock,
315 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
316
317 c2_status_t querySupportedParams(
318 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
319 ) const override;
320
321 c2_status_t querySupportedValues(
322 std::vector<C2FieldSupportedValuesQuery>& fields,
323 c2_blocking_t mayBlock) const override;
324
325private:
326 sp<Base> mBase;
327 const C2String mName;
328};
329
330Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800331 : mBase{base},
332 mName{[base]() -> C2String {
333 C2String outName;
334 Return<void> transStatus = base->getName(
335 [&outName](const hidl_string& name) {
336 outName = name.c_str();
337 });
338 return transStatus.isOk() ? outName : "";
339 }()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800340}
341
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800342c2_status_t Codec2ConfigurableClient::HidlImpl::query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800343 const std::vector<C2Param*> &stackParams,
344 const std::vector<C2Param::Index> &heapParamIndices,
345 c2_blocking_t mayBlock,
346 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800347 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800348 stackParams.size() + heapParamIndices.size());
349 size_t numIndices = 0;
350 for (C2Param* const& stackParam : stackParams) {
351 if (!stackParam) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800352 LOG(WARNING) << "query -- null stack param encountered.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800353 continue;
354 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800355 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800356 }
357 size_t numStackIndices = numIndices;
358 for (const C2Param::Index& index : heapParamIndices) {
359 indices[numIndices++] =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800360 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800361 }
362 indices.resize(numIndices);
363 if (heapParams) {
364 heapParams->reserve(heapParams->size() + numIndices);
365 }
366 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800367 Return<void> transStatus = mBase->query(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800368 indices,
369 mayBlock == C2_MAY_BLOCK,
370 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800371 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800372 status = static_cast<c2_status_t>(s);
373 if (status != C2_OK && status != C2_BAD_INDEX) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800374 LOG(DEBUG) << "query -- call failed: "
375 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800376 return;
377 }
378 std::vector<C2Param*> paramPointers;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800379 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800380 LOG(ERROR) << "query -- error while parsing params.";
381 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800382 return;
383 }
384 size_t i = 0;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800385 for (auto it = paramPointers.begin();
386 it != paramPointers.end(); ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800387 C2Param* paramPointer = *it;
388 if (numStackIndices > 0) {
389 --numStackIndices;
390 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800391 LOG(WARNING) << "query -- null stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800392 ++it;
393 continue;
394 }
395 for (; i < stackParams.size() && !stackParams[i]; ) {
396 ++i;
397 }
398 if (i >= stackParams.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800399 LOG(ERROR) << "query -- unexpected error.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800400 status = C2_CORRUPTED;
401 return;
402 }
403 if (stackParams[i]->index() != paramPointer->index()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800404 LOG(WARNING) << "query -- param skipped: "
405 "index = "
406 << stackParams[i]->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800407 stackParams[i++]->invalidate();
408 continue;
409 }
410 if (!stackParams[i++]->updateFrom(*paramPointer)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800411 LOG(WARNING) << "query -- param update failed: "
412 "index = "
413 << paramPointer->index() << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800414 }
415 } else {
416 if (!paramPointer) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800417 LOG(WARNING) << "query -- null heap param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800418 ++it;
419 continue;
420 }
421 if (!heapParams) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800422 LOG(WARNING) << "query -- "
423 "unexpected extra stack param.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800424 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800425 heapParams->emplace_back(
426 C2Param::Copy(*paramPointer));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800427 }
428 }
429 ++it;
430 }
431 });
432 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800433 LOG(ERROR) << "query -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800434 return C2_TRANSACTION_FAILED;
435 }
436 return status;
437}
438
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800439c2_status_t Codec2ConfigurableClient::HidlImpl::config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800440 const std::vector<C2Param*> &params,
441 c2_blocking_t mayBlock,
442 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800443 c2_hidl::Params hidlParams;
444 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800445 LOG(ERROR) << "config -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800446 return C2_TRANSACTION_FAILED;
447 }
448 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800449 Return<void> transStatus = mBase->config(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800450 hidlParams,
451 mayBlock == C2_MAY_BLOCK,
452 [&status, &params, failures](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800453 c2_hidl::Status s,
454 const hidl_vec<c2_hidl::SettingResult> f,
455 const c2_hidl::Params& o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800456 status = static_cast<c2_status_t>(s);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800457 if (status != C2_OK && status != C2_BAD_INDEX) {
458 LOG(DEBUG) << "config -- call failed: "
459 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800460 }
461 size_t i = failures->size();
462 failures->resize(i + f.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800463 for (const c2_hidl::SettingResult& sf : f) {
464 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800465 LOG(ERROR) << "config -- "
466 << "invalid SettingResult returned.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800467 return;
468 }
469 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800470 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800471 LOG(ERROR) << "config -- "
472 << "failed to parse returned params.";
473 status = C2_CORRUPTED;
474 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800475 });
476 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800477 LOG(ERROR) << "config -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800478 return C2_TRANSACTION_FAILED;
479 }
480 return status;
481}
482
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800483c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800484 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
485 // TODO: Cache and query properly!
486 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800487 Return<void> transStatus = mBase->querySupportedParams(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800488 std::numeric_limits<uint32_t>::min(),
489 std::numeric_limits<uint32_t>::max(),
490 [&status, params](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800491 c2_hidl::Status s,
492 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800493 status = static_cast<c2_status_t>(s);
494 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800495 LOG(DEBUG) << "querySupportedParams -- call failed: "
496 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800497 return;
498 }
499 size_t i = params->size();
500 params->resize(i + p.size());
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800501 for (const c2_hidl::ParamDescriptor& sp : p) {
502 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800503 LOG(ERROR) << "querySupportedParams -- "
504 << "invalid returned ParamDescriptor.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800505 return;
506 }
507 }
508 });
509 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800510 LOG(ERROR) << "querySupportedParams -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800511 return C2_TRANSACTION_FAILED;
512 }
513 return status;
514}
515
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800516c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800517 std::vector<C2FieldSupportedValuesQuery>& fields,
518 c2_blocking_t mayBlock) const {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800519 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800520 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800521 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800522 LOG(ERROR) << "querySupportedValues -- bad input";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800523 return C2_TRANSACTION_FAILED;
524 }
525 }
526
527 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800528 Return<void> transStatus = mBase->querySupportedValues(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800529 inFields,
530 mayBlock == C2_MAY_BLOCK,
531 [&status, &inFields, &fields](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800532 c2_hidl::Status s,
533 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800534 status = static_cast<c2_status_t>(s);
535 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800536 LOG(DEBUG) << "querySupportedValues -- call failed: "
537 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800538 return;
539 }
540 if (r.size() != fields.size()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800541 LOG(ERROR) << "querySupportedValues -- "
542 "input and output lists "
543 "have different sizes.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800544 status = C2_CORRUPTED;
545 return;
546 }
547 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800548 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800549 LOG(ERROR) << "querySupportedValues -- "
550 "invalid returned value.";
551 status = C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800552 return;
553 }
554 }
555 });
556 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800557 LOG(ERROR) << "querySupportedValues -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800558 return C2_TRANSACTION_FAILED;
559 }
560 return status;
561}
562
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800563// Codec2ConfigurableClient::AidlImpl
564
565struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase {
566 typedef c2_aidl::IConfigurable Base;
567
568 // base cannot be null.
569 explicit AidlImpl(const std::shared_ptr<Base>& base);
570
571 const C2String& getName() const override {
572 return mName;
573 }
574
575 c2_status_t query(
576 const std::vector<C2Param*>& stackParams,
577 const std::vector<C2Param::Index> &heapParamIndices,
578 c2_blocking_t mayBlock,
579 std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
580
581 c2_status_t config(
582 const std::vector<C2Param*> &params,
583 c2_blocking_t mayBlock,
584 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
585
586 c2_status_t querySupportedParams(
587 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
588 ) const override;
589
590 c2_status_t querySupportedValues(
591 std::vector<C2FieldSupportedValuesQuery>& fields,
592 c2_blocking_t mayBlock) const override;
593
594private:
595 std::shared_ptr<Base> mBase;
596 const C2String mName;
597};
598
599Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base)
600 : mBase{base},
601 mName{[base]() -> C2String {
602 std::string outName;
603 ndk::ScopedAStatus status = base->getName(&outName);
604 return status.isOk() ? outName : "";
605 }()} {
606}
607
608c2_status_t Codec2ConfigurableClient::AidlImpl::query(
609 const std::vector<C2Param*> &stackParams,
610 const std::vector<C2Param::Index> &heapParamIndices,
611 c2_blocking_t mayBlock,
612 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800613 std::vector<int> indices(
614 stackParams.size() + heapParamIndices.size());
615 size_t numIndices = 0;
616 for (C2Param* const& stackParam : stackParams) {
617 if (!stackParam) {
618 LOG(WARNING) << "query -- null stack param encountered.";
619 continue;
620 }
621 indices[numIndices++] = int(stackParam->index());
622 }
623 size_t numStackIndices = numIndices;
624 for (const C2Param::Index& index : heapParamIndices) {
625 indices[numIndices++] = int(static_cast<uint32_t>(index));
626 }
627 indices.resize(numIndices);
628 if (heapParams) {
629 heapParams->reserve(heapParams->size() + numIndices);
630 }
631 c2_aidl::Params result;
632 ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800633 c2_status_t status = GetC2Status(transStatus, "query");
634 if (status != C2_OK) {
635 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800636 }
637
Wonsik Kim1caded02022-12-09 13:03:11 -0800638 std::vector<C2Param*> paramPointers;
639 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, result)) {
640 LOG(ERROR) << "query -- error while parsing params.";
641 return C2_CORRUPTED;
642 }
643 size_t i = 0;
644 for (auto it = paramPointers.begin();
645 it != paramPointers.end(); ) {
646 C2Param* paramPointer = *it;
647 if (numStackIndices > 0) {
648 --numStackIndices;
649 if (!paramPointer) {
650 LOG(DEBUG) << "query -- null stack param.";
651 ++it;
652 continue;
653 }
654 for (; i < stackParams.size() && !stackParams[i]; ) {
655 ++i;
656 }
657 if (i >= stackParams.size()) {
658 LOG(ERROR) << "query -- unexpected error.";
659 status = C2_CORRUPTED;
660 break;
661 }
662 if (stackParams[i]->index() != paramPointer->index()) {
663 LOG(DEBUG) << "query -- param skipped: "
664 "index = "
665 << stackParams[i]->index() << ".";
666 stackParams[i++]->invalidate();
667 // this means that the param could not be queried.
668 // signalling C2_BAD_INDEX to the client.
669 status = C2_BAD_INDEX;
670 continue;
671 }
672 if (!stackParams[i++]->updateFrom(*paramPointer)) {
673 LOG(WARNING) << "query -- param update failed: "
674 "index = "
675 << paramPointer->index() << ".";
676 }
677 } else {
678 if (!paramPointer) {
679 LOG(DEBUG) << "query -- null heap param.";
680 ++it;
681 continue;
682 }
683 if (!heapParams) {
684 LOG(WARNING) << "query -- "
685 "unexpected extra stack param.";
686 } else {
687 heapParams->emplace_back(C2Param::Copy(*paramPointer));
688 }
689 }
690 ++it;
691 }
692 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800693}
694
695c2_status_t Codec2ConfigurableClient::AidlImpl::config(
696 const std::vector<C2Param*> &params,
697 c2_blocking_t mayBlock,
698 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
Wonsik Kim1caded02022-12-09 13:03:11 -0800699 c2_aidl::Params aidlParams;
700 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
701 LOG(ERROR) << "config -- bad input.";
702 return C2_TRANSACTION_FAILED;
703 }
704 c2_aidl::IConfigurable::ConfigResult result;
705 ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800706 c2_status_t status = GetC2Status(transStatus, "config");
707 if (status != C2_OK) {
708 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800709 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800710 size_t i = failures->size();
711 failures->resize(i + result.failures.size());
712 for (const c2_aidl::SettingResult& sf : result.failures) {
713 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
714 LOG(ERROR) << "config -- invalid SettingResult returned.";
715 return C2_CORRUPTED;
716 }
717 }
718 if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) {
719 LOG(ERROR) << "config -- "
720 << "failed to parse returned params.";
721 status = C2_CORRUPTED;
722 }
723 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800724}
725
726c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams(
727 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800728 // TODO: Cache and query properly!
729 std::vector<c2_aidl::ParamDescriptor> result;
730 ndk::ScopedAStatus transStatus = mBase->querySupportedParams(
731 std::numeric_limits<uint32_t>::min(),
732 std::numeric_limits<uint32_t>::max(),
733 &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800734 c2_status_t status = GetC2Status(transStatus, "querySupportedParams");
735 if (status != C2_OK) {
736 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800737 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800738 size_t i = params->size();
739 params->resize(i + result.size());
740 for (const c2_aidl::ParamDescriptor& sp : result) {
741 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
742 LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor.";
743 return C2_CORRUPTED;
744 }
745 }
746 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800747}
748
749c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues(
750 std::vector<C2FieldSupportedValuesQuery>& fields,
751 c2_blocking_t mayBlock) const {
Wonsik Kim1caded02022-12-09 13:03:11 -0800752 std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size());
753 for (size_t i = 0; i < fields.size(); ++i) {
754 if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) {
755 LOG(ERROR) << "querySupportedValues -- bad input";
756 return C2_TRANSACTION_FAILED;
757 }
758 }
759
760 std::vector<c2_aidl::FieldSupportedValuesQueryResult> result;
761 ndk::ScopedAStatus transStatus = mBase->querySupportedValues(
762 inFields, (mayBlock == C2_MAY_BLOCK), &result);
Wonsik Kime8e98152022-12-16 16:04:17 -0800763 c2_status_t status = GetC2Status(transStatus, "querySupportedValues");
764 if (status != C2_OK) {
765 return status;
Wonsik Kim1caded02022-12-09 13:03:11 -0800766 }
Wonsik Kim1caded02022-12-09 13:03:11 -0800767 if (result.size() != fields.size()) {
768 LOG(ERROR) << "querySupportedValues -- "
769 "input and output lists "
770 "have different sizes.";
771 return C2_CORRUPTED;
772 }
773 for (size_t i = 0; i < fields.size(); ++i) {
774 if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) {
775 LOG(ERROR) << "querySupportedValues -- "
776 "invalid returned value.";
777 return C2_CORRUPTED;
778 }
779 }
780 return status;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800781}
782
783// Codec2ConfigurableClient
784
785Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase)
786 : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) {
787}
788
789Codec2ConfigurableClient::Codec2ConfigurableClient(
790 const std::shared_ptr<AidlBase> &aidlBase)
791 : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) {
792}
793
794const C2String& Codec2ConfigurableClient::getName() const {
795 return mImpl->getName();
796}
797
798c2_status_t Codec2ConfigurableClient::query(
799 const std::vector<C2Param*>& stackParams,
800 const std::vector<C2Param::Index> &heapParamIndices,
801 c2_blocking_t mayBlock,
802 std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
803 return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
804}
805
806c2_status_t Codec2ConfigurableClient::config(
807 const std::vector<C2Param*> &params,
808 c2_blocking_t mayBlock,
809 std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
810 return mImpl->config(params, mayBlock, failures);
811}
812
813c2_status_t Codec2ConfigurableClient::querySupportedParams(
814 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
815 return mImpl->querySupportedParams(params);
816}
817
818c2_status_t Codec2ConfigurableClient::querySupportedValues(
819 std::vector<C2FieldSupportedValuesQuery>& fields,
820 c2_blocking_t mayBlock) const {
821 return mImpl->querySupportedValues(fields, mayBlock);
822}
823
824
Pawin Vongmasa36653902018-11-15 00:10:25 -0800825// Codec2Client::Component::HidlListener
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800826struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800827 std::weak_ptr<Component> component;
828 std::weak_ptr<Listener> base;
829
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800830 virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800831 std::list<std::unique_ptr<C2Work>> workItems;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800832 if (!c2_hidl::utils::objcpy(&workItems, workBundle)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800833 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800834 return Void();
835 }
836 // release input buffers potentially held by the component from queue
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800837 std::shared_ptr<Codec2Client::Component> strongComponent =
838 component.lock();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800839 if (strongComponent) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800840 strongComponent->handleOnWorkDone(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800841 }
842 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
Wonsik Kimab34ed62019-01-31 15:28:46 -0800843 listener->onWorkDone(component, workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800844 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800845 LOG(DEBUG) << "onWorkDone -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800846 }
847 return Void();
848 }
849
850 virtual Return<void> onTripped(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800851 const hidl_vec<c2_hidl::SettingResult>& settingResults) override {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800852 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
853 settingResults.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800854 for (size_t i = 0; i < settingResults.size(); ++i) {
855 std::unique_ptr<C2SettingResult> c2SettingResult;
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800856 if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800857 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800858 return Void();
859 }
860 c2SettingResults[i] = std::move(c2SettingResult);
861 }
862 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
863 listener->onTripped(component, c2SettingResults);
864 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800865 LOG(DEBUG) << "onTripped -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800866 }
867 return Void();
868 }
869
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800870 virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800871 LOG(DEBUG) << "onError --"
872 << " status = " << s
873 << ", errorCode = " << errorCode
874 << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800875 if (std::shared_ptr<Listener> listener = base.lock()) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -0800876 listener->onError(component, s == c2_hidl::Status::OK ?
Pawin Vongmasa36653902018-11-15 00:10:25 -0800877 errorCode : static_cast<c2_status_t>(s));
878 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800879 LOG(DEBUG) << "onError -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -0800880 }
881 return Void();
882 }
883
884 virtual Return<void> onFramesRendered(
885 const hidl_vec<RenderedFrame>& renderedFrames) override {
886 std::shared_ptr<Listener> listener = base.lock();
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800887 if (!listener) {
888 LOG(DEBUG) << "onFramesRendered -- listener died.";
889 return Void();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800890 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800891 for (const RenderedFrame& renderedFrame : renderedFrames) {
892 listener->onFrameRendered(
893 renderedFrame.bufferQueueId,
894 renderedFrame.slotId,
895 renderedFrame.timestampNs);
896 }
897 return Void();
898 }
899
900 virtual Return<void> onInputBuffersReleased(
901 const hidl_vec<InputBuffer>& inputBuffers) override {
902 std::shared_ptr<Listener> listener = base.lock();
903 if (!listener) {
904 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
905 return Void();
906 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800907 for (const InputBuffer& inputBuffer : inputBuffers) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800908 LOG(VERBOSE) << "onInputBuffersReleased --"
909 " received death notification of"
910 " input buffer:"
911 " frameIndex = " << inputBuffer.frameIndex
912 << ", bufferIndex = " << inputBuffer.arrayIndex
913 << ".";
Wonsik Kimab34ed62019-01-31 15:28:46 -0800914 listener->onInputBufferDone(
915 inputBuffer.frameIndex, inputBuffer.arrayIndex);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800916 }
917 return Void();
918 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -0800919
Pawin Vongmasa36653902018-11-15 00:10:25 -0800920};
921
Wonsik Kime8e98152022-12-16 16:04:17 -0800922// Codec2Client::Component::AidlListener
923struct Codec2Client::Component::AidlListener : public c2_aidl::BnComponentListener {
924 std::weak_ptr<Component> component;
925 std::weak_ptr<Listener> base;
926
927 virtual ::ndk::ScopedAStatus onWorkDone(const c2_aidl::WorkBundle& workBundle) override {
928 std::list<std::unique_ptr<C2Work>> workItems;
929 if (!c2_aidl::utils::FromAidl(&workItems, workBundle)) {
930 LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
931 return ::ndk::ScopedAStatus::ok();
932 }
933 // release input buffers potentially held by the component from queue
934 std::shared_ptr<Codec2Client::Component> strongComponent =
935 component.lock();
936 if (strongComponent) {
937 strongComponent->handleOnWorkDone(workItems);
938 }
939 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
940 listener->onWorkDone(component, workItems);
941 } else {
942 LOG(DEBUG) << "onWorkDone -- listener died.";
943 }
944 return ::ndk::ScopedAStatus::ok();
945 }
946
947 virtual ::ndk::ScopedAStatus onTripped(
948 const std::vector<c2_aidl::SettingResult>& settingResults) override {
949 std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
950 settingResults.size());
951 for (size_t i = 0; i < settingResults.size(); ++i) {
952 std::unique_ptr<C2SettingResult> c2SettingResult;
953 if (!c2_aidl::utils::FromAidl(&c2SettingResult, settingResults[i])) {
954 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
955 return ::ndk::ScopedAStatus::ok();
956 }
957 c2SettingResults[i] = std::move(c2SettingResult);
958 }
959 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
960 listener->onTripped(component, c2SettingResults);
961 } else {
962 LOG(DEBUG) << "onTripped -- listener died.";
963 }
964 return ::ndk::ScopedAStatus::ok();
965 }
966
967 virtual ::ndk::ScopedAStatus onError(const c2_aidl::Status &s, int32_t errorCode) override {
968 LOG(DEBUG) << "onError --"
969 << " status = " << s.status
970 << ", errorCode = " << errorCode
971 << ".";
972 if (std::shared_ptr<Listener> listener = base.lock()) {
973 listener->onError(component, s.status == c2_aidl::Status::OK ?
974 errorCode : static_cast<c2_status_t>(s.status));
975 } else {
976 LOG(DEBUG) << "onError -- listener died.";
977 }
978 return ::ndk::ScopedAStatus::ok();
979 }
980
981 virtual ::ndk::ScopedAStatus onFramesRendered(
982 const std::vector<RenderedFrame>& renderedFrames) override {
983 std::shared_ptr<Listener> listener = base.lock();
984 if (!listener) {
985 LOG(DEBUG) << "onFramesRendered -- listener died.";
986 return ::ndk::ScopedAStatus::ok();
987 }
988 for (const RenderedFrame& renderedFrame : renderedFrames) {
989 listener->onFrameRendered(
990 renderedFrame.bufferQueueId,
991 renderedFrame.slotId,
992 renderedFrame.timestampNs);
993 }
994 return ::ndk::ScopedAStatus::ok();
995 }
996
997 virtual ::ndk::ScopedAStatus onInputBuffersReleased(
998 const std::vector<InputBuffer>& inputBuffers) override {
999 std::shared_ptr<Listener> listener = base.lock();
1000 if (!listener) {
1001 LOG(DEBUG) << "onInputBuffersReleased -- listener died.";
1002 return ::ndk::ScopedAStatus::ok();
1003 }
1004 for (const InputBuffer& inputBuffer : inputBuffers) {
1005 LOG(VERBOSE) << "onInputBuffersReleased --"
1006 " received death notification of"
1007 " input buffer:"
1008 " frameIndex = " << inputBuffer.frameIndex
1009 << ", bufferIndex = " << inputBuffer.arrayIndex
1010 << ".";
1011 listener->onInputBufferDone(
1012 inputBuffer.frameIndex, inputBuffer.arrayIndex);
1013 }
1014 return ::ndk::ScopedAStatus::ok();
1015 }
1016
1017};
1018
1019// Codec2Client::Component::HidlBufferPoolSender
1020struct Codec2Client::Component::HidlBufferPoolSender :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001021 hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
Wonsik Kime8e98152022-12-16 16:04:17 -08001022 HidlBufferPoolSender()
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001023 : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
1024 }
1025};
1026
Wonsik Kime8e98152022-12-16 16:04:17 -08001027// Codec2Client::Component::AidlBufferPoolSender
1028struct Codec2Client::Component::AidlBufferPoolSender :
1029 c2_aidl::utils::DefaultBufferPoolSender {
1030 AidlBufferPoolSender()
1031 : c2_aidl::utils::DefaultBufferPoolSender() {
1032 }
1033};
1034
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001035// Codec2Client::Component::OutputBufferQueue
1036struct Codec2Client::Component::OutputBufferQueue :
Sungtak Leea714f112021-03-16 05:40:03 -07001037 hardware::media::c2::OutputBufferQueue {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001038 OutputBufferQueue()
Sungtak Leea714f112021-03-16 05:40:03 -07001039 : hardware::media::c2::OutputBufferQueue() {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001040 }
1041};
1042
Pawin Vongmasa36653902018-11-15 00:10:25 -08001043// Codec2Client
Wonsik Kime8e98152022-12-16 16:04:17 -08001044Codec2Client::Codec2Client(sp<HidlBase> const& base,
Sungtak Leef4b39512023-05-10 07:17:22 +00001045 sp<c2_hidl::IConfigurable> const& configurable,
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001046 size_t serviceIndex)
Sungtak Leef4b39512023-05-10 07:17:22 +00001047 : Configurable{configurable},
Wonsik Kime8e98152022-12-16 16:04:17 -08001048 mHidlBase1_0{base},
1049 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1050 mHidlBase1_2{HidlBase1_2::castFrom(base)},
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001051 mServiceIndex{serviceIndex} {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001052 Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager();
Pawin Vongmasa36653902018-11-15 00:10:25 -08001053 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001054 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001055 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08001056 mHidlHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001057 }
1058}
1059
Wonsik Kime8e98152022-12-16 16:04:17 -08001060Codec2Client::Codec2Client(std::shared_ptr<AidlBase> const& base,
1061 std::shared_ptr<c2_aidl::IConfigurable> const& configurable,
1062 size_t serviceIndex)
1063 : Configurable{configurable},
1064 mAidlBase{base},
1065 mServiceIndex{serviceIndex} {
1066 ::ndk::ScopedAStatus transStatus = base->getPoolClientManager(&mAidlHostPoolManager);
1067 if (!transStatus.isOk()) {
1068 LOG(ERROR) << "getPoolClientManager -- transaction failed.";
1069 mAidlHostPoolManager.reset();
1070 }
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001071}
1072
Wonsik Kime8e98152022-12-16 16:04:17 -08001073sp<Codec2Client::HidlBase> const& Codec2Client::getHidlBase() const {
1074 return mHidlBase1_0;
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001075}
1076
Wonsik Kime8e98152022-12-16 16:04:17 -08001077sp<Codec2Client::HidlBase1_0> const& Codec2Client::getHidlBase1_0() const {
1078 return mHidlBase1_0;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001079}
1080
Wonsik Kime8e98152022-12-16 16:04:17 -08001081sp<Codec2Client::HidlBase1_1> const& Codec2Client::getHidlBase1_1() const {
1082 return mHidlBase1_1;
1083}
1084
1085sp<Codec2Client::HidlBase1_2> const& Codec2Client::getHidlBase1_2() const {
1086 return mHidlBase1_2;
1087}
1088
1089::ndk::SpAIBinder Codec2Client::getAidlBase() const {
1090 return mAidlBase ? mAidlBase->asBinder() : nullptr;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001091}
1092
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001093std::string const& Codec2Client::getServiceName() const {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001094 return GetServiceNames()[mServiceIndex];
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001095}
1096
Pawin Vongmasa36653902018-11-15 00:10:25 -08001097c2_status_t Codec2Client::createComponent(
1098 const C2String& name,
1099 const std::shared_ptr<Codec2Client::Listener>& listener,
1100 std::shared_ptr<Codec2Client::Component>* const component) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001101 if (mAidlBase) {
1102 std::shared_ptr<Component::AidlListener> aidlListener =
1103 Component::AidlListener::make<Component::AidlListener>();
1104 aidlListener->base = listener;
1105 std::shared_ptr<c2_aidl::IComponent> aidlComponent;
1106 ::ndk::ScopedAStatus transStatus = mAidlBase->createComponent(
1107 name,
1108 aidlListener,
1109 bufferpool2_aidl::implementation::ClientManager::getInstance(),
1110 &aidlComponent);
1111 c2_status_t status = GetC2Status(transStatus, "createComponent");
1112 if (status != C2_OK) {
1113 return status;
1114 } else if (!aidlComponent) {
1115 LOG(ERROR) << "createComponent(" << name.c_str()
1116 << ") -- null component.";
1117 return C2_CORRUPTED;
1118 }
1119 *component = std::make_shared<Codec2Client::Component>(aidlComponent);
1120 status = (*component)->setDeathListener((*component), listener);
1121 if (status != C2_OK) {
1122 LOG(ERROR) << "createComponent(" << name.c_str()
1123 << ") -- failed to set up death listener: "
1124 << status << ".";
1125 }
1126 (*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager);
1127 return status;
1128 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001129
Pawin Vongmasa36653902018-11-15 00:10:25 -08001130 c2_status_t status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001131 sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001132 hidlListener->base = listener;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001133 Return<void> transStatus;
Wonsik Kime8e98152022-12-16 16:04:17 -08001134 if (mHidlBase1_2) {
1135 transStatus = mHidlBase1_2->createComponent_1_2(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001136 name,
1137 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001138 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasa36653902018-11-15 00:10:25 -08001139 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001140 c2_hidl::Status s,
1141 const sp<c2_hidl::IComponent>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001142 status = static_cast<c2_status_t>(s);
1143 if (status != C2_OK) {
1144 return;
1145 }
1146 *component = std::make_shared<Codec2Client::Component>(c);
1147 hidlListener->component = *component;
Sungtak Lee8577dab2021-03-12 02:25:50 -08001148 });
1149 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001150 else if (mHidlBase1_1) {
1151 transStatus = mHidlBase1_1->createComponent_1_1(
Sungtak Lee8577dab2021-03-12 02:25:50 -08001152 name,
1153 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001154 bufferpool_hidl::implementation::ClientManager::getInstance(),
Sungtak Lee8577dab2021-03-12 02:25:50 -08001155 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001156 c2_hidl::Status s,
1157 const sp<c2_hidl_base::V1_1::IComponent>& c) {
Sungtak Lee8577dab2021-03-12 02:25:50 -08001158 status = static_cast<c2_status_t>(s);
1159 if (status != C2_OK) {
1160 return;
1161 }
1162 *component = std::make_shared<Codec2Client::Component>(c);
1163 hidlListener->component = *component;
1164 });
Wonsik Kime8e98152022-12-16 16:04:17 -08001165 } else if (mHidlBase1_0) { // ver1_0
1166 transStatus = mHidlBase1_0->createComponent(
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001167 name,
1168 hidlListener,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001169 bufferpool_hidl::implementation::ClientManager::getInstance(),
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001170 [&status, component, hidlListener](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001171 c2_hidl::Status s,
1172 const sp<c2_hidl_base::V1_0::IComponent>& c) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001173 status = static_cast<c2_status_t>(s);
1174 if (status != C2_OK) {
1175 return;
1176 }
1177 *component = std::make_shared<Codec2Client::Component>(c);
1178 hidlListener->component = *component;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001179 });
Sungtak Lee8577dab2021-03-12 02:25:50 -08001180 } else {
1181 status = C2_CORRUPTED;
1182 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001183 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001184 LOG(ERROR) << "createComponent(" << name.c_str()
1185 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001186 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001187 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001188 if (status == C2_NOT_FOUND) {
1189 LOG(VERBOSE) << "createComponent(" << name.c_str()
1190 << ") -- component not found.";
1191 } else {
1192 LOG(ERROR) << "createComponent(" << name.c_str()
1193 << ") -- call failed: " << status << ".";
1194 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001195 return status;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001196 } else if (!*component) {
1197 LOG(ERROR) << "createComponent(" << name.c_str()
1198 << ") -- null component.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001199 return C2_CORRUPTED;
1200 }
1201
1202 status = (*component)->setDeathListener(*component, listener);
1203 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001204 LOG(ERROR) << "createComponent(" << name.c_str()
1205 << ") -- failed to set up death listener: "
1206 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001207 }
1208
Wonsik Kime8e98152022-12-16 16:04:17 -08001209 (*component)->mHidlBufferPoolSender->setReceiver(mHidlHostPoolManager);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001210 return status;
1211}
1212
1213c2_status_t Codec2Client::createInterface(
1214 const C2String& name,
1215 std::shared_ptr<Codec2Client::Interface>* const interface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001216 if (mAidlBase) {
1217 std::shared_ptr<c2_aidl::IComponentInterface> aidlInterface;
1218 ::ndk::ScopedAStatus transStatus = mAidlBase->createInterface(
1219 name,
1220 &aidlInterface);
1221 c2_status_t status = GetC2Status(transStatus, "createInterface");
1222 if (status != C2_OK) {
1223 return status;
1224 } else if (!aidlInterface) {
1225 LOG(ERROR) << "createInterface(" << name.c_str()
1226 << ") -- null interface.";
1227 return C2_CORRUPTED;
1228 }
1229 interface->reset(new Codec2Client::Interface(aidlInterface));
1230 return C2_OK;
1231 }
1232
Pawin Vongmasa36653902018-11-15 00:10:25 -08001233 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001234 Return<void> transStatus = mHidlBase1_0->createInterface(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001235 name,
1236 [&status, interface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001237 c2_hidl::Status s,
1238 const sp<c2_hidl::IComponentInterface>& i) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001239 status = static_cast<c2_status_t>(s);
1240 if (status != C2_OK) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001241 return;
1242 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001243 *interface = std::make_shared<Interface>(i);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001244 });
1245 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001246 LOG(ERROR) << "createInterface(" << name.c_str()
1247 << ") -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001248 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001249 } else if (status != C2_OK) {
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001250 if (status == C2_NOT_FOUND) {
1251 LOG(VERBOSE) << "createInterface(" << name.c_str()
1252 << ") -- component not found.";
1253 } else {
1254 LOG(ERROR) << "createInterface(" << name.c_str()
1255 << ") -- call failed: " << status << ".";
1256 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001257 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001258 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001259
Pawin Vongmasa36653902018-11-15 00:10:25 -08001260 return status;
1261}
1262
1263c2_status_t Codec2Client::createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001264 std::shared_ptr<InputSurface>* const inputSurface) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001265 if (mAidlBase) {
1266 // FIXME
1267 return C2_OMITTED;
1268 }
1269
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001270 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001271 Return<void> transStatus = mHidlBase1_0->createInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001272 [&status, inputSurface](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001273 c2_hidl::Status s,
1274 const sp<c2_hidl::IInputSurface>& i) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001275 status = static_cast<c2_status_t>(s);
1276 if (status != C2_OK) {
1277 return;
1278 }
1279 *inputSurface = std::make_shared<InputSurface>(i);
1280 });
1281 if (!transStatus.isOk()) {
1282 LOG(ERROR) << "createInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001283 return C2_TRANSACTION_FAILED;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001284 } else if (status != C2_OK) {
1285 LOG(DEBUG) << "createInputSurface -- call failed: "
1286 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001287 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001288 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001289}
1290
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001291std::vector<C2Component::Traits> const& Codec2Client::listComponents() const {
1292 return Cache::List()[mServiceIndex].getTraits();
1293}
1294
1295std::vector<C2Component::Traits> Codec2Client::_listComponents(
1296 bool* success) const {
1297 std::vector<C2Component::Traits> traits;
1298 std::string const& serviceName = getServiceName();
Wonsik Kime8e98152022-12-16 16:04:17 -08001299
1300 if (mAidlBase) {
1301 std::vector<c2_aidl::IComponentStore::ComponentTraits> aidlTraits;
1302 ::ndk::ScopedAStatus transStatus = mAidlBase->listComponents(&aidlTraits);
1303 if (!transStatus.isOk()) {
1304 LOG(ERROR) << "_listComponents -- transaction failed.";
1305 *success = false;
1306 } else {
1307 traits.resize(aidlTraits.size());
1308 *success = true;
1309 for (size_t i = 0; i < aidlTraits.size(); ++i) {
1310 if (!c2_aidl::utils::FromAidl(&traits[i], aidlTraits[i])) {
1311 LOG(ERROR) << "_listComponents -- corrupted output.";
1312 *success = false;
1313 traits.clear();
1314 break;
1315 }
1316 traits[i].owner = serviceName;
1317 }
1318 }
1319 return traits;
1320 }
1321 Return<void> transStatus = mHidlBase1_0->listComponents(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001322 [&traits, &serviceName](c2_hidl::Status s,
1323 const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) {
1324 if (s != c2_hidl::Status::OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001325 LOG(DEBUG) << "_listComponents -- call failed: "
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001326 << static_cast<c2_status_t>(s) << ".";
1327 return;
1328 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001329 traits.resize(t.size());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001330 for (size_t i = 0; i < t.size(); ++i) {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001331 if (!c2_hidl::utils::objcpy(&traits[i], t[i])) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001332 LOG(ERROR) << "_listComponents -- corrupted output.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001333 return;
1334 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001335 traits[i].owner = serviceName;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001336 }
1337 });
1338 if (!transStatus.isOk()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001339 LOG(ERROR) << "_listComponents -- transaction failed.";
1340 *success = false;
1341 } else {
1342 *success = true;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001343 }
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001344 return traits;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001345}
1346
1347c2_status_t Codec2Client::copyBuffer(
1348 const std::shared_ptr<C2Buffer>& src,
1349 const std::shared_ptr<C2Buffer>& dst) {
1350 // TODO: Implement?
1351 (void)src;
1352 (void)dst;
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001353 LOG(ERROR) << "copyBuffer not implemented";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001354 return C2_OMITTED;
1355}
1356
Wonsik Kime8e98152022-12-16 16:04:17 -08001357std::shared_ptr<C2ParamReflector> Codec2Client::getParamReflector() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001358 // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it
1359 // should reflect the HAL API.
Wonsik Kime8e98152022-12-16 16:04:17 -08001360 struct HidlSimpleParamReflector : public C2ParamReflector {
1361 std::unique_ptr<C2StructDescriptor> describe(
1362 C2Param::CoreIndex coreIndex) const override {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001363 hidl_vec<c2_hidl::ParamIndex> indices(1);
1364 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001365 std::unique_ptr<C2StructDescriptor> descriptor;
1366 Return<void> transStatus = mBase->getStructDescriptors(
1367 indices,
1368 [&descriptor](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001369 c2_hidl::Status s,
1370 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001371 c2_status_t status = static_cast<c2_status_t>(s);
1372 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001373 LOG(DEBUG) << "SimpleParamReflector -- "
1374 "getStructDescriptors() failed: "
1375 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001376 descriptor.reset();
1377 return;
1378 }
1379 if (sd.size() != 1) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001380 LOG(DEBUG) << "SimpleParamReflector -- "
1381 "getStructDescriptors() "
1382 "returned vector of size "
1383 << sd.size() << ". "
1384 "It should be 1.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001385 descriptor.reset();
1386 return;
1387 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001388 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001389 LOG(DEBUG) << "SimpleParamReflector -- "
1390 "getStructDescriptors() returned "
1391 "corrupted data.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001392 descriptor.reset();
1393 return;
1394 }
1395 });
Wonsik Kim492fecd2020-11-19 11:14:11 -08001396 if (!transStatus.isOk()) {
1397 LOG(DEBUG) << "SimpleParamReflector -- transaction failed: "
1398 << transStatus.description();
1399 descriptor.reset();
1400 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001401 return descriptor;
1402 }
1403
Wonsik Kime8e98152022-12-16 16:04:17 -08001404 HidlSimpleParamReflector(sp<HidlBase> base)
Pawin Vongmasa36653902018-11-15 00:10:25 -08001405 : mBase(base) { }
1406
Wonsik Kime8e98152022-12-16 16:04:17 -08001407 sp<HidlBase> mBase;
1408 };
1409 struct AidlSimpleParamReflector : public C2ParamReflector {
1410 std::unique_ptr<C2StructDescriptor> describe(
1411 C2Param::CoreIndex coreIndex) const override {
1412 std::vector<c2_aidl::StructDescriptor> aidlDesc;
1413 std::unique_ptr<C2StructDescriptor> descriptor;
1414 ::ndk::ScopedAStatus transStatus = mBase->getStructDescriptors(
1415 {int32_t(coreIndex.coreIndex())},
1416 &aidlDesc);
1417 c2_status_t status = GetC2Status(transStatus, "describe");
1418 if (status != C2_OK) {
1419 descriptor.reset();
1420 } else if (!c2_aidl::utils::FromAidl(&descriptor, aidlDesc[0])) {
1421 LOG(ERROR) << "describe -- conversion failed.";
1422 descriptor.reset();
1423 }
1424 return descriptor;
1425 }
1426
1427 AidlSimpleParamReflector(const std::shared_ptr<AidlBase> &base)
1428 : mBase(base) { }
1429
1430 std::shared_ptr<AidlBase> mBase;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001431 };
1432
Wonsik Kime8e98152022-12-16 16:04:17 -08001433 if (mAidlBase) {
1434 return std::make_shared<AidlSimpleParamReflector>(mAidlBase);
1435 }
1436 return std::make_shared<HidlSimpleParamReflector>(mHidlBase1_0);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001437};
1438
Wonsik Kime8e98152022-12-16 16:04:17 -08001439std::vector<std::string> Codec2Client::CacheServiceNames() {
1440 std::vector<std::string> names;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001441
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001442 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim2ecfbeb2023-11-02 20:03:14 +00001443 // Get AIDL service names
1444 AServiceManager_forEachDeclaredInstance(
1445 AidlBase::descriptor, &names, [](const char *name, void *context) {
1446 std::vector<std::string> *names = (std::vector<std::string> *)context;
1447 names->emplace_back(name);
1448 });
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001449 } else {
1450 // Get HIDL service names
1451 using ::android::hardware::media::c2::V1_0::IComponentStore;
1452 using ::android::hidl::manager::V1_2::IServiceManager;
1453 while (true) {
1454 sp<IServiceManager> serviceManager = IServiceManager::getService();
1455 CHECK(serviceManager) << "Hardware service manager is not running.";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001456
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001457 Return<void> transResult;
1458 transResult = serviceManager->listManifestByInterface(
1459 IComponentStore::descriptor,
1460 [&names](
1461 hidl_vec<hidl_string> const& instanceNames) {
1462 names.insert(names.end(), instanceNames.begin(), instanceNames.end());
1463 });
1464 if (transResult.isOk()) {
1465 break;
1466 }
1467 LOG(ERROR) << "Could not retrieve the list of service instances of "
1468 << IComponentStore::descriptor
1469 << ". Retrying...";
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001470 }
Wonsik Kime8e98152022-12-16 16:04:17 -08001471 }
1472 // Sort service names in each category.
1473 std::stable_sort(
1474 names.begin(), names.end(),
1475 [](const std::string &a, const std::string &b) {
1476 // First compare by prefix: default -> vendor -> {everything else}
1477 constexpr int DEFAULT = 1;
1478 constexpr int VENDOR = 2;
1479 constexpr int OTHER = 3;
1480 int aPrefix = ((a.compare(0, 7, "default") == 0) ? DEFAULT :
1481 (a.compare(0, 6, "vendor") == 0) ? VENDOR :
1482 OTHER);
1483 int bPrefix = ((b.compare(0, 7, "default") == 0) ? DEFAULT :
1484 (b.compare(0, 6, "vendor") == 0) ? VENDOR :
1485 OTHER);
1486 if (aPrefix != bPrefix) {
1487 return aPrefix < bPrefix;
1488 }
1489 // If the prefix is the same, compare alphabetically
1490 return a < b;
1491 });
1492
1493 // Summarize to logcat.
1494 if (names.empty()) {
1495 LOG(INFO) << "No Codec2 services declared in the manifest.";
1496 } else {
1497 std::stringstream stringOutput;
1498 stringOutput << "Available Codec2 services:";
1499 for (std::string const& name : names) {
1500 stringOutput << " \"" << name << "\"";
1501 }
1502 LOG(INFO) << stringOutput.str();
1503 }
1504
1505 return names;
1506}
1507
1508std::vector<std::string> const& Codec2Client::GetServiceNames() {
1509 static std::vector<std::string> sServiceNames = CacheServiceNames();
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001510 return sServiceNames;
1511}
1512
Pawin Vongmasa36653902018-11-15 00:10:25 -08001513std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001514 const char* name,
1515 bool setAsPreferredCodec2ComponentStore) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001516 size_t index = getServiceIndex(name);
Pawin Vongmasa83d2c552020-03-05 04:36:08 -08001517 if (index == GetServiceNames().size()) {
1518 if (setAsPreferredCodec2ComponentStore) {
1519 LOG(WARNING) << "CreateFromService(" << name
1520 << ") -- preferred C2ComponentStore not set.";
1521 }
1522 return nullptr;
1523 }
1524 std::shared_ptr<Codec2Client> client = _CreateFromIndex(index);
1525 if (setAsPreferredCodec2ComponentStore) {
1526 SetPreferredCodec2ComponentStore(
1527 std::make_shared<Client2Store>(client));
1528 LOG(INFO) << "CreateFromService(" << name
1529 << ") -- service set as preferred C2ComponentStore.";
1530 }
1531 return client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001532}
1533
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001534std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
1535 CreateFromAllServices() {
1536 std::vector<std::shared_ptr<Codec2Client>> clients(
1537 GetServiceNames().size());
1538 for (size_t i = GetServiceNames().size(); i > 0; ) {
1539 --i;
1540 clients[i] = _CreateFromIndex(i);
1541 }
1542 return clients;
1543}
1544
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001545std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001546 std::string const& name = GetServiceNames()[index];
Pawin Vongmasa9aac3042020-03-05 02:30:32 -08001547 LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\"";
Wonsik Kime8e98152022-12-16 16:04:17 -08001548
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001549 if (c2_aidl::utils::IsSelected()) {
Wonsik Kim2ecfbeb2023-11-02 20:03:14 +00001550 std::string instanceName =
1551 ::android::base::StringPrintf("%s/%s", AidlBase::descriptor, name.c_str());
1552 if (AServiceManager_isDeclared(instanceName.c_str())) {
1553 std::shared_ptr<AidlBase> baseStore = AidlBase::fromBinder(
1554 ::ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));
1555 CHECK(baseStore) << "Codec2 AIDL service \"" << name << "\""
1556 " inaccessible for unknown reasons.";
1557 LOG(VERBOSE) << "Client to Codec2 AIDL service \"" << name << "\" created";
1558 std::shared_ptr<c2_aidl::IConfigurable> configurable;
1559 ::ndk::ScopedAStatus transStatus = baseStore->getConfigurable(&configurable);
1560 CHECK(transStatus.isOk()) << "Codec2 AIDL service \"" << name << "\""
1561 "does not have IConfigurable.";
1562 return std::make_shared<Codec2Client>(baseStore, configurable, index);
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001563 } else {
Wonsik Kim2ecfbeb2023-11-02 20:03:14 +00001564 LOG(ERROR) << "Codec2 AIDL service \"" << name << "\" is not declared";
Wonsik Kime8e98152022-12-16 16:04:17 -08001565 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001566 } else {
1567 std::string instanceName = "android.hardware.media.c2/" + name;
1568 sp<HidlBase> baseStore = HidlBase::getService(name);
1569 CHECK(baseStore) << "Codec2 service \"" << name << "\""
1570 " inaccessible for unknown reasons.";
1571 LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created";
1572 Return<sp<c2_hidl::IConfigurable>> transResult = baseStore->getConfigurable();
1573 CHECK(transResult.isOk()) << "Codec2 service \"" << name << "\""
1574 "does not have IConfigurable.";
1575 sp<c2_hidl::IConfigurable> configurable =
1576 static_cast<sp<c2_hidl::IConfigurable>>(transResult);
1577 return std::make_shared<Codec2Client>(baseStore, configurable, index);
Wonsik Kime8e98152022-12-16 16:04:17 -08001578 }
Wonsik Kimb613d4b2023-09-01 14:01:36 -07001579 return nullptr;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001580}
1581
1582c2_status_t Codec2Client::ForAllServices(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001583 const std::string &key,
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001584 size_t numberOfAttempts,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001585 std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
1586 predicate) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001587 c2_status_t status = C2_NO_INIT; // no IComponentStores present
1588
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001589 // Cache the mapping key -> index of Codec2Client in Cache::List().
Pawin Vongmasa36653902018-11-15 00:10:25 -08001590 static std::mutex key2IndexMutex;
1591 static std::map<std::string, size_t> key2Index;
1592
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001593 // By default try all stores. However, try the last known client first. If
1594 // the last known client fails, retry once. We do this by pushing the last
1595 // known client in front of the list of all clients.
Pawin Vongmasa36653902018-11-15 00:10:25 -08001596 std::deque<size_t> indices;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001597 for (size_t index = Cache::List().size(); index > 0; ) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001598 indices.push_front(--index);
1599 }
1600
1601 bool wasMapped = false;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001602 {
1603 std::scoped_lock lock{key2IndexMutex};
1604 auto it = key2Index.find(key);
1605 if (it != key2Index.end()) {
1606 indices.push_front(it->second);
1607 wasMapped = true;
1608 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001609 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001610
1611 for (size_t index : indices) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001612 Cache& cache = Cache::List()[index];
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001613 for (size_t tries = numberOfAttempts; tries > 0; --tries) {
1614 std::shared_ptr<Codec2Client> client{cache.getClient()};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001615 status = predicate(client);
1616 if (status == C2_OK) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001617 std::scoped_lock lock{key2IndexMutex};
Pawin Vongmasa36653902018-11-15 00:10:25 -08001618 key2Index[key] = index; // update last known client index
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001619 return C2_OK;
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001620 } else if (status == C2_NO_MEMORY) {
1621 return C2_NO_MEMORY;
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001622 } else if (status == C2_TRANSACTION_FAILED) {
1623 LOG(WARNING) << "\"" << key << "\" failed for service \""
1624 << client->getName()
1625 << "\" due to transaction failure. "
1626 << "(Service may have crashed.)"
1627 << (tries > 1 ? " Retrying..." : "");
1628 cache.invalidate();
1629 continue;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001630 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001631 if (wasMapped) {
1632 LOG(INFO) << "\"" << key << "\" became invalid in service \""
1633 << client->getName() << "\". Retrying...";
1634 wasMapped = false;
1635 }
1636 break;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001637 }
1638 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001639 return status; // return the last status from a valid client
Pawin Vongmasa36653902018-11-15 00:10:25 -08001640}
1641
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001642c2_status_t Codec2Client::CreateComponentByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001643 const char* componentName,
1644 const std::shared_ptr<Listener>& listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001645 std::shared_ptr<Component>* component,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001646 std::shared_ptr<Codec2Client>* owner,
1647 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001648 std::string key{"create:"};
1649 key.append(componentName);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001650 c2_status_t status = ForAllServices(
1651 key,
1652 numberOfAttempts,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001653 [owner, component, componentName, &listener](
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001654 const std::shared_ptr<Codec2Client> &client)
1655 -> c2_status_t {
1656 c2_status_t status = client->createComponent(componentName,
1657 listener,
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001658 component);
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001659 if (status == C2_OK) {
1660 if (owner) {
1661 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001662 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001663 } else if (status != C2_NOT_FOUND) {
1664 LOG(DEBUG) << "IComponentStore("
1665 << client->getServiceName()
1666 << ")::createComponent(\"" << componentName
1667 << "\") returned status = "
1668 << status << ".";
1669 }
1670 return status;
1671 });
1672 if (status != C2_OK) {
1673 LOG(DEBUG) << "Failed to create component \"" << componentName
1674 << "\" from all known services. "
1675 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001676 }
Chih-Yu Huangb8fe0792020-12-07 17:14:55 +09001677 return status;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001678}
1679
Wonsik Kime8e98152022-12-16 16:04:17 -08001680std::shared_ptr<Codec2Client::Interface> Codec2Client::CreateInterfaceByName(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001681 const char* interfaceName,
Pawin Vongmasa23c90c82019-09-03 00:44:42 -07001682 std::shared_ptr<Codec2Client>* owner,
1683 size_t numberOfAttempts) {
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001684 std::string key{"create:"};
1685 key.append(interfaceName);
1686 std::shared_ptr<Interface> interface;
1687 c2_status_t status = ForAllServices(
1688 key,
1689 numberOfAttempts,
1690 [owner, &interface, interfaceName](
1691 const std::shared_ptr<Codec2Client> &client)
1692 -> c2_status_t {
1693 c2_status_t status = client->createInterface(interfaceName,
1694 &interface);
1695 if (status == C2_OK) {
1696 if (owner) {
1697 *owner = client;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001698 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001699 } else if (status != C2_NOT_FOUND) {
1700 LOG(DEBUG) << "IComponentStore("
1701 << client->getServiceName()
1702 << ")::createInterface(\"" << interfaceName
1703 << "\") returned status = "
1704 << status << ".";
1705 }
1706 return status;
1707 });
1708 if (status != C2_OK) {
1709 LOG(DEBUG) << "Failed to create interface \"" << interfaceName
1710 << "\" from all known services. "
1711 "Last returned status = " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001712 }
Pawin Vongmasa1e7015a2019-10-09 02:15:50 -07001713 return interface;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001714}
1715
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001716std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
1717 static std::vector<C2Component::Traits> sList{[]() {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001718 std::vector<C2Component::Traits> list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001719 for (Cache& cache : Cache::List()) {
1720 std::vector<C2Component::Traits> const& traits = cache.getTraits();
1721 list.insert(list.end(), traits.begin(), traits.end());
Pawin Vongmasa36653902018-11-15 00:10:25 -08001722 }
1723 return list;
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001724 }()};
1725 return sList;
1726}
Pawin Vongmasa36653902018-11-15 00:10:25 -08001727
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001728std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface(
1729 char const* serviceName) {
Pawin Vongmasa18588322019-05-18 01:52:13 -07001730 int32_t inputSurfaceSetting = ::android::base::GetIntProperty(
1731 "debug.stagefright.c2inputsurface", int32_t(0));
1732 if (inputSurfaceSetting <= 0) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001733 return nullptr;
1734 }
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001735 size_t index = GetServiceNames().size();
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001736 if (serviceName) {
1737 index = getServiceIndex(serviceName);
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001738 if (index == GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001739 LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
1740 << serviceName << "\"";
1741 }
1742 }
1743
1744 std::shared_ptr<Codec2Client::InputSurface> inputSurface;
Pawin Vongmasa270dd6a2019-04-06 04:41:15 -07001745 if (index != GetServiceNames().size()) {
Pawin Vongmasa892c81d2019-03-12 00:56:50 -07001746 std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
1747 if (client->createInputSurface(&inputSurface) == C2_OK) {
1748 return inputSurface;
1749 }
1750 }
1751 LOG(INFO) << "CreateInputSurface -- attempting to create an input surface "
1752 "from all services...";
1753 for (Cache& cache : Cache::List()) {
1754 std::shared_ptr<Codec2Client> client = cache.getClient();
1755 if (client->createInputSurface(&inputSurface) == C2_OK) {
1756 LOG(INFO) << "CreateInputSurface -- input surface obtained from "
1757 "service \"" << client->getServiceName() << "\"";
1758 return inputSurface;
1759 }
1760 }
1761 LOG(WARNING) << "CreateInputSurface -- failed to create an input surface "
1762 "from all services";
1763 return nullptr;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001764}
1765
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001766// Codec2Client::Interface
Wonsik Kime8e98152022-12-16 16:04:17 -08001767Codec2Client::Interface::Interface(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001768 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001769 [base]() -> sp<c2_hidl::IConfigurable> {
1770 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001771 base->getConfigurable();
1772 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001773 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001774 nullptr;
1775 }()
1776 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001777 mHidlBase{base} {
1778}
1779
1780Codec2Client::Interface::Interface(const std::shared_ptr<AidlBase>& base)
1781 : Configurable{
1782 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1783 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1784 ::ndk::ScopedAStatus transStatus =
1785 base->getConfigurable(&aidlConfigurable);
1786 return transStatus.isOk() ? aidlConfigurable : nullptr;
1787 }()
1788 },
1789 mAidlBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001790}
1791
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001792// Codec2Client::Component
Wonsik Kime8e98152022-12-16 16:04:17 -08001793
1794class Codec2Client::Component::AidlDeathManager {
1795public:
1796 AidlDeathManager()
1797 : mSeq(0),
1798 mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) {
1799 }
1800
1801 ~AidlDeathManager() = default;
1802
1803 bool linkToDeath(
1804 const std::shared_ptr<Component> &comp,
1805 const std::shared_ptr<Listener> &listener,
1806 size_t *seqPtr) {
1807 std::unique_lock lock(mMutex);
1808 size_t seq = mSeq++;
1809 if (!mMap.try_emplace(seq, comp, listener).second) {
1810 return false;
1811 }
1812 if (STATUS_OK != AIBinder_linkToDeath(
1813 comp->mAidlBase->asBinder().get(), mDeathRecipient.get(), (void *)seq)) {
1814 mMap.erase(seq);
1815 return false;
1816 }
1817 *seqPtr = seq;
1818 return true;
1819 }
1820
1821 void unlinkToDeath(size_t seq, const std::shared_ptr<AidlBase> &base) {
1822 std::unique_lock lock(mMutex);
1823 AIBinder_unlinkToDeath(base->asBinder().get(), mDeathRecipient.get(), (void *)seq);
1824 mMap.erase(seq);
1825 }
1826
1827private:
1828 std::mutex mMutex;
1829 size_t mSeq;
1830 typedef std::tuple<std::weak_ptr<Component>, std::weak_ptr<Listener>> Context;
1831 std::map<size_t, Context> mMap;
1832 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
1833
1834 bool extractContext(size_t seq, Context *context) {
1835 std::unique_lock lock(mMutex);
1836 auto node = mMap.extract(seq);
1837 if (!node) {
1838 return false;
1839 }
1840 *context = node.mapped();
1841 return true;
1842 }
1843
1844 static void OnBinderDied(void *cookie) {
1845 size_t seq = size_t(cookie);
1846 Context context;
1847 if (!Component::GetAidlDeathManager()->extractContext(seq, &context)) {
1848 return;
1849 }
1850 std::weak_ptr<Component> weakComponent;
1851 std::weak_ptr<Listener> weakListener;
1852 std::tie(weakComponent, weakListener) = context;
1853 if (std::shared_ptr<Listener> listener = weakListener.lock()) {
1854 listener->onDeath(weakComponent);
1855 } else {
1856 LOG(DEBUG) << "onDeath -- listener died.";
1857 }
1858 }
1859};
1860
1861Codec2Client::Component::Component(const sp<HidlBase>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001862 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001863 [base]() -> sp<c2_hidl::IConfigurable> {
1864 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001865 base->getInterface();
1866 if (!transResult1.isOk()) {
1867 return nullptr;
1868 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001869 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1870 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001871 getConfigurable();
1872 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001873 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001874 nullptr;
1875 }()
1876 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001877 mHidlBase1_0{base},
1878 mHidlBase1_1{HidlBase1_1::castFrom(base)},
1879 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1880 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001881 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1882}
1883
Wonsik Kime8e98152022-12-16 16:04:17 -08001884Codec2Client::Component::Component(const sp<HidlBase1_1>& base)
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001885 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001886 [base]() -> sp<c2_hidl::IConfigurable> {
1887 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001888 base->getInterface();
1889 if (!transResult1.isOk()) {
1890 return nullptr;
1891 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001892 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1893 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001894 getConfigurable();
1895 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001896 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001897 nullptr;
1898 }()
1899 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001900 mHidlBase1_0{base},
1901 mHidlBase1_1{base},
1902 mHidlBase1_2{HidlBase1_2::castFrom(base)},
1903 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
Sungtak Lee8577dab2021-03-12 02:25:50 -08001904 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1905}
1906
Wonsik Kime8e98152022-12-16 16:04:17 -08001907Codec2Client::Component::Component(const sp<HidlBase1_2>& base)
Sungtak Lee8577dab2021-03-12 02:25:50 -08001908 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001909 [base]() -> sp<c2_hidl::IConfigurable> {
1910 Return<sp<c2_hidl::IComponentInterface>> transResult1 =
Sungtak Lee8577dab2021-03-12 02:25:50 -08001911 base->getInterface();
1912 if (!transResult1.isOk()) {
1913 return nullptr;
1914 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001915 Return<sp<c2_hidl::IConfigurable>> transResult2 =
1916 static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
Sungtak Lee8577dab2021-03-12 02:25:50 -08001917 getConfigurable();
1918 return transResult2.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001919 static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
Sungtak Lee8577dab2021-03-12 02:25:50 -08001920 nullptr;
1921 }()
1922 },
Wonsik Kime8e98152022-12-16 16:04:17 -08001923 mHidlBase1_0{base},
1924 mHidlBase1_1{base},
1925 mHidlBase1_2{base},
1926 mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()},
1927 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
1928}
1929
1930Codec2Client::Component::Component(const std::shared_ptr<AidlBase> &base)
1931 : Configurable{
1932 [base]() -> std::shared_ptr<c2_aidl::IConfigurable> {
1933 std::shared_ptr<c2_aidl::IComponentInterface> aidlIntf;
1934 ::ndk::ScopedAStatus transStatus = base->getInterface(&aidlIntf);
1935 if (!transStatus.isOk()) {
1936 return nullptr;
1937 }
1938 std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable;
1939 transStatus = aidlIntf->getConfigurable(&aidlConfigurable);
1940 return transStatus.isOk() ? aidlConfigurable : nullptr;
1941 }()
1942 },
1943 mAidlBase{base},
1944 mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()},
Pawin Vongmasabf69de92019-10-29 06:21:27 -07001945 mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001946}
1947
1948Codec2Client::Component::~Component() {
Wonsik Kime8e98152022-12-16 16:04:17 -08001949 if (mAidlDeathSeq) {
1950 GetAidlDeathManager()->unlinkToDeath(*mAidlDeathSeq, mAidlBase);
1951 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001952}
1953
1954c2_status_t Codec2Client::Component::createBlockPool(
1955 C2Allocator::id_t id,
1956 C2BlockPool::local_id_t* blockPoolId,
1957 std::shared_ptr<Codec2Client::Configurable>* configurable) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001958 if (mAidlBase) {
1959 c2_aidl::IComponent::BlockPool aidlBlockPool;
Ryan Prichard8d37bb02023-09-13 20:23:15 -07001960 ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id),
1961 &aidlBlockPool);
Wonsik Kime8e98152022-12-16 16:04:17 -08001962 c2_status_t status = GetC2Status(transStatus, "createBlockPool");
1963 if (status != C2_OK) {
1964 return status;
1965 }
1966 *blockPoolId = aidlBlockPool.blockPoolId;
1967 *configurable = std::make_shared<Configurable>(aidlBlockPool.configurable);
1968 return C2_OK;
1969 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001970 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08001971 Return<void> transStatus = mHidlBase1_0->createBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08001972 static_cast<uint32_t>(id),
1973 [&status, blockPoolId, configurable](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001974 c2_hidl::Status s,
Pawin Vongmasa36653902018-11-15 00:10:25 -08001975 uint64_t pId,
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08001976 const sp<c2_hidl::IConfigurable>& c) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08001977 status = static_cast<c2_status_t>(s);
1978 configurable->reset();
1979 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001980 LOG(DEBUG) << "createBlockPool -- call failed: "
1981 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001982 return;
1983 }
1984 *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId);
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001985 *configurable = std::make_shared<Configurable>(c);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001986 });
1987 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08001988 LOG(ERROR) << "createBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08001989 return C2_TRANSACTION_FAILED;
1990 }
1991 return status;
1992}
1993
1994c2_status_t Codec2Client::Component::destroyBlockPool(
1995 C2BlockPool::local_id_t localId) {
Wonsik Kime8e98152022-12-16 16:04:17 -08001996 if (mAidlBase) {
1997 ::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId);
1998 return GetC2Status(transStatus, "destroyBlockPool");
1999 }
2000 Return<c2_hidl::Status> transResult = mHidlBase1_0->destroyBlockPool(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002001 static_cast<uint64_t>(localId));
2002 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002003 LOG(ERROR) << "destroyBlockPool -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002004 return C2_TRANSACTION_FAILED;
2005 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002006 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002007}
2008
Wonsik Kimab34ed62019-01-31 15:28:46 -08002009void Codec2Client::Component::handleOnWorkDone(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002010 const std::list<std::unique_ptr<C2Work>> &workItems) {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002011 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002012 mOutputBufferQueue->holdBufferQueueBlocks(workItems);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002013}
2014
2015c2_status_t Codec2Client::Component::queue(
2016 std::list<std::unique_ptr<C2Work>>* const items) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002017 if (mAidlBase) {
2018 c2_aidl::WorkBundle workBundle;
2019 if (!c2_aidl::utils::ToAidl(&workBundle, *items, mAidlBufferPoolSender.get())) {
2020 LOG(ERROR) << "queue -- bad input.";
2021 return C2_TRANSACTION_FAILED;
2022 }
2023 ::ndk::ScopedAStatus transStatus = mAidlBase->queue(workBundle);
2024 return GetC2Status(transStatus, "queue");
2025 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002026 c2_hidl::WorkBundle workBundle;
Wonsik Kime8e98152022-12-16 16:04:17 -08002027 if (!c2_hidl::utils::objcpy(&workBundle, *items, mHidlBufferPoolSender.get())) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002028 LOG(ERROR) << "queue -- bad input.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002029 return C2_TRANSACTION_FAILED;
2030 }
Wonsik Kime8e98152022-12-16 16:04:17 -08002031 Return<c2_hidl::Status> transStatus = mHidlBase1_0->queue(workBundle);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002032 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002033 LOG(ERROR) << "queue -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002034 return C2_TRANSACTION_FAILED;
2035 }
2036 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002037 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002038 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002039 LOG(DEBUG) << "queue -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002040 }
2041 return status;
2042}
2043
2044c2_status_t Codec2Client::Component::flush(
2045 C2Component::flush_mode_t mode,
2046 std::list<std::unique_ptr<C2Work>>* const flushedWork) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002047 (void)mode; // Flush mode isn't supported in HIDL/AIDL yet.
2048 c2_status_t status = C2_OK;
2049 if (mAidlBase) {
2050 c2_aidl::WorkBundle workBundle;
2051 ::ndk::ScopedAStatus transStatus = mAidlBase->flush(&workBundle);
2052 c2_status_t status = GetC2Status(transStatus, "flush");
2053 if (status != C2_OK) {
2054 return status;
2055 }
2056 if (!c2_aidl::utils::FromAidl(flushedWork, workBundle)) {
2057 LOG(DEBUG) << "flush -- flushedWork corrupted.";
2058 return C2_CORRUPTED;
2059 }
2060 } else {
2061 Return<void> transStatus = mHidlBase1_0->flush(
2062 [&status, flushedWork](
2063 c2_hidl::Status s, const c2_hidl::WorkBundle& wb) {
2064 status = static_cast<c2_status_t>(s);
2065 if (status != C2_OK) {
2066 LOG(DEBUG) << "flush -- call failed: " << status << ".";
2067 return;
2068 }
2069 if (!c2_hidl::utils::objcpy(flushedWork, wb)) {
2070 status = C2_CORRUPTED;
2071 } else {
2072 status = C2_OK;
2073 }
2074 });
2075 if (!transStatus.isOk()) {
2076 LOG(ERROR) << "flush -- transaction failed.";
2077 return C2_TRANSACTION_FAILED;
2078 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002079 }
2080
2081 // Indices of flushed work items.
2082 std::vector<uint64_t> flushedIndices;
2083 for (const std::unique_ptr<C2Work> &work : *flushedWork) {
2084 if (work) {
2085 if (work->worklets.empty()
2086 || !work->worklets.back()
2087 || (work->worklets.back()->output.flags &
2088 C2FrameData::FLAG_INCOMPLETE) == 0) {
2089 // input is complete
2090 flushedIndices.emplace_back(
2091 work->input.ordinal.frameIndex.peeku());
2092 }
2093 }
2094 }
2095
Pawin Vongmasa36653902018-11-15 00:10:25 -08002096 // Output bufferqueue-based blocks' lifetime management
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002097 mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002098
2099 return status;
2100}
2101
2102c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002103 if (mAidlBase) {
2104 ::ndk::ScopedAStatus transStatus = mAidlBase->drain(
2105 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2106 return GetC2Status(transStatus, "drain");
2107 }
2108 Return<c2_hidl::Status> transStatus = mHidlBase1_0->drain(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002109 mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
2110 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002111 LOG(ERROR) << "drain -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002112 return C2_TRANSACTION_FAILED;
2113 }
2114 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002115 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002116 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002117 LOG(DEBUG) << "drain -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002118 }
2119 return status;
2120}
2121
2122c2_status_t Codec2Client::Component::start() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002123 if (mAidlBase) {
2124 ::ndk::ScopedAStatus transStatus = mAidlBase->start();
2125 return GetC2Status(transStatus, "start");
2126 }
2127 Return<c2_hidl::Status> transStatus = mHidlBase1_0->start();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002128 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002129 LOG(ERROR) << "start -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002130 return C2_TRANSACTION_FAILED;
2131 }
2132 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002133 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002134 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002135 LOG(DEBUG) << "start -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002136 }
2137 return status;
2138}
2139
2140c2_status_t Codec2Client::Component::stop() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002141 if (mAidlBase) {
2142 ::ndk::ScopedAStatus transStatus = mAidlBase->stop();
2143 return GetC2Status(transStatus, "stop");
2144 }
2145 Return<c2_hidl::Status> transStatus = mHidlBase1_0->stop();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002146 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002147 LOG(ERROR) << "stop -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002148 return C2_TRANSACTION_FAILED;
2149 }
2150 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002151 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002152 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002153 LOG(DEBUG) << "stop -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002154 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002155 return status;
2156}
2157
2158c2_status_t Codec2Client::Component::reset() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002159 if (mAidlBase) {
2160 ::ndk::ScopedAStatus transStatus = mAidlBase->reset();
2161 return GetC2Status(transStatus, "reset");
2162 }
2163 Return<c2_hidl::Status> transStatus = mHidlBase1_0->reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002164 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002165 LOG(ERROR) << "reset -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002166 return C2_TRANSACTION_FAILED;
2167 }
2168 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002169 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002170 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002171 LOG(DEBUG) << "reset -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002172 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002173 return status;
2174}
2175
2176c2_status_t Codec2Client::Component::release() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002177 if (mAidlBase) {
2178 ::ndk::ScopedAStatus transStatus = mAidlBase->release();
2179 return GetC2Status(transStatus, "release");
2180 }
2181 Return<c2_hidl::Status> transStatus = mHidlBase1_0->release();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002182 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002183 LOG(ERROR) << "release -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002184 return C2_TRANSACTION_FAILED;
2185 }
2186 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002187 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002188 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002189 LOG(DEBUG) << "release -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002190 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08002191 return status;
2192}
2193
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002194c2_status_t Codec2Client::Component::configureVideoTunnel(
2195 uint32_t avSyncHwId,
2196 native_handle_t** sidebandHandle) {
2197 *sidebandHandle = nullptr;
Wonsik Kime8e98152022-12-16 16:04:17 -08002198 if (mAidlBase) {
2199 ::aidl::android::hardware::common::NativeHandle handle;
2200 ::ndk::ScopedAStatus transStatus = mAidlBase->configureVideoTunnel(avSyncHwId, &handle);
2201 c2_status_t status = GetC2Status(transStatus, "configureVideoTunnel");
2202 if (status != C2_OK) {
2203 return status;
2204 }
2205 if (isAidlNativeHandleEmpty(handle)) {
2206 LOG(DEBUG) << "configureVideoTunnel -- empty handle returned";
2207 } else {
2208 *sidebandHandle = dupFromAidl(handle);
2209 }
2210 return C2_OK;
2211 }
2212 if (!mHidlBase1_1) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002213 return C2_OMITTED;
2214 }
2215 c2_status_t status{};
Wonsik Kime8e98152022-12-16 16:04:17 -08002216 Return<void> transStatus = mHidlBase1_1->configureVideoTunnel(avSyncHwId,
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002217 [&status, sidebandHandle](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002218 c2_hidl::Status s, hardware::hidl_handle const& h) {
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002219 status = static_cast<c2_status_t>(s);
2220 if (h.getNativeHandle()) {
2221 *sidebandHandle = native_handle_clone(h.getNativeHandle());
2222 }
2223 });
2224 if (!transStatus.isOk()) {
2225 LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
2226 return C2_TRANSACTION_FAILED;
2227 }
2228 return status;
2229}
2230
Pawin Vongmasa36653902018-11-15 00:10:25 -08002231c2_status_t Codec2Client::Component::setOutputSurface(
2232 C2BlockPool::local_id_t blockPoolId,
2233 const sp<IGraphicBufferProducer>& surface,
Sungtak Leedb14cba2021-04-10 00:50:23 -07002234 uint32_t generation,
2235 int maxDequeueCount) {
Sungtak Lee08515812019-06-05 11:16:32 -07002236 uint64_t bqId = 0;
2237 sp<IGraphicBufferProducer> nullIgbp;
2238 sp<HGraphicBufferProducer2> nullHgbp;
Pawin Vongmasa3866c7e2019-01-31 05:21:29 -08002239
Sungtak Lee08515812019-06-05 11:16:32 -07002240 sp<HGraphicBufferProducer2> igbp = surface ?
2241 surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp;
2242 if (surface && !igbp) {
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002243 igbp = new B2HGraphicBufferProducer2(surface);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002244 }
2245
Sungtak Leefb579022022-05-10 06:36:15 +00002246 std::scoped_lock lock(mOutputMutex);
Sungtak Leea714f112021-03-16 05:40:03 -07002247 std::shared_ptr<SurfaceSyncObj> syncObj;
2248
Sungtak Lee08515812019-06-05 11:16:32 -07002249 if (!surface) {
Sungtak Leedb14cba2021-04-10 00:50:23 -07002250 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002251 } else if (surface->getUniqueId(&bqId) != OK) {
2252 LOG(ERROR) << "setOutputSurface -- "
2253 "cannot obtain bufferqueue id.";
2254 bqId = 0;
Sungtak Leedb14cba2021-04-10 00:50:23 -07002255 mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002256 } else {
Wonsik Kime8e98152022-12-16 16:04:17 -08002257 mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount,
2258 mHidlBase1_2 ? &syncObj : nullptr);
Sungtak Lee08515812019-06-05 11:16:32 -07002259 }
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002260
2261 // set consumer bits
2262 // TODO: should this get incorporated into setOutputSurface method so that consumer bits
2263 // can be set atomically?
2264 uint64_t consumerUsage = kDefaultConsumerUsage;
2265 {
2266 if (surface) {
Sungtak Lee46a69d62023-08-12 07:24:24 +00002267 uint64_t usage = 0;
2268 status_t err = surface->getConsumerUsage(&usage);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002269 if (err != NO_ERROR) {
2270 ALOGD("setOutputSurface -- failed to get consumer usage bits (%d/%s). ignoring",
2271 err, asString(err));
2272 } else {
2273 // Note: we are adding the default usage because components must support
2274 // producing output frames that can be displayed an all output surfaces.
2275
2276 // TODO: do not set usage for tunneled scenario. It is unclear if consumer usage
2277 // is meaningful in a tunneled scenario; on one hand output buffers exist, but
2278 // they do not exist inside of C2 scope. Any buffer usage shall be communicated
2279 // through the sideband channel.
2280
Sungtak Lee46a69d62023-08-12 07:24:24 +00002281 consumerUsage = usage | kDefaultConsumerUsage;
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002282 }
2283 }
2284
2285 C2StreamUsageTuning::output outputUsage{
2286 0u, C2AndroidMemoryUsage::FromGrallocUsage(consumerUsage).expected};
2287 std::vector<std::unique_ptr<C2SettingResult>> failures;
2288 c2_status_t err = config({&outputUsage}, C2_MAY_BLOCK, &failures);
2289 if (err != C2_OK) {
2290 ALOGD("setOutputSurface -- failed to set consumer usage (%d/%s)",
2291 err, asString(err));
2292 }
2293 }
2294 ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
2295 generation, (long long)consumerUsage, syncObj ? " sync" : "");
Sungtak Lee08515812019-06-05 11:16:32 -07002296
Wonsik Kime8e98152022-12-16 16:04:17 -08002297 if (mAidlBase) {
2298 // FIXME
2299 return C2_OMITTED;
2300 }
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002301 Return<c2_hidl::Status> transStatus = syncObj ?
Wonsik Kime8e98152022-12-16 16:04:17 -08002302 mHidlBase1_2->setOutputSurfaceWithSyncObj(
Sungtak Leea714f112021-03-16 05:40:03 -07002303 static_cast<uint64_t>(blockPoolId),
2304 bqId == 0 ? nullHgbp : igbp, *syncObj) :
Wonsik Kime8e98152022-12-16 16:04:17 -08002305 mHidlBase1_0->setOutputSurface(
Sungtak Leea714f112021-03-16 05:40:03 -07002306 static_cast<uint64_t>(blockPoolId),
2307 bqId == 0 ? nullHgbp : igbp);
Lajos Molnar78aa7c92021-02-18 21:39:01 -08002308
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002309 mOutputBufferQueue->expireOldWaiters();
2310
Pawin Vongmasa36653902018-11-15 00:10:25 -08002311 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002312 LOG(ERROR) << "setOutputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002313 return C2_TRANSACTION_FAILED;
2314 }
2315 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002316 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002317 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002318 LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002319 }
Sungtak Leea714f112021-03-16 05:40:03 -07002320 ALOGD("Surface configure completed");
Pawin Vongmasa36653902018-11-15 00:10:25 -08002321 return status;
2322}
2323
2324status_t Codec2Client::Component::queueToOutputSurface(
2325 const C2ConstGraphicBlock& block,
2326 const QueueBufferInput& input,
2327 QueueBufferOutput* output) {
Arun Johnson7ba67072023-11-06 22:23:04 +00002328 ScopedTrace trace(ATRACE_TAG,"Codec2Client::Component::queueToOutputSurface");
Pawin Vongmasabf69de92019-10-29 06:21:27 -07002329 return mOutputBufferQueue->outputBuffer(block, input, output);
Pawin Vongmasa36653902018-11-15 00:10:25 -08002330}
2331
Brian Lindahlc953b462023-01-27 16:21:43 -07002332void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
2333 mOutputBufferQueue->pollForRenderedFrames(delta);
2334}
2335
Sungtak Leea714f112021-03-16 05:40:03 -07002336void Codec2Client::Component::setOutputSurfaceMaxDequeueCount(
2337 int maxDequeueCount) {
2338 mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount);
2339}
2340
Sungtak Leec7da7a02022-05-05 08:45:33 +00002341void Codec2Client::Component::stopUsingOutputSurface(
2342 C2BlockPool::local_id_t blockPoolId) {
Sungtak Leefb579022022-05-10 06:36:15 +00002343 std::scoped_lock lock(mOutputMutex);
Sungtak Leec7da7a02022-05-05 08:45:33 +00002344 mOutputBufferQueue->stop();
Wonsik Kime8e98152022-12-16 16:04:17 -08002345 if (mAidlBase) {
2346 // FIXME
2347 return;
2348 }
2349 Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface(
Sungtak Leec7da7a02022-05-05 08:45:33 +00002350 static_cast<uint64_t>(blockPoolId), nullptr);
2351 if (!transStatus.isOk()) {
2352 LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed.";
2353 } else {
2354 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002355 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Sungtak Leec7da7a02022-05-05 08:45:33 +00002356 if (status != C2_OK) {
2357 LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: "
2358 << status << ".";
2359 }
2360 }
Sungtak Lee8e2e2c62023-01-17 18:29:34 +00002361 mOutputBufferQueue->expireOldWaiters();
Sungtak Leec7da7a02022-05-05 08:45:33 +00002362}
2363
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002364c2_status_t Codec2Client::Component::connectToInputSurface(
2365 const std::shared_ptr<InputSurface>& inputSurface,
2366 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002367 if (mAidlBase) {
2368 // FIXME
2369 return C2_OMITTED;
2370 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002371 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002372 Return<void> transStatus = mHidlBase1_0->connectToInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002373 inputSurface->mBase,
2374 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002375 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002376 status = static_cast<c2_status_t>(s);
2377 if (status != C2_OK) {
2378 LOG(DEBUG) << "connectToInputSurface -- call failed: "
2379 << status << ".";
2380 return;
2381 }
2382 *connection = std::make_shared<InputSurfaceConnection>(c);
2383 });
Pawin Vongmasa36653902018-11-15 00:10:25 -08002384 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002385 LOG(ERROR) << "connectToInputSurface -- transaction failed";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002386 return C2_TRANSACTION_FAILED;
2387 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002388 return status;
2389}
2390
2391c2_status_t Codec2Client::Component::connectToOmxInputSurface(
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002392 const sp<HGraphicBufferProducer1>& producer,
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002393 const sp<HGraphicBufferSource>& source,
2394 std::shared_ptr<InputSurfaceConnection>* connection) {
Wonsik Kime8e98152022-12-16 16:04:17 -08002395 if (mAidlBase) {
2396 LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL";
2397 return C2_OMITTED;
2398 }
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002399 c2_status_t status;
Wonsik Kime8e98152022-12-16 16:04:17 -08002400 Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface(
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002401 producer, source,
2402 [&status, connection](
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002403 c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002404 status = static_cast<c2_status_t>(s);
2405 if (status != C2_OK) {
2406 LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
2407 << status << ".";
2408 return;
2409 }
2410 *connection = std::make_shared<InputSurfaceConnection>(c);
2411 });
2412 if (!transStatus.isOk()) {
2413 LOG(ERROR) << "connectToOmxInputSurface -- transaction failed.";
2414 return C2_TRANSACTION_FAILED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08002415 }
2416 return status;
2417}
2418
2419c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
Wonsik Kime8e98152022-12-16 16:04:17 -08002420 if (mAidlBase) {
2421 // FIXME
2422 return C2_OMITTED;
2423 }
2424 Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface();
Pawin Vongmasa36653902018-11-15 00:10:25 -08002425 if (!transStatus.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002426 LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002427 return C2_TRANSACTION_FAILED;
2428 }
2429 c2_status_t status =
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002430 static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002431 if (status != C2_OK) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002432 LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
2433 << status << ".";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002434 }
2435 return status;
2436}
2437
Wonsik Kime8e98152022-12-16 16:04:17 -08002438Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() {
2439 // This object never gets destructed
2440 static AidlDeathManager *sManager = new AidlDeathManager();
2441 return sManager;
2442}
2443
Pawin Vongmasa36653902018-11-15 00:10:25 -08002444c2_status_t Codec2Client::Component::setDeathListener(
2445 const std::shared_ptr<Component>& component,
2446 const std::shared_ptr<Listener>& listener) {
2447
2448 struct HidlDeathRecipient : public hardware::hidl_death_recipient {
2449 std::weak_ptr<Component> component;
2450 std::weak_ptr<Listener> base;
2451
2452 virtual void serviceDied(
2453 uint64_t /* cookie */,
2454 const wp<::android::hidl::base::V1_0::IBase>& /* who */
2455 ) override {
2456 if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) {
2457 listener->onDeath(component);
2458 } else {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002459 LOG(DEBUG) << "onDeath -- listener died.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002460 }
2461 }
2462 };
2463
Wonsik Kime8e98152022-12-16 16:04:17 -08002464 if (component->mAidlBase) {
2465 size_t seq;
2466 if (GetAidlDeathManager()->linkToDeath(component, listener, &seq)) {
2467 component->mAidlDeathSeq = seq;
2468 }
2469 return C2_OK;
2470 }
2471
Pawin Vongmasa36653902018-11-15 00:10:25 -08002472 sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient();
2473 deathRecipient->base = listener;
2474 deathRecipient->component = component;
2475
2476 component->mDeathRecipient = deathRecipient;
Wonsik Kime8e98152022-12-16 16:04:17 -08002477 Return<bool> transResult = component->mHidlBase1_0->linkToDeath(
Pawin Vongmasa36653902018-11-15 00:10:25 -08002478 component->mDeathRecipient, 0);
2479 if (!transResult.isOk()) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002480 LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002481 return C2_TRANSACTION_FAILED;
2482 }
2483 if (!static_cast<bool>(transResult)) {
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002484 LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed.";
Pawin Vongmasa36653902018-11-15 00:10:25 -08002485 return C2_CORRUPTED;
2486 }
2487 return C2_OK;
2488}
2489
2490// Codec2Client::InputSurface
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002491Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002492 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002493 [base]() -> sp<c2_hidl::IConfigurable> {
2494 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002495 base->getConfigurable();
2496 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002497 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002498 nullptr;
2499 }()
2500 },
2501 mBase{base},
2502 mGraphicBufferProducer{new
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002503 H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> {
2504 Return<sp<HGraphicBufferProducer2>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002505 base->getGraphicBufferProducer();
2506 return transResult.isOk() ?
Pawin Vongmasaef939bf2019-03-03 04:44:59 -08002507 static_cast<sp<HGraphicBufferProducer2>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002508 nullptr;
2509 }())} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002510}
2511
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002512sp<IGraphicBufferProducer>
Pawin Vongmasa36653902018-11-15 00:10:25 -08002513 Codec2Client::InputSurface::getGraphicBufferProducer() const {
2514 return mGraphicBufferProducer;
2515}
2516
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002517sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002518 return mBase;
2519}
2520
2521// Codec2Client::InputSurfaceConnection
Pawin Vongmasa36653902018-11-15 00:10:25 -08002522Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002523 const sp<c2_hidl::IInputSurfaceConnection>& base)
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002524 : Configurable{
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002525 [base]() -> sp<c2_hidl::IConfigurable> {
2526 Return<sp<c2_hidl::IConfigurable>> transResult =
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002527 base->getConfigurable();
2528 return transResult.isOk() ?
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002529 static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
Pawin Vongmasa1c75a232019-01-09 04:41:52 -08002530 nullptr;
2531 }()
2532 },
2533 mBase{base} {
Pawin Vongmasa36653902018-11-15 00:10:25 -08002534}
2535
2536c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
Wonsik Kimc8fc2c32022-12-12 14:43:00 -08002537 Return<c2_hidl::Status> transResult = mBase->disconnect();
2538 return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
Pawin Vongmasa36653902018-11-15 00:10:25 -08002539}
2540
2541} // namespace android