| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1 | /* | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2 | * Copyright 2018 The Android Open Source Project | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | //#define LOG_NDEBUG 0 | 
|  | 18 | #define LOG_TAG "Codec2Client" | 
| Arun Johnson | 7ba6707 | 2023-11-06 22:23:04 +0000 | [diff] [blame] | 19 | #define ATRACE_TAG  ATRACE_TAG_VIDEO | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 20 | #include <android-base/logging.h> | 
| Arun Johnson | 7ba6707 | 2023-11-06 22:23:04 +0000 | [diff] [blame] | 21 | #include <utils/Trace.h> | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 22 | #include <codec2/hidl/client.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 23 | #include <C2Debug.h> | 
|  | 24 | #include <C2BufferPriv.h> | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 25 | #include <C2Config.h> // for C2StreamUsageTuning | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 26 | #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 Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 36 | #include <aidl/android/hardware/media/bufferpool2/IClientManager.h> | 
|  | 37 | #include <aidl/android/hardware/media/c2/BnComponentListener.h> | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 38 | #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 Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 46 | #include <aidl/android/hardware/media/c2/StructDescriptor.h> | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 47 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 48 | #include <aidlcommonsupport/NativeHandle.h> | 
| Wonsik Kim | 138db0d | 2023-11-02 16:02:01 -0700 | [diff] [blame] | 49 | #include <android/api-level.h> | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 50 | #include <android/binder_auto_utils.h> | 
|  | 51 | #include <android/binder_ibinder.h> | 
|  | 52 | #include <android/binder_manager.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 53 | #include <android-base/properties.h> | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 54 | #include <android-base/stringprintf.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 55 | #include <bufferpool/ClientManager.h> | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 56 | #include <bufferpool2/ClientManager.h> | 
|  | 57 | #include <codec2/aidl/BufferTypes.h> | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 58 | #include <codec2/aidl/ParamTypes.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 59 | #include <codec2/hidl/1.0/types.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 60 | #include <codec2/hidl/1.1/types.h> | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 61 | #include <codec2/hidl/1.2/types.h> | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 62 | #include <codec2/hidl/output.h> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 63 |  | 
|  | 64 | #include <cutils/native_handle.h> | 
|  | 65 | #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h> | 
|  | 66 | #include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 67 | #include <hardware/gralloc.h> // for GRALLOC_USAGE_* | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 68 | #include <hidl/HidlSupport.h> | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 69 | #include <system/window.h> // for NATIVE_WINDOW_QUERY_* | 
|  | 70 | #include <media/stagefright/foundation/ADebug.h> // for asString(status_t) | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 71 |  | 
|  | 72 | #include <deque> | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 73 | #include <iterator> | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 74 | #include <limits> | 
|  | 75 | #include <map> | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 76 | #include <mutex> | 
|  | 77 | #include <sstream> | 
|  | 78 | #include <thread> | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 79 | #include <type_traits> | 
|  | 80 | #include <vector> | 
|  | 81 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 82 | namespace android { | 
|  | 83 |  | 
|  | 84 | using ::android::hardware::hidl_vec; | 
|  | 85 | using ::android::hardware::hidl_string; | 
|  | 86 | using ::android::hardware::Return; | 
|  | 87 | using ::android::hardware::Void; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 88 |  | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 89 | using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue:: | 
|  | 90 | V1_0::IGraphicBufferProducer; | 
|  | 91 | using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue:: | 
|  | 92 | V2_0::IGraphicBufferProducer; | 
|  | 93 | using B2HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue:: | 
|  | 94 | V2_0::utils::B2HGraphicBufferProducer; | 
|  | 95 | using H2BGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue:: | 
|  | 96 | V2_0::utils::H2BGraphicBufferProducer; | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 97 | using ::android::hardware::media::c2::V1_2::SurfaceSyncObj; | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 98 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 99 | namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 100 | namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0; | 
|  | 101 | namespace c2_aidl = ::aidl::android::hardware::media::c2; | 
|  | 102 | namespace c2_hidl_base = ::android::hardware::media::c2; | 
|  | 103 | namespace c2_hidl = ::android::hardware::media::c2::V1_2; | 
|  | 104 |  | 
|  | 105 | using c2_hidl::utils::operator<<; | 
|  | 106 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 107 | namespace /* unnamed */ { | 
|  | 108 |  | 
|  | 109 | // c2_status_t value that corresponds to hwbinder transaction failure. | 
|  | 110 | constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED; | 
|  | 111 |  | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 112 | // By default prepare buffer to be displayed on any of the common surfaces | 
|  | 113 | constexpr uint64_t kDefaultConsumerUsage = | 
|  | 114 | (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER); | 
|  | 115 |  | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 116 | // Searches for a name in GetServiceNames() and returns the index found. If the | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 117 | // name is not found, the returned index will be equal to | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 118 | // GetServiceNames().size(). | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 119 | size_t getServiceIndex(char const* name) { | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 120 | std::vector<std::string> const& names = Codec2Client::GetServiceNames(); | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 121 | size_t i = 0; | 
|  | 122 | for (; i < names.size(); ++i) { | 
|  | 123 | if (name == names[i]) { | 
|  | 124 | break; | 
|  | 125 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 126 | } | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 127 | return i; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 128 | } | 
|  | 129 |  | 
| Pawin Vongmasa | 83d2c55 | 2020-03-05 04:36:08 -0800 | [diff] [blame] | 130 | class Client2Store : public C2ComponentStore { | 
|  | 131 | std::shared_ptr<Codec2Client> mClient; | 
|  | 132 |  | 
|  | 133 | public: | 
|  | 134 | Client2Store(std::shared_ptr<Codec2Client> const& client) | 
|  | 135 | : mClient(client) { } | 
|  | 136 |  | 
|  | 137 | virtual ~Client2Store() = default; | 
|  | 138 |  | 
|  | 139 | virtual c2_status_t config_sm( | 
|  | 140 | std::vector<C2Param*> const ¶ms, | 
|  | 141 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) { | 
|  | 142 | return mClient->config(params, C2_MAY_BLOCK, failures); | 
|  | 143 | }; | 
|  | 144 |  | 
|  | 145 | virtual c2_status_t copyBuffer( | 
|  | 146 | std::shared_ptr<C2GraphicBuffer>, | 
|  | 147 | std::shared_ptr<C2GraphicBuffer>) { | 
|  | 148 | return C2_OMITTED; | 
|  | 149 | } | 
|  | 150 |  | 
|  | 151 | virtual c2_status_t createComponent( | 
|  | 152 | C2String, std::shared_ptr<C2Component>* const component) { | 
|  | 153 | component->reset(); | 
|  | 154 | return C2_OMITTED; | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | virtual c2_status_t createInterface( | 
|  | 158 | C2String, std::shared_ptr<C2ComponentInterface>* const interface) { | 
|  | 159 | interface->reset(); | 
|  | 160 | return C2_OMITTED; | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | virtual c2_status_t query_sm( | 
|  | 164 | std::vector<C2Param*> const& stackParams, | 
|  | 165 | std::vector<C2Param::Index> const& heapParamIndices, | 
|  | 166 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const { | 
|  | 167 | return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams); | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | virtual c2_status_t querySupportedParams_nb( | 
|  | 171 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const { | 
|  | 172 | return mClient->querySupportedParams(params); | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | virtual c2_status_t querySupportedValues_sm( | 
|  | 176 | std::vector<C2FieldSupportedValuesQuery>& fields) const { | 
|  | 177 | return mClient->querySupportedValues(fields, C2_MAY_BLOCK); | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | virtual C2String getName() const { | 
|  | 181 | return mClient->getName(); | 
|  | 182 | } | 
|  | 183 |  | 
|  | 184 | virtual std::shared_ptr<C2ParamReflector> getParamReflector() const { | 
|  | 185 | return mClient->getParamReflector(); | 
|  | 186 | } | 
|  | 187 |  | 
|  | 188 | virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() { | 
|  | 189 | return std::vector<std::shared_ptr<C2Component::Traits const>>(); | 
|  | 190 | } | 
|  | 191 | }; | 
|  | 192 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 193 | c2_status_t GetC2Status(const ::ndk::ScopedAStatus &transStatus, const char *method) { | 
|  | 194 | if (!transStatus.isOk()) { | 
|  | 195 | if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) { | 
|  | 196 | c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError()); | 
|  | 197 | LOG(DEBUG) << method << " -- call failed: " << status << "."; | 
|  | 198 | return status; | 
|  | 199 | } else { | 
|  | 200 | LOG(ERROR) << method << " -- transaction failed."; | 
|  | 201 | return C2_TRANSACTION_FAILED; | 
|  | 202 | } | 
|  | 203 | } | 
|  | 204 | return C2_OK; | 
|  | 205 | } | 
|  | 206 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 207 | }  // unnamed namespace | 
|  | 208 |  | 
|  | 209 | // This class caches a Codec2Client object and its component traits. The client | 
|  | 210 | // will be created the first time it is needed, and it can be refreshed if the | 
|  | 211 | // service dies (by calling invalidate()). The first time listComponents() is | 
|  | 212 | // called from the client, the result will be cached. | 
|  | 213 | class Codec2Client::Cache { | 
|  | 214 | // Cached client | 
|  | 215 | std::shared_ptr<Codec2Client> mClient; | 
|  | 216 | mutable std::mutex mClientMutex; | 
|  | 217 |  | 
|  | 218 | // Cached component traits | 
|  | 219 | std::vector<C2Component::Traits> mTraits; | 
|  | 220 | std::once_flag mTraitsInitializationFlag; | 
|  | 221 |  | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 222 | // The index of the service. This is based on GetServiceNames(). | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 223 | size_t mIndex; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 224 | // Called by s() exactly once to initialize the cache. The index must be a | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 225 | // valid index into the vector returned by GetServiceNames(). Calling | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 226 | // init(index) will associate the cache to the service with name | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 227 | // GetServiceNames()[index]. | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 228 | void init(size_t index) { | 
|  | 229 | mIndex = index; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 230 | } | 
|  | 231 |  | 
|  | 232 | public: | 
|  | 233 | Cache() = default; | 
|  | 234 |  | 
|  | 235 | // Initializes mClient if needed, then returns mClient. | 
|  | 236 | // If the service is unavailable but listed in the manifest, this function | 
|  | 237 | // will block indefinitely. | 
|  | 238 | std::shared_ptr<Codec2Client> getClient() { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 239 | std::scoped_lock lock{mClientMutex}; | 
|  | 240 | if (!mClient) { | 
|  | 241 | mClient = Codec2Client::_CreateFromIndex(mIndex); | 
|  | 242 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 243 | CHECK(mClient) << "Failed to create Codec2Client to service \"" | 
|  | 244 | << GetServiceNames()[mIndex] << "\". (Index = " | 
|  | 245 | << mIndex << ")."; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 246 | return mClient; | 
|  | 247 | } | 
|  | 248 |  | 
|  | 249 | // Causes a subsequent call to getClient() to create a new client. This | 
|  | 250 | // function should be called after the service dies. | 
|  | 251 | // | 
|  | 252 | // Note: This function is called only by ForAllServices(). | 
|  | 253 | void invalidate() { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 254 | std::scoped_lock lock{mClientMutex}; | 
|  | 255 | mClient = nullptr; | 
|  | 256 | } | 
|  | 257 |  | 
|  | 258 | // Returns a list of traits for components supported by the service. This | 
|  | 259 | // list is cached. | 
|  | 260 | std::vector<C2Component::Traits> const& getTraits() { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 261 | std::call_once(mTraitsInitializationFlag, [this]() { | 
|  | 262 | bool success{false}; | 
|  | 263 | // Spin until _listComponents() is successful. | 
|  | 264 | while (true) { | 
|  | 265 | std::shared_ptr<Codec2Client> client = getClient(); | 
|  | 266 | mTraits = client->_listComponents(&success); | 
|  | 267 | if (success) { | 
|  | 268 | break; | 
|  | 269 | } | 
| Pawin Vongmasa | 21617db | 2020-04-24 06:16:42 -0700 | [diff] [blame] | 270 | invalidate(); | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 271 | using namespace std::chrono_literals; | 
|  | 272 | static constexpr auto kServiceRetryPeriod = 5s; | 
|  | 273 | LOG(INFO) << "Failed to retrieve component traits from service " | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 274 | "\"" << GetServiceNames()[mIndex] << "\". " | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 275 | "Retrying..."; | 
|  | 276 | std::this_thread::sleep_for(kServiceRetryPeriod); | 
|  | 277 | } | 
|  | 278 | }); | 
|  | 279 | return mTraits; | 
|  | 280 | } | 
|  | 281 |  | 
|  | 282 | // List() returns the list of all caches. | 
|  | 283 | static std::vector<Cache>& List() { | 
|  | 284 | static std::vector<Cache> sCaches{[]() { | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 285 | size_t numServices = GetServiceNames().size(); | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 286 | std::vector<Cache> caches(numServices); | 
|  | 287 | for (size_t i = 0; i < numServices; ++i) { | 
|  | 288 | caches[i].init(i); | 
|  | 289 | } | 
|  | 290 | return caches; | 
|  | 291 | }()}; | 
|  | 292 | return sCaches; | 
|  | 293 | } | 
|  | 294 | }; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 295 | // Codec2ConfigurableClient::HidlImpl | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 296 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 297 | struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase { | 
|  | 298 | typedef c2_hidl::IConfigurable Base; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 299 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 300 | // base cannot be null. | 
|  | 301 | explicit HidlImpl(const sp<Base>& base); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 302 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 303 | const C2String& getName() const override { | 
|  | 304 | return mName; | 
|  | 305 | } | 
|  | 306 |  | 
|  | 307 | c2_status_t query( | 
|  | 308 | const std::vector<C2Param*>& stackParams, | 
|  | 309 | const std::vector<C2Param::Index> &heapParamIndices, | 
|  | 310 | c2_blocking_t mayBlock, | 
|  | 311 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const override; | 
|  | 312 |  | 
|  | 313 | c2_status_t config( | 
|  | 314 | const std::vector<C2Param*> ¶ms, | 
|  | 315 | c2_blocking_t mayBlock, | 
|  | 316 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) override; | 
|  | 317 |  | 
|  | 318 | c2_status_t querySupportedParams( | 
|  | 319 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params | 
|  | 320 | ) const override; | 
|  | 321 |  | 
|  | 322 | c2_status_t querySupportedValues( | 
|  | 323 | std::vector<C2FieldSupportedValuesQuery>& fields, | 
|  | 324 | c2_blocking_t mayBlock) const override; | 
|  | 325 |  | 
|  | 326 | private: | 
|  | 327 | sp<Base> mBase; | 
|  | 328 | const C2String mName; | 
|  | 329 | }; | 
|  | 330 |  | 
|  | 331 | Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base) | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 332 | : mBase{base}, | 
|  | 333 | mName{[base]() -> C2String { | 
|  | 334 | C2String outName; | 
|  | 335 | Return<void> transStatus = base->getName( | 
|  | 336 | [&outName](const hidl_string& name) { | 
|  | 337 | outName = name.c_str(); | 
|  | 338 | }); | 
|  | 339 | return transStatus.isOk() ? outName : ""; | 
|  | 340 | }()} { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 341 | } | 
|  | 342 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 343 | c2_status_t Codec2ConfigurableClient::HidlImpl::query( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 344 | const std::vector<C2Param*> &stackParams, | 
|  | 345 | const std::vector<C2Param::Index> &heapParamIndices, | 
|  | 346 | c2_blocking_t mayBlock, | 
|  | 347 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 348 | hidl_vec<c2_hidl::ParamIndex> indices( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 349 | stackParams.size() + heapParamIndices.size()); | 
|  | 350 | size_t numIndices = 0; | 
|  | 351 | for (C2Param* const& stackParam : stackParams) { | 
|  | 352 | if (!stackParam) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 353 | LOG(WARNING) << "query -- null stack param encountered."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 354 | continue; | 
|  | 355 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 356 | indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 357 | } | 
|  | 358 | size_t numStackIndices = numIndices; | 
|  | 359 | for (const C2Param::Index& index : heapParamIndices) { | 
|  | 360 | indices[numIndices++] = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 361 | static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 362 | } | 
|  | 363 | indices.resize(numIndices); | 
|  | 364 | if (heapParams) { | 
|  | 365 | heapParams->reserve(heapParams->size() + numIndices); | 
|  | 366 | } | 
|  | 367 | c2_status_t status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 368 | Return<void> transStatus = mBase->query( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 369 | indices, | 
|  | 370 | mayBlock == C2_MAY_BLOCK, | 
|  | 371 | [&status, &numStackIndices, &stackParams, heapParams]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 372 | c2_hidl::Status s, const c2_hidl::Params& p) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 373 | status = static_cast<c2_status_t>(s); | 
|  | 374 | if (status != C2_OK && status != C2_BAD_INDEX) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 375 | LOG(DEBUG) << "query -- call failed: " | 
|  | 376 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 377 | return; | 
|  | 378 | } | 
|  | 379 | std::vector<C2Param*> paramPointers; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 380 | if (!c2_hidl::utils::parseParamsBlob(¶mPointers, p)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 381 | LOG(ERROR) << "query -- error while parsing params."; | 
|  | 382 | status = C2_CORRUPTED; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 383 | return; | 
|  | 384 | } | 
|  | 385 | size_t i = 0; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 386 | for (auto it = paramPointers.begin(); | 
|  | 387 | it != paramPointers.end(); ) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 388 | C2Param* paramPointer = *it; | 
|  | 389 | if (numStackIndices > 0) { | 
|  | 390 | --numStackIndices; | 
|  | 391 | if (!paramPointer) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 392 | LOG(WARNING) << "query -- null stack param."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 393 | ++it; | 
|  | 394 | continue; | 
|  | 395 | } | 
|  | 396 | for (; i < stackParams.size() && !stackParams[i]; ) { | 
|  | 397 | ++i; | 
|  | 398 | } | 
|  | 399 | if (i >= stackParams.size()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 400 | LOG(ERROR) << "query -- unexpected error."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 401 | status = C2_CORRUPTED; | 
|  | 402 | return; | 
|  | 403 | } | 
|  | 404 | if (stackParams[i]->index() != paramPointer->index()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 405 | LOG(WARNING) << "query -- param skipped: " | 
|  | 406 | "index = " | 
|  | 407 | << stackParams[i]->index() << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 408 | stackParams[i++]->invalidate(); | 
|  | 409 | continue; | 
|  | 410 | } | 
|  | 411 | if (!stackParams[i++]->updateFrom(*paramPointer)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 412 | LOG(WARNING) << "query -- param update failed: " | 
|  | 413 | "index = " | 
|  | 414 | << paramPointer->index() << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 415 | } | 
|  | 416 | } else { | 
|  | 417 | if (!paramPointer) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 418 | LOG(WARNING) << "query -- null heap param."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 419 | ++it; | 
|  | 420 | continue; | 
|  | 421 | } | 
|  | 422 | if (!heapParams) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 423 | LOG(WARNING) << "query -- " | 
|  | 424 | "unexpected extra stack param."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 425 | } else { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 426 | heapParams->emplace_back( | 
|  | 427 | C2Param::Copy(*paramPointer)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 428 | } | 
|  | 429 | } | 
|  | 430 | ++it; | 
|  | 431 | } | 
|  | 432 | }); | 
|  | 433 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 434 | LOG(ERROR) << "query -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 435 | return C2_TRANSACTION_FAILED; | 
|  | 436 | } | 
|  | 437 | return status; | 
|  | 438 | } | 
|  | 439 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 440 | c2_status_t Codec2ConfigurableClient::HidlImpl::config( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 441 | const std::vector<C2Param*> ¶ms, | 
|  | 442 | c2_blocking_t mayBlock, | 
|  | 443 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 444 | c2_hidl::Params hidlParams; | 
|  | 445 | if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 446 | LOG(ERROR) << "config -- bad input."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 447 | return C2_TRANSACTION_FAILED; | 
|  | 448 | } | 
|  | 449 | c2_status_t status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 450 | Return<void> transStatus = mBase->config( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 451 | hidlParams, | 
|  | 452 | mayBlock == C2_MAY_BLOCK, | 
|  | 453 | [&status, ¶ms, failures]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 454 | c2_hidl::Status s, | 
|  | 455 | const hidl_vec<c2_hidl::SettingResult> f, | 
|  | 456 | const c2_hidl::Params& o) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 457 | status = static_cast<c2_status_t>(s); | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 458 | if (status != C2_OK && status != C2_BAD_INDEX) { | 
|  | 459 | LOG(DEBUG) << "config -- call failed: " | 
|  | 460 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 461 | } | 
|  | 462 | size_t i = failures->size(); | 
|  | 463 | failures->resize(i + f.size()); | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 464 | for (const c2_hidl::SettingResult& sf : f) { | 
|  | 465 | if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 466 | LOG(ERROR) << "config -- " | 
|  | 467 | << "invalid SettingResult returned."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 468 | return; | 
|  | 469 | } | 
|  | 470 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 471 | if (!c2_hidl::utils::updateParamsFromBlob(params, o)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 472 | LOG(ERROR) << "config -- " | 
|  | 473 | << "failed to parse returned params."; | 
|  | 474 | status = C2_CORRUPTED; | 
|  | 475 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 476 | }); | 
|  | 477 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 478 | LOG(ERROR) << "config -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 479 | return C2_TRANSACTION_FAILED; | 
|  | 480 | } | 
|  | 481 | return status; | 
|  | 482 | } | 
|  | 483 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 484 | c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 485 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const { | 
|  | 486 | // TODO: Cache and query properly! | 
|  | 487 | c2_status_t status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 488 | Return<void> transStatus = mBase->querySupportedParams( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 489 | std::numeric_limits<uint32_t>::min(), | 
|  | 490 | std::numeric_limits<uint32_t>::max(), | 
|  | 491 | [&status, params]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 492 | c2_hidl::Status s, | 
|  | 493 | const hidl_vec<c2_hidl::ParamDescriptor>& p) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 494 | status = static_cast<c2_status_t>(s); | 
|  | 495 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 496 | LOG(DEBUG) << "querySupportedParams -- call failed: " | 
|  | 497 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 498 | return; | 
|  | 499 | } | 
|  | 500 | size_t i = params->size(); | 
|  | 501 | params->resize(i + p.size()); | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 502 | for (const c2_hidl::ParamDescriptor& sp : p) { | 
|  | 503 | if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 504 | LOG(ERROR) << "querySupportedParams -- " | 
|  | 505 | << "invalid returned ParamDescriptor."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 506 | return; | 
|  | 507 | } | 
|  | 508 | } | 
|  | 509 | }); | 
|  | 510 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 511 | LOG(ERROR) << "querySupportedParams -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 512 | return C2_TRANSACTION_FAILED; | 
|  | 513 | } | 
|  | 514 | return status; | 
|  | 515 | } | 
|  | 516 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 517 | c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 518 | std::vector<C2FieldSupportedValuesQuery>& fields, | 
|  | 519 | c2_blocking_t mayBlock) const { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 520 | hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 521 | for (size_t i = 0; i < fields.size(); ++i) { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 522 | if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 523 | LOG(ERROR) << "querySupportedValues -- bad input"; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 524 | return C2_TRANSACTION_FAILED; | 
|  | 525 | } | 
|  | 526 | } | 
|  | 527 |  | 
|  | 528 | c2_status_t status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 529 | Return<void> transStatus = mBase->querySupportedValues( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 530 | inFields, | 
|  | 531 | mayBlock == C2_MAY_BLOCK, | 
|  | 532 | [&status, &inFields, &fields]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 533 | c2_hidl::Status s, | 
|  | 534 | const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 535 | status = static_cast<c2_status_t>(s); | 
|  | 536 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 537 | LOG(DEBUG) << "querySupportedValues -- call failed: " | 
|  | 538 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 539 | return; | 
|  | 540 | } | 
|  | 541 | if (r.size() != fields.size()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 542 | LOG(ERROR) << "querySupportedValues -- " | 
|  | 543 | "input and output lists " | 
|  | 544 | "have different sizes."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 545 | status = C2_CORRUPTED; | 
|  | 546 | return; | 
|  | 547 | } | 
|  | 548 | for (size_t i = 0; i < fields.size(); ++i) { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 549 | if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 550 | LOG(ERROR) << "querySupportedValues -- " | 
|  | 551 | "invalid returned value."; | 
|  | 552 | status = C2_CORRUPTED; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 553 | return; | 
|  | 554 | } | 
|  | 555 | } | 
|  | 556 | }); | 
|  | 557 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 558 | LOG(ERROR) << "querySupportedValues -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 559 | return C2_TRANSACTION_FAILED; | 
|  | 560 | } | 
|  | 561 | return status; | 
|  | 562 | } | 
|  | 563 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 564 | // Codec2ConfigurableClient::AidlImpl | 
|  | 565 |  | 
|  | 566 | struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase { | 
|  | 567 | typedef c2_aidl::IConfigurable Base; | 
|  | 568 |  | 
|  | 569 | // base cannot be null. | 
|  | 570 | explicit AidlImpl(const std::shared_ptr<Base>& base); | 
|  | 571 |  | 
|  | 572 | const C2String& getName() const override { | 
|  | 573 | return mName; | 
|  | 574 | } | 
|  | 575 |  | 
|  | 576 | c2_status_t query( | 
|  | 577 | const std::vector<C2Param*>& stackParams, | 
|  | 578 | const std::vector<C2Param::Index> &heapParamIndices, | 
|  | 579 | c2_blocking_t mayBlock, | 
|  | 580 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const override; | 
|  | 581 |  | 
|  | 582 | c2_status_t config( | 
|  | 583 | const std::vector<C2Param*> ¶ms, | 
|  | 584 | c2_blocking_t mayBlock, | 
|  | 585 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) override; | 
|  | 586 |  | 
|  | 587 | c2_status_t querySupportedParams( | 
|  | 588 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params | 
|  | 589 | ) const override; | 
|  | 590 |  | 
|  | 591 | c2_status_t querySupportedValues( | 
|  | 592 | std::vector<C2FieldSupportedValuesQuery>& fields, | 
|  | 593 | c2_blocking_t mayBlock) const override; | 
|  | 594 |  | 
|  | 595 | private: | 
|  | 596 | std::shared_ptr<Base> mBase; | 
|  | 597 | const C2String mName; | 
|  | 598 | }; | 
|  | 599 |  | 
|  | 600 | Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base) | 
|  | 601 | : mBase{base}, | 
|  | 602 | mName{[base]() -> C2String { | 
|  | 603 | std::string outName; | 
|  | 604 | ndk::ScopedAStatus status = base->getName(&outName); | 
|  | 605 | return status.isOk() ? outName : ""; | 
|  | 606 | }()} { | 
|  | 607 | } | 
|  | 608 |  | 
|  | 609 | c2_status_t Codec2ConfigurableClient::AidlImpl::query( | 
|  | 610 | const std::vector<C2Param*> &stackParams, | 
|  | 611 | const std::vector<C2Param::Index> &heapParamIndices, | 
|  | 612 | c2_blocking_t mayBlock, | 
|  | 613 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const { | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 614 | std::vector<int> indices( | 
|  | 615 | stackParams.size() + heapParamIndices.size()); | 
|  | 616 | size_t numIndices = 0; | 
|  | 617 | for (C2Param* const& stackParam : stackParams) { | 
|  | 618 | if (!stackParam) { | 
|  | 619 | LOG(WARNING) << "query -- null stack param encountered."; | 
|  | 620 | continue; | 
|  | 621 | } | 
|  | 622 | indices[numIndices++] = int(stackParam->index()); | 
|  | 623 | } | 
|  | 624 | size_t numStackIndices = numIndices; | 
|  | 625 | for (const C2Param::Index& index : heapParamIndices) { | 
|  | 626 | indices[numIndices++] = int(static_cast<uint32_t>(index)); | 
|  | 627 | } | 
|  | 628 | indices.resize(numIndices); | 
|  | 629 | if (heapParams) { | 
|  | 630 | heapParams->reserve(heapParams->size() + numIndices); | 
|  | 631 | } | 
|  | 632 | c2_aidl::Params result; | 
|  | 633 | ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 634 | c2_status_t status = GetC2Status(transStatus, "query"); | 
|  | 635 | if (status != C2_OK) { | 
|  | 636 | return status; | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 637 | } | 
|  | 638 |  | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 639 | std::vector<C2Param*> paramPointers; | 
|  | 640 | if (!c2_aidl::utils::ParseParamsBlob(¶mPointers, result)) { | 
|  | 641 | LOG(ERROR) << "query -- error while parsing params."; | 
|  | 642 | return C2_CORRUPTED; | 
|  | 643 | } | 
|  | 644 | size_t i = 0; | 
|  | 645 | for (auto it = paramPointers.begin(); | 
|  | 646 | it != paramPointers.end(); ) { | 
|  | 647 | C2Param* paramPointer = *it; | 
|  | 648 | if (numStackIndices > 0) { | 
|  | 649 | --numStackIndices; | 
|  | 650 | if (!paramPointer) { | 
|  | 651 | LOG(DEBUG) << "query -- null stack param."; | 
|  | 652 | ++it; | 
|  | 653 | continue; | 
|  | 654 | } | 
|  | 655 | for (; i < stackParams.size() && !stackParams[i]; ) { | 
|  | 656 | ++i; | 
|  | 657 | } | 
|  | 658 | if (i >= stackParams.size()) { | 
|  | 659 | LOG(ERROR) << "query -- unexpected error."; | 
|  | 660 | status = C2_CORRUPTED; | 
|  | 661 | break; | 
|  | 662 | } | 
|  | 663 | if (stackParams[i]->index() != paramPointer->index()) { | 
|  | 664 | LOG(DEBUG) << "query -- param skipped: " | 
|  | 665 | "index = " | 
|  | 666 | << stackParams[i]->index() << "."; | 
|  | 667 | stackParams[i++]->invalidate(); | 
|  | 668 | // this means that the param could not be queried. | 
|  | 669 | // signalling C2_BAD_INDEX to the client. | 
|  | 670 | status = C2_BAD_INDEX; | 
|  | 671 | continue; | 
|  | 672 | } | 
|  | 673 | if (!stackParams[i++]->updateFrom(*paramPointer)) { | 
|  | 674 | LOG(WARNING) << "query -- param update failed: " | 
|  | 675 | "index = " | 
|  | 676 | << paramPointer->index() << "."; | 
|  | 677 | } | 
|  | 678 | } else { | 
|  | 679 | if (!paramPointer) { | 
|  | 680 | LOG(DEBUG) << "query -- null heap param."; | 
|  | 681 | ++it; | 
|  | 682 | continue; | 
|  | 683 | } | 
|  | 684 | if (!heapParams) { | 
|  | 685 | LOG(WARNING) << "query -- " | 
|  | 686 | "unexpected extra stack param."; | 
|  | 687 | } else { | 
|  | 688 | heapParams->emplace_back(C2Param::Copy(*paramPointer)); | 
|  | 689 | } | 
|  | 690 | } | 
|  | 691 | ++it; | 
|  | 692 | } | 
|  | 693 | return status; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 694 | } | 
|  | 695 |  | 
|  | 696 | c2_status_t Codec2ConfigurableClient::AidlImpl::config( | 
|  | 697 | const std::vector<C2Param*> ¶ms, | 
|  | 698 | c2_blocking_t mayBlock, | 
|  | 699 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) { | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 700 | c2_aidl::Params aidlParams; | 
|  | 701 | if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) { | 
|  | 702 | LOG(ERROR) << "config -- bad input."; | 
|  | 703 | return C2_TRANSACTION_FAILED; | 
|  | 704 | } | 
|  | 705 | c2_aidl::IConfigurable::ConfigResult result; | 
|  | 706 | ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 707 | c2_status_t status = GetC2Status(transStatus, "config"); | 
|  | 708 | if (status != C2_OK) { | 
|  | 709 | return status; | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 710 | } | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 711 | size_t i = failures->size(); | 
|  | 712 | failures->resize(i + result.failures.size()); | 
|  | 713 | for (const c2_aidl::SettingResult& sf : result.failures) { | 
|  | 714 | if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) { | 
|  | 715 | LOG(ERROR) << "config -- invalid SettingResult returned."; | 
|  | 716 | return C2_CORRUPTED; | 
|  | 717 | } | 
|  | 718 | } | 
|  | 719 | if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) { | 
|  | 720 | LOG(ERROR) << "config -- " | 
|  | 721 | << "failed to parse returned params."; | 
|  | 722 | status = C2_CORRUPTED; | 
|  | 723 | } | 
|  | 724 | return status; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 725 | } | 
|  | 726 |  | 
|  | 727 | c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams( | 
|  | 728 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const { | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 729 | // TODO: Cache and query properly! | 
|  | 730 | std::vector<c2_aidl::ParamDescriptor> result; | 
|  | 731 | ndk::ScopedAStatus transStatus = mBase->querySupportedParams( | 
|  | 732 | std::numeric_limits<uint32_t>::min(), | 
|  | 733 | std::numeric_limits<uint32_t>::max(), | 
|  | 734 | &result); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 735 | c2_status_t status = GetC2Status(transStatus, "querySupportedParams"); | 
|  | 736 | if (status != C2_OK) { | 
|  | 737 | return status; | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 738 | } | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 739 | size_t i = params->size(); | 
|  | 740 | params->resize(i + result.size()); | 
|  | 741 | for (const c2_aidl::ParamDescriptor& sp : result) { | 
|  | 742 | if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) { | 
|  | 743 | LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor."; | 
|  | 744 | return C2_CORRUPTED; | 
|  | 745 | } | 
|  | 746 | } | 
|  | 747 | return status; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 748 | } | 
|  | 749 |  | 
|  | 750 | c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues( | 
|  | 751 | std::vector<C2FieldSupportedValuesQuery>& fields, | 
|  | 752 | c2_blocking_t mayBlock) const { | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 753 | std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size()); | 
|  | 754 | for (size_t i = 0; i < fields.size(); ++i) { | 
|  | 755 | if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) { | 
|  | 756 | LOG(ERROR) << "querySupportedValues -- bad input"; | 
|  | 757 | return C2_TRANSACTION_FAILED; | 
|  | 758 | } | 
|  | 759 | } | 
|  | 760 |  | 
|  | 761 | std::vector<c2_aidl::FieldSupportedValuesQueryResult> result; | 
|  | 762 | ndk::ScopedAStatus transStatus = mBase->querySupportedValues( | 
|  | 763 | inFields, (mayBlock == C2_MAY_BLOCK), &result); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 764 | c2_status_t status = GetC2Status(transStatus, "querySupportedValues"); | 
|  | 765 | if (status != C2_OK) { | 
|  | 766 | return status; | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 767 | } | 
| Wonsik Kim | 1caded0 | 2022-12-09 13:03:11 -0800 | [diff] [blame] | 768 | if (result.size() != fields.size()) { | 
|  | 769 | LOG(ERROR) << "querySupportedValues -- " | 
|  | 770 | "input and output lists " | 
|  | 771 | "have different sizes."; | 
|  | 772 | return C2_CORRUPTED; | 
|  | 773 | } | 
|  | 774 | for (size_t i = 0; i < fields.size(); ++i) { | 
|  | 775 | if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) { | 
|  | 776 | LOG(ERROR) << "querySupportedValues -- " | 
|  | 777 | "invalid returned value."; | 
|  | 778 | return C2_CORRUPTED; | 
|  | 779 | } | 
|  | 780 | } | 
|  | 781 | return status; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 782 | } | 
|  | 783 |  | 
|  | 784 | // Codec2ConfigurableClient | 
|  | 785 |  | 
|  | 786 | Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase) | 
|  | 787 | : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) { | 
|  | 788 | } | 
|  | 789 |  | 
|  | 790 | Codec2ConfigurableClient::Codec2ConfigurableClient( | 
|  | 791 | const std::shared_ptr<AidlBase> &aidlBase) | 
|  | 792 | : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) { | 
|  | 793 | } | 
|  | 794 |  | 
|  | 795 | const C2String& Codec2ConfigurableClient::getName() const { | 
|  | 796 | return mImpl->getName(); | 
|  | 797 | } | 
|  | 798 |  | 
|  | 799 | c2_status_t Codec2ConfigurableClient::query( | 
|  | 800 | const std::vector<C2Param*>& stackParams, | 
|  | 801 | const std::vector<C2Param::Index> &heapParamIndices, | 
|  | 802 | c2_blocking_t mayBlock, | 
|  | 803 | std::vector<std::unique_ptr<C2Param>>* const heapParams) const { | 
|  | 804 | return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams); | 
|  | 805 | } | 
|  | 806 |  | 
|  | 807 | c2_status_t Codec2ConfigurableClient::config( | 
|  | 808 | const std::vector<C2Param*> ¶ms, | 
|  | 809 | c2_blocking_t mayBlock, | 
|  | 810 | std::vector<std::unique_ptr<C2SettingResult>>* const failures) { | 
|  | 811 | return mImpl->config(params, mayBlock, failures); | 
|  | 812 | } | 
|  | 813 |  | 
|  | 814 | c2_status_t Codec2ConfigurableClient::querySupportedParams( | 
|  | 815 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const { | 
|  | 816 | return mImpl->querySupportedParams(params); | 
|  | 817 | } | 
|  | 818 |  | 
|  | 819 | c2_status_t Codec2ConfigurableClient::querySupportedValues( | 
|  | 820 | std::vector<C2FieldSupportedValuesQuery>& fields, | 
|  | 821 | c2_blocking_t mayBlock) const { | 
|  | 822 | return mImpl->querySupportedValues(fields, mayBlock); | 
|  | 823 | } | 
|  | 824 |  | 
|  | 825 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 826 | // Codec2Client::Component::HidlListener | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 827 | struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 828 | std::weak_ptr<Component> component; | 
|  | 829 | std::weak_ptr<Listener> base; | 
|  | 830 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 831 | virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 832 | std::list<std::unique_ptr<C2Work>> workItems; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 833 | if (!c2_hidl::utils::objcpy(&workItems, workBundle)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 834 | LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 835 | return Void(); | 
|  | 836 | } | 
|  | 837 | // release input buffers potentially held by the component from queue | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 838 | std::shared_ptr<Codec2Client::Component> strongComponent = | 
|  | 839 | component.lock(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 840 | if (strongComponent) { | 
| Wonsik Kim | ab34ed6 | 2019-01-31 15:28:46 -0800 | [diff] [blame] | 841 | strongComponent->handleOnWorkDone(workItems); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 842 | } | 
|  | 843 | if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) { | 
| Wonsik Kim | ab34ed6 | 2019-01-31 15:28:46 -0800 | [diff] [blame] | 844 | listener->onWorkDone(component, workItems); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 845 | } else { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 846 | LOG(DEBUG) << "onWorkDone -- listener died."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 847 | } | 
|  | 848 | return Void(); | 
|  | 849 | } | 
|  | 850 |  | 
|  | 851 | virtual Return<void> onTripped( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 852 | const hidl_vec<c2_hidl::SettingResult>& settingResults) override { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 853 | std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults( | 
|  | 854 | settingResults.size()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 855 | for (size_t i = 0; i < settingResults.size(); ++i) { | 
|  | 856 | std::unique_ptr<C2SettingResult> c2SettingResult; | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 857 | if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 858 | LOG(DEBUG) << "onTripped -- received corrupted SettingResult."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 859 | return Void(); | 
|  | 860 | } | 
|  | 861 | c2SettingResults[i] = std::move(c2SettingResult); | 
|  | 862 | } | 
|  | 863 | if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) { | 
|  | 864 | listener->onTripped(component, c2SettingResults); | 
|  | 865 | } else { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 866 | LOG(DEBUG) << "onTripped -- listener died."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 867 | } | 
|  | 868 | return Void(); | 
|  | 869 | } | 
|  | 870 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 871 | virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 872 | LOG(DEBUG) << "onError --" | 
|  | 873 | << " status = " << s | 
|  | 874 | << ", errorCode = " << errorCode | 
|  | 875 | << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 876 | if (std::shared_ptr<Listener> listener = base.lock()) { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 877 | listener->onError(component, s == c2_hidl::Status::OK ? | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 878 | errorCode : static_cast<c2_status_t>(s)); | 
|  | 879 | } else { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 880 | LOG(DEBUG) << "onError -- listener died."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 881 | } | 
|  | 882 | return Void(); | 
|  | 883 | } | 
|  | 884 |  | 
|  | 885 | virtual Return<void> onFramesRendered( | 
|  | 886 | const hidl_vec<RenderedFrame>& renderedFrames) override { | 
|  | 887 | std::shared_ptr<Listener> listener = base.lock(); | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 888 | if (!listener) { | 
|  | 889 | LOG(DEBUG) << "onFramesRendered -- listener died."; | 
|  | 890 | return Void(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 891 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 892 | for (const RenderedFrame& renderedFrame : renderedFrames) { | 
|  | 893 | listener->onFrameRendered( | 
|  | 894 | renderedFrame.bufferQueueId, | 
|  | 895 | renderedFrame.slotId, | 
|  | 896 | renderedFrame.timestampNs); | 
|  | 897 | } | 
|  | 898 | return Void(); | 
|  | 899 | } | 
|  | 900 |  | 
|  | 901 | virtual Return<void> onInputBuffersReleased( | 
|  | 902 | const hidl_vec<InputBuffer>& inputBuffers) override { | 
|  | 903 | std::shared_ptr<Listener> listener = base.lock(); | 
|  | 904 | if (!listener) { | 
|  | 905 | LOG(DEBUG) << "onInputBuffersReleased -- listener died."; | 
|  | 906 | return Void(); | 
|  | 907 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 908 | for (const InputBuffer& inputBuffer : inputBuffers) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 909 | LOG(VERBOSE) << "onInputBuffersReleased --" | 
|  | 910 | " received death notification of" | 
|  | 911 | " input buffer:" | 
|  | 912 | " frameIndex = " << inputBuffer.frameIndex | 
|  | 913 | << ", bufferIndex = " << inputBuffer.arrayIndex | 
|  | 914 | << "."; | 
| Wonsik Kim | ab34ed6 | 2019-01-31 15:28:46 -0800 | [diff] [blame] | 915 | listener->onInputBufferDone( | 
|  | 916 | inputBuffer.frameIndex, inputBuffer.arrayIndex); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 917 | } | 
|  | 918 | return Void(); | 
|  | 919 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 920 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 921 | }; | 
|  | 922 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 923 | // Codec2Client::Component::AidlListener | 
|  | 924 | struct Codec2Client::Component::AidlListener : public c2_aidl::BnComponentListener { | 
|  | 925 | std::weak_ptr<Component> component; | 
|  | 926 | std::weak_ptr<Listener> base; | 
|  | 927 |  | 
|  | 928 | virtual ::ndk::ScopedAStatus onWorkDone(const c2_aidl::WorkBundle& workBundle) override { | 
|  | 929 | std::list<std::unique_ptr<C2Work>> workItems; | 
|  | 930 | if (!c2_aidl::utils::FromAidl(&workItems, workBundle)) { | 
|  | 931 | LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle."; | 
|  | 932 | return ::ndk::ScopedAStatus::ok(); | 
|  | 933 | } | 
|  | 934 | // release input buffers potentially held by the component from queue | 
|  | 935 | std::shared_ptr<Codec2Client::Component> strongComponent = | 
|  | 936 | component.lock(); | 
|  | 937 | if (strongComponent) { | 
|  | 938 | strongComponent->handleOnWorkDone(workItems); | 
|  | 939 | } | 
|  | 940 | if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) { | 
|  | 941 | listener->onWorkDone(component, workItems); | 
|  | 942 | } else { | 
|  | 943 | LOG(DEBUG) << "onWorkDone -- listener died."; | 
|  | 944 | } | 
|  | 945 | return ::ndk::ScopedAStatus::ok(); | 
|  | 946 | } | 
|  | 947 |  | 
|  | 948 | virtual ::ndk::ScopedAStatus onTripped( | 
|  | 949 | const std::vector<c2_aidl::SettingResult>& settingResults) override { | 
|  | 950 | std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults( | 
|  | 951 | settingResults.size()); | 
|  | 952 | for (size_t i = 0; i < settingResults.size(); ++i) { | 
|  | 953 | std::unique_ptr<C2SettingResult> c2SettingResult; | 
|  | 954 | if (!c2_aidl::utils::FromAidl(&c2SettingResult, settingResults[i])) { | 
|  | 955 | LOG(DEBUG) << "onTripped -- received corrupted SettingResult."; | 
|  | 956 | return ::ndk::ScopedAStatus::ok(); | 
|  | 957 | } | 
|  | 958 | c2SettingResults[i] = std::move(c2SettingResult); | 
|  | 959 | } | 
|  | 960 | if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) { | 
|  | 961 | listener->onTripped(component, c2SettingResults); | 
|  | 962 | } else { | 
|  | 963 | LOG(DEBUG) << "onTripped -- listener died."; | 
|  | 964 | } | 
|  | 965 | return ::ndk::ScopedAStatus::ok(); | 
|  | 966 | } | 
|  | 967 |  | 
|  | 968 | virtual ::ndk::ScopedAStatus onError(const c2_aidl::Status &s, int32_t errorCode) override { | 
|  | 969 | LOG(DEBUG) << "onError --" | 
|  | 970 | << " status = " << s.status | 
|  | 971 | << ", errorCode = " << errorCode | 
|  | 972 | << "."; | 
|  | 973 | if (std::shared_ptr<Listener> listener = base.lock()) { | 
|  | 974 | listener->onError(component, s.status == c2_aidl::Status::OK ? | 
|  | 975 | errorCode : static_cast<c2_status_t>(s.status)); | 
|  | 976 | } else { | 
|  | 977 | LOG(DEBUG) << "onError -- listener died."; | 
|  | 978 | } | 
|  | 979 | return ::ndk::ScopedAStatus::ok(); | 
|  | 980 | } | 
|  | 981 |  | 
|  | 982 | virtual ::ndk::ScopedAStatus onFramesRendered( | 
|  | 983 | const std::vector<RenderedFrame>& renderedFrames) override { | 
|  | 984 | std::shared_ptr<Listener> listener = base.lock(); | 
|  | 985 | if (!listener) { | 
|  | 986 | LOG(DEBUG) << "onFramesRendered -- listener died."; | 
|  | 987 | return ::ndk::ScopedAStatus::ok(); | 
|  | 988 | } | 
|  | 989 | for (const RenderedFrame& renderedFrame : renderedFrames) { | 
|  | 990 | listener->onFrameRendered( | 
|  | 991 | renderedFrame.bufferQueueId, | 
|  | 992 | renderedFrame.slotId, | 
|  | 993 | renderedFrame.timestampNs); | 
|  | 994 | } | 
|  | 995 | return ::ndk::ScopedAStatus::ok(); | 
|  | 996 | } | 
|  | 997 |  | 
|  | 998 | virtual ::ndk::ScopedAStatus onInputBuffersReleased( | 
|  | 999 | const std::vector<InputBuffer>& inputBuffers) override { | 
|  | 1000 | std::shared_ptr<Listener> listener = base.lock(); | 
|  | 1001 | if (!listener) { | 
|  | 1002 | LOG(DEBUG) << "onInputBuffersReleased -- listener died."; | 
|  | 1003 | return ::ndk::ScopedAStatus::ok(); | 
|  | 1004 | } | 
|  | 1005 | for (const InputBuffer& inputBuffer : inputBuffers) { | 
|  | 1006 | LOG(VERBOSE) << "onInputBuffersReleased --" | 
|  | 1007 | " received death notification of" | 
|  | 1008 | " input buffer:" | 
|  | 1009 | " frameIndex = " << inputBuffer.frameIndex | 
|  | 1010 | << ", bufferIndex = " << inputBuffer.arrayIndex | 
|  | 1011 | << "."; | 
|  | 1012 | listener->onInputBufferDone( | 
|  | 1013 | inputBuffer.frameIndex, inputBuffer.arrayIndex); | 
|  | 1014 | } | 
|  | 1015 | return ::ndk::ScopedAStatus::ok(); | 
|  | 1016 | } | 
|  | 1017 |  | 
|  | 1018 | }; | 
|  | 1019 |  | 
|  | 1020 | // Codec2Client::Component::HidlBufferPoolSender | 
|  | 1021 | struct Codec2Client::Component::HidlBufferPoolSender : | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1022 | hardware::media::c2::V1_1::utils::DefaultBufferPoolSender { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1023 | HidlBufferPoolSender() | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1024 | : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() { | 
|  | 1025 | } | 
|  | 1026 | }; | 
|  | 1027 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1028 | // Codec2Client::Component::AidlBufferPoolSender | 
|  | 1029 | struct Codec2Client::Component::AidlBufferPoolSender : | 
|  | 1030 | c2_aidl::utils::DefaultBufferPoolSender { | 
|  | 1031 | AidlBufferPoolSender() | 
|  | 1032 | : c2_aidl::utils::DefaultBufferPoolSender() { | 
|  | 1033 | } | 
|  | 1034 | }; | 
|  | 1035 |  | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1036 | // Codec2Client::Component::OutputBufferQueue | 
|  | 1037 | struct Codec2Client::Component::OutputBufferQueue : | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 1038 | hardware::media::c2::OutputBufferQueue { | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1039 | OutputBufferQueue() | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 1040 | : hardware::media::c2::OutputBufferQueue() { | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1041 | } | 
|  | 1042 | }; | 
|  | 1043 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1044 | // Codec2Client | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1045 | Codec2Client::Codec2Client(sp<HidlBase> const& base, | 
| Sungtak Lee | f4b3951 | 2023-05-10 07:17:22 +0000 | [diff] [blame] | 1046 | sp<c2_hidl::IConfigurable> const& configurable, | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1047 | size_t serviceIndex) | 
| Sungtak Lee | f4b3951 | 2023-05-10 07:17:22 +0000 | [diff] [blame] | 1048 | : Configurable{configurable}, | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1049 | mHidlBase1_0{base}, | 
|  | 1050 | mHidlBase1_1{HidlBase1_1::castFrom(base)}, | 
|  | 1051 | mHidlBase1_2{HidlBase1_2::castFrom(base)}, | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1052 | mServiceIndex{serviceIndex} { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1053 | Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1054 | if (!transResult.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1055 | LOG(ERROR) << "getPoolClientManager -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1056 | } else { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1057 | mHidlHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1058 | } | 
|  | 1059 | } | 
|  | 1060 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1061 | Codec2Client::Codec2Client(std::shared_ptr<AidlBase> const& base, | 
|  | 1062 | std::shared_ptr<c2_aidl::IConfigurable> const& configurable, | 
|  | 1063 | size_t serviceIndex) | 
|  | 1064 | : Configurable{configurable}, | 
|  | 1065 | mAidlBase{base}, | 
|  | 1066 | mServiceIndex{serviceIndex} { | 
|  | 1067 | ::ndk::ScopedAStatus transStatus = base->getPoolClientManager(&mAidlHostPoolManager); | 
|  | 1068 | if (!transStatus.isOk()) { | 
|  | 1069 | LOG(ERROR) << "getPoolClientManager -- transaction failed."; | 
|  | 1070 | mAidlHostPoolManager.reset(); | 
|  | 1071 | } | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1072 | } | 
|  | 1073 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1074 | sp<Codec2Client::HidlBase> const& Codec2Client::getHidlBase() const { | 
|  | 1075 | return mHidlBase1_0; | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1076 | } | 
|  | 1077 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1078 | sp<Codec2Client::HidlBase1_0> const& Codec2Client::getHidlBase1_0() const { | 
|  | 1079 | return mHidlBase1_0; | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1080 | } | 
|  | 1081 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1082 | sp<Codec2Client::HidlBase1_1> const& Codec2Client::getHidlBase1_1() const { | 
|  | 1083 | return mHidlBase1_1; | 
|  | 1084 | } | 
|  | 1085 |  | 
|  | 1086 | sp<Codec2Client::HidlBase1_2> const& Codec2Client::getHidlBase1_2() const { | 
|  | 1087 | return mHidlBase1_2; | 
|  | 1088 | } | 
|  | 1089 |  | 
|  | 1090 | ::ndk::SpAIBinder Codec2Client::getAidlBase() const { | 
|  | 1091 | return mAidlBase ? mAidlBase->asBinder() : nullptr; | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1092 | } | 
|  | 1093 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1094 | std::string const& Codec2Client::getServiceName() const { | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1095 | return GetServiceNames()[mServiceIndex]; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1096 | } | 
|  | 1097 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1098 | c2_status_t Codec2Client::createComponent( | 
|  | 1099 | const C2String& name, | 
|  | 1100 | const std::shared_ptr<Codec2Client::Listener>& listener, | 
|  | 1101 | std::shared_ptr<Codec2Client::Component>* const component) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1102 | if (mAidlBase) { | 
|  | 1103 | std::shared_ptr<Component::AidlListener> aidlListener = | 
|  | 1104 | Component::AidlListener::make<Component::AidlListener>(); | 
|  | 1105 | aidlListener->base = listener; | 
|  | 1106 | std::shared_ptr<c2_aidl::IComponent> aidlComponent; | 
|  | 1107 | ::ndk::ScopedAStatus transStatus = mAidlBase->createComponent( | 
|  | 1108 | name, | 
|  | 1109 | aidlListener, | 
|  | 1110 | bufferpool2_aidl::implementation::ClientManager::getInstance(), | 
|  | 1111 | &aidlComponent); | 
|  | 1112 | c2_status_t status = GetC2Status(transStatus, "createComponent"); | 
|  | 1113 | if (status != C2_OK) { | 
|  | 1114 | return status; | 
|  | 1115 | } else if (!aidlComponent) { | 
|  | 1116 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1117 | << ") -- null component."; | 
|  | 1118 | return C2_CORRUPTED; | 
|  | 1119 | } | 
|  | 1120 | *component = std::make_shared<Codec2Client::Component>(aidlComponent); | 
|  | 1121 | status = (*component)->setDeathListener((*component), listener); | 
|  | 1122 | if (status != C2_OK) { | 
|  | 1123 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1124 | << ") -- failed to set up death listener: " | 
|  | 1125 | << status << "."; | 
|  | 1126 | } | 
|  | 1127 | (*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager); | 
|  | 1128 | return status; | 
|  | 1129 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1130 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1131 | c2_status_t status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1132 | sp<Component::HidlListener> hidlListener = new Component::HidlListener{}; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1133 | hidlListener->base = listener; | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1134 | Return<void> transStatus; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1135 | if (mHidlBase1_2) { | 
|  | 1136 | transStatus = mHidlBase1_2->createComponent_1_2( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1137 | name, | 
|  | 1138 | hidlListener, | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1139 | bufferpool_hidl::implementation::ClientManager::getInstance(), | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1140 | [&status, component, hidlListener]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1141 | c2_hidl::Status s, | 
|  | 1142 | const sp<c2_hidl::IComponent>& c) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1143 | status = static_cast<c2_status_t>(s); | 
|  | 1144 | if (status != C2_OK) { | 
|  | 1145 | return; | 
|  | 1146 | } | 
|  | 1147 | *component = std::make_shared<Codec2Client::Component>(c); | 
|  | 1148 | hidlListener->component = *component; | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1149 | }); | 
|  | 1150 | } | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1151 | else if (mHidlBase1_1) { | 
|  | 1152 | transStatus = mHidlBase1_1->createComponent_1_1( | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1153 | name, | 
|  | 1154 | hidlListener, | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1155 | bufferpool_hidl::implementation::ClientManager::getInstance(), | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1156 | [&status, component, hidlListener]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1157 | c2_hidl::Status s, | 
|  | 1158 | const sp<c2_hidl_base::V1_1::IComponent>& c) { | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1159 | status = static_cast<c2_status_t>(s); | 
|  | 1160 | if (status != C2_OK) { | 
|  | 1161 | return; | 
|  | 1162 | } | 
|  | 1163 | *component = std::make_shared<Codec2Client::Component>(c); | 
|  | 1164 | hidlListener->component = *component; | 
|  | 1165 | }); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1166 | } else if (mHidlBase1_0) { // ver1_0 | 
|  | 1167 | transStatus = mHidlBase1_0->createComponent( | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1168 | name, | 
|  | 1169 | hidlListener, | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1170 | bufferpool_hidl::implementation::ClientManager::getInstance(), | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1171 | [&status, component, hidlListener]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1172 | c2_hidl::Status s, | 
|  | 1173 | const sp<c2_hidl_base::V1_0::IComponent>& c) { | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1174 | status = static_cast<c2_status_t>(s); | 
|  | 1175 | if (status != C2_OK) { | 
|  | 1176 | return; | 
|  | 1177 | } | 
|  | 1178 | *component = std::make_shared<Codec2Client::Component>(c); | 
|  | 1179 | hidlListener->component = *component; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1180 | }); | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1181 | } else { | 
|  | 1182 | status = C2_CORRUPTED; | 
|  | 1183 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1184 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1185 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1186 | << ") -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1187 | return C2_TRANSACTION_FAILED; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1188 | } else if (status != C2_OK) { | 
| Pawin Vongmasa | 9aac304 | 2020-03-05 02:30:32 -0800 | [diff] [blame] | 1189 | if (status == C2_NOT_FOUND) { | 
|  | 1190 | LOG(VERBOSE) << "createComponent(" << name.c_str() | 
|  | 1191 | << ") -- component not found."; | 
|  | 1192 | } else { | 
|  | 1193 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1194 | << ") -- call failed: " << status << "."; | 
|  | 1195 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1196 | return status; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1197 | } else if (!*component) { | 
|  | 1198 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1199 | << ") -- null component."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1200 | return C2_CORRUPTED; | 
|  | 1201 | } | 
|  | 1202 |  | 
|  | 1203 | status = (*component)->setDeathListener(*component, listener); | 
|  | 1204 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1205 | LOG(ERROR) << "createComponent(" << name.c_str() | 
|  | 1206 | << ") -- failed to set up death listener: " | 
|  | 1207 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1208 | } | 
|  | 1209 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1210 | (*component)->mHidlBufferPoolSender->setReceiver(mHidlHostPoolManager); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1211 | return status; | 
|  | 1212 | } | 
|  | 1213 |  | 
|  | 1214 | c2_status_t Codec2Client::createInterface( | 
|  | 1215 | const C2String& name, | 
|  | 1216 | std::shared_ptr<Codec2Client::Interface>* const interface) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1217 | if (mAidlBase) { | 
|  | 1218 | std::shared_ptr<c2_aidl::IComponentInterface> aidlInterface; | 
|  | 1219 | ::ndk::ScopedAStatus transStatus = mAidlBase->createInterface( | 
|  | 1220 | name, | 
|  | 1221 | &aidlInterface); | 
|  | 1222 | c2_status_t status = GetC2Status(transStatus, "createInterface"); | 
|  | 1223 | if (status != C2_OK) { | 
|  | 1224 | return status; | 
|  | 1225 | } else if (!aidlInterface) { | 
|  | 1226 | LOG(ERROR) << "createInterface(" << name.c_str() | 
|  | 1227 | << ") -- null interface."; | 
|  | 1228 | return C2_CORRUPTED; | 
|  | 1229 | } | 
|  | 1230 | interface->reset(new Codec2Client::Interface(aidlInterface)); | 
|  | 1231 | return C2_OK; | 
|  | 1232 | } | 
|  | 1233 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1234 | c2_status_t status; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1235 | Return<void> transStatus = mHidlBase1_0->createInterface( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1236 | name, | 
|  | 1237 | [&status, interface]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1238 | c2_hidl::Status s, | 
|  | 1239 | const sp<c2_hidl::IComponentInterface>& i) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1240 | status = static_cast<c2_status_t>(s); | 
|  | 1241 | if (status != C2_OK) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1242 | return; | 
|  | 1243 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1244 | *interface = std::make_shared<Interface>(i); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1245 | }); | 
|  | 1246 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1247 | LOG(ERROR) << "createInterface(" << name.c_str() | 
|  | 1248 | << ") -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1249 | return C2_TRANSACTION_FAILED; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1250 | } else if (status != C2_OK) { | 
| Pawin Vongmasa | 9aac304 | 2020-03-05 02:30:32 -0800 | [diff] [blame] | 1251 | if (status == C2_NOT_FOUND) { | 
|  | 1252 | LOG(VERBOSE) << "createInterface(" << name.c_str() | 
|  | 1253 | << ") -- component not found."; | 
|  | 1254 | } else { | 
|  | 1255 | LOG(ERROR) << "createInterface(" << name.c_str() | 
|  | 1256 | << ") -- call failed: " << status << "."; | 
|  | 1257 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1258 | return status; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1259 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1260 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1261 | return status; | 
|  | 1262 | } | 
|  | 1263 |  | 
|  | 1264 | c2_status_t Codec2Client::createInputSurface( | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1265 | std::shared_ptr<InputSurface>* const inputSurface) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1266 | if (mAidlBase) { | 
|  | 1267 | // FIXME | 
|  | 1268 | return C2_OMITTED; | 
|  | 1269 | } | 
|  | 1270 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1271 | c2_status_t status; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1272 | Return<void> transStatus = mHidlBase1_0->createInputSurface( | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1273 | [&status, inputSurface]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1274 | c2_hidl::Status s, | 
|  | 1275 | const sp<c2_hidl::IInputSurface>& i) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1276 | status = static_cast<c2_status_t>(s); | 
|  | 1277 | if (status != C2_OK) { | 
|  | 1278 | return; | 
|  | 1279 | } | 
|  | 1280 | *inputSurface = std::make_shared<InputSurface>(i); | 
|  | 1281 | }); | 
|  | 1282 | if (!transStatus.isOk()) { | 
|  | 1283 | LOG(ERROR) << "createInputSurface -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1284 | return C2_TRANSACTION_FAILED; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1285 | } else if (status != C2_OK) { | 
|  | 1286 | LOG(DEBUG) << "createInputSurface -- call failed: " | 
|  | 1287 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1288 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1289 | return status; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1290 | } | 
|  | 1291 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1292 | std::vector<C2Component::Traits> const& Codec2Client::listComponents() const { | 
|  | 1293 | return Cache::List()[mServiceIndex].getTraits(); | 
|  | 1294 | } | 
|  | 1295 |  | 
|  | 1296 | std::vector<C2Component::Traits> Codec2Client::_listComponents( | 
|  | 1297 | bool* success) const { | 
|  | 1298 | std::vector<C2Component::Traits> traits; | 
|  | 1299 | std::string const& serviceName = getServiceName(); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1300 |  | 
|  | 1301 | if (mAidlBase) { | 
|  | 1302 | std::vector<c2_aidl::IComponentStore::ComponentTraits> aidlTraits; | 
|  | 1303 | ::ndk::ScopedAStatus transStatus = mAidlBase->listComponents(&aidlTraits); | 
|  | 1304 | if (!transStatus.isOk()) { | 
|  | 1305 | LOG(ERROR) << "_listComponents -- transaction failed."; | 
|  | 1306 | *success = false; | 
|  | 1307 | } else { | 
|  | 1308 | traits.resize(aidlTraits.size()); | 
|  | 1309 | *success = true; | 
|  | 1310 | for (size_t i = 0; i < aidlTraits.size(); ++i) { | 
|  | 1311 | if (!c2_aidl::utils::FromAidl(&traits[i], aidlTraits[i])) { | 
|  | 1312 | LOG(ERROR) << "_listComponents -- corrupted output."; | 
|  | 1313 | *success = false; | 
|  | 1314 | traits.clear(); | 
|  | 1315 | break; | 
|  | 1316 | } | 
|  | 1317 | traits[i].owner = serviceName; | 
|  | 1318 | } | 
|  | 1319 | } | 
|  | 1320 | return traits; | 
|  | 1321 | } | 
|  | 1322 | Return<void> transStatus = mHidlBase1_0->listComponents( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1323 | [&traits, &serviceName](c2_hidl::Status s, | 
|  | 1324 | const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) { | 
|  | 1325 | if (s != c2_hidl::Status::OK) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1326 | LOG(DEBUG) << "_listComponents -- call failed: " | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1327 | << static_cast<c2_status_t>(s) << "."; | 
|  | 1328 | return; | 
|  | 1329 | } | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1330 | traits.resize(t.size()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1331 | for (size_t i = 0; i < t.size(); ++i) { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1332 | if (!c2_hidl::utils::objcpy(&traits[i], t[i])) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1333 | LOG(ERROR) << "_listComponents -- corrupted output."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1334 | return; | 
|  | 1335 | } | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1336 | traits[i].owner = serviceName; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1337 | } | 
|  | 1338 | }); | 
|  | 1339 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1340 | LOG(ERROR) << "_listComponents -- transaction failed."; | 
|  | 1341 | *success = false; | 
|  | 1342 | } else { | 
|  | 1343 | *success = true; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1344 | } | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1345 | return traits; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1346 | } | 
|  | 1347 |  | 
|  | 1348 | c2_status_t Codec2Client::copyBuffer( | 
|  | 1349 | const std::shared_ptr<C2Buffer>& src, | 
|  | 1350 | const std::shared_ptr<C2Buffer>& dst) { | 
|  | 1351 | // TODO: Implement? | 
|  | 1352 | (void)src; | 
|  | 1353 | (void)dst; | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1354 | LOG(ERROR) << "copyBuffer not implemented"; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1355 | return C2_OMITTED; | 
|  | 1356 | } | 
|  | 1357 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1358 | std::shared_ptr<C2ParamReflector> Codec2Client::getParamReflector() { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1359 | // TODO: this is not meant to be exposed as C2ParamReflector on the client side; instead, it | 
|  | 1360 | // should reflect the HAL API. | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1361 | struct HidlSimpleParamReflector : public C2ParamReflector { | 
|  | 1362 | std::unique_ptr<C2StructDescriptor> describe( | 
|  | 1363 | C2Param::CoreIndex coreIndex) const override { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1364 | hidl_vec<c2_hidl::ParamIndex> indices(1); | 
|  | 1365 | indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1366 | std::unique_ptr<C2StructDescriptor> descriptor; | 
|  | 1367 | Return<void> transStatus = mBase->getStructDescriptors( | 
|  | 1368 | indices, | 
|  | 1369 | [&descriptor]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1370 | c2_hidl::Status s, | 
|  | 1371 | const hidl_vec<c2_hidl::StructDescriptor>& sd) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1372 | c2_status_t status = static_cast<c2_status_t>(s); | 
|  | 1373 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1374 | LOG(DEBUG) << "SimpleParamReflector -- " | 
|  | 1375 | "getStructDescriptors() failed: " | 
|  | 1376 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1377 | descriptor.reset(); | 
|  | 1378 | return; | 
|  | 1379 | } | 
|  | 1380 | if (sd.size() != 1) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1381 | LOG(DEBUG) << "SimpleParamReflector -- " | 
|  | 1382 | "getStructDescriptors() " | 
|  | 1383 | "returned vector of size " | 
|  | 1384 | << sd.size() << ". " | 
|  | 1385 | "It should be 1."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1386 | descriptor.reset(); | 
|  | 1387 | return; | 
|  | 1388 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1389 | if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1390 | LOG(DEBUG) << "SimpleParamReflector -- " | 
|  | 1391 | "getStructDescriptors() returned " | 
|  | 1392 | "corrupted data."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1393 | descriptor.reset(); | 
|  | 1394 | return; | 
|  | 1395 | } | 
|  | 1396 | }); | 
| Wonsik Kim | 492fecd | 2020-11-19 11:14:11 -0800 | [diff] [blame] | 1397 | if (!transStatus.isOk()) { | 
|  | 1398 | LOG(DEBUG) << "SimpleParamReflector -- transaction failed: " | 
|  | 1399 | << transStatus.description(); | 
|  | 1400 | descriptor.reset(); | 
|  | 1401 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1402 | return descriptor; | 
|  | 1403 | } | 
|  | 1404 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1405 | HidlSimpleParamReflector(sp<HidlBase> base) | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1406 | : mBase(base) { } | 
|  | 1407 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1408 | sp<HidlBase> mBase; | 
|  | 1409 | }; | 
|  | 1410 | struct AidlSimpleParamReflector : public C2ParamReflector { | 
|  | 1411 | std::unique_ptr<C2StructDescriptor> describe( | 
|  | 1412 | C2Param::CoreIndex coreIndex) const override { | 
|  | 1413 | std::vector<c2_aidl::StructDescriptor> aidlDesc; | 
|  | 1414 | std::unique_ptr<C2StructDescriptor> descriptor; | 
|  | 1415 | ::ndk::ScopedAStatus transStatus = mBase->getStructDescriptors( | 
|  | 1416 | {int32_t(coreIndex.coreIndex())}, | 
|  | 1417 | &aidlDesc); | 
|  | 1418 | c2_status_t status = GetC2Status(transStatus, "describe"); | 
|  | 1419 | if (status != C2_OK) { | 
|  | 1420 | descriptor.reset(); | 
|  | 1421 | } else if (!c2_aidl::utils::FromAidl(&descriptor, aidlDesc[0])) { | 
|  | 1422 | LOG(ERROR) << "describe -- conversion failed."; | 
|  | 1423 | descriptor.reset(); | 
|  | 1424 | } | 
|  | 1425 | return descriptor; | 
|  | 1426 | } | 
|  | 1427 |  | 
|  | 1428 | AidlSimpleParamReflector(const std::shared_ptr<AidlBase> &base) | 
|  | 1429 | : mBase(base) { } | 
|  | 1430 |  | 
|  | 1431 | std::shared_ptr<AidlBase> mBase; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1432 | }; | 
|  | 1433 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1434 | if (mAidlBase) { | 
|  | 1435 | return std::make_shared<AidlSimpleParamReflector>(mAidlBase); | 
|  | 1436 | } | 
|  | 1437 | return std::make_shared<HidlSimpleParamReflector>(mHidlBase1_0); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1438 | }; | 
|  | 1439 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1440 | std::vector<std::string> Codec2Client::CacheServiceNames() { | 
|  | 1441 | std::vector<std::string> names; | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1442 |  | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1443 | if (c2_aidl::utils::IsSelected()) { | 
| Wonsik Kim | 138db0d | 2023-11-02 16:02:01 -0700 | [diff] [blame] | 1444 | if (__builtin_available(android __ANDROID_API_S__, *)) { | 
|  | 1445 | // Get AIDL service names | 
|  | 1446 | AServiceManager_forEachDeclaredInstance( | 
|  | 1447 | AidlBase::descriptor, &names, [](const char *name, void *context) { | 
|  | 1448 | std::vector<std::string> *names = (std::vector<std::string> *)context; | 
|  | 1449 | names->emplace_back(name); | 
|  | 1450 | }); | 
|  | 1451 | } else { | 
|  | 1452 | LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35"; | 
|  | 1453 | } | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1454 | } else { | 
|  | 1455 | // Get HIDL service names | 
|  | 1456 | using ::android::hardware::media::c2::V1_0::IComponentStore; | 
|  | 1457 | using ::android::hidl::manager::V1_2::IServiceManager; | 
|  | 1458 | while (true) { | 
|  | 1459 | sp<IServiceManager> serviceManager = IServiceManager::getService(); | 
|  | 1460 | CHECK(serviceManager) << "Hardware service manager is not running."; | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1461 |  | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1462 | Return<void> transResult; | 
|  | 1463 | transResult = serviceManager->listManifestByInterface( | 
|  | 1464 | IComponentStore::descriptor, | 
|  | 1465 | [&names]( | 
|  | 1466 | hidl_vec<hidl_string> const& instanceNames) { | 
|  | 1467 | names.insert(names.end(), instanceNames.begin(), instanceNames.end()); | 
|  | 1468 | }); | 
|  | 1469 | if (transResult.isOk()) { | 
|  | 1470 | break; | 
|  | 1471 | } | 
|  | 1472 | LOG(ERROR) << "Could not retrieve the list of service instances of " | 
|  | 1473 | << IComponentStore::descriptor | 
|  | 1474 | << ". Retrying..."; | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1475 | } | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1476 | } | 
|  | 1477 | // Sort service names in each category. | 
|  | 1478 | std::stable_sort( | 
|  | 1479 | names.begin(), names.end(), | 
|  | 1480 | [](const std::string &a, const std::string &b) { | 
|  | 1481 | // First compare by prefix: default -> vendor -> {everything else} | 
|  | 1482 | constexpr int DEFAULT = 1; | 
|  | 1483 | constexpr int VENDOR = 2; | 
|  | 1484 | constexpr int OTHER = 3; | 
|  | 1485 | int aPrefix = ((a.compare(0, 7, "default") == 0) ? DEFAULT : | 
|  | 1486 | (a.compare(0, 6, "vendor") == 0) ? VENDOR : | 
|  | 1487 | OTHER); | 
|  | 1488 | int bPrefix = ((b.compare(0, 7, "default") == 0) ? DEFAULT : | 
|  | 1489 | (b.compare(0, 6, "vendor") == 0) ? VENDOR : | 
|  | 1490 | OTHER); | 
|  | 1491 | if (aPrefix != bPrefix) { | 
|  | 1492 | return aPrefix < bPrefix; | 
|  | 1493 | } | 
|  | 1494 | // If the prefix is the same, compare alphabetically | 
|  | 1495 | return a < b; | 
|  | 1496 | }); | 
|  | 1497 |  | 
|  | 1498 | // Summarize to logcat. | 
|  | 1499 | if (names.empty()) { | 
|  | 1500 | LOG(INFO) << "No Codec2 services declared in the manifest."; | 
|  | 1501 | } else { | 
|  | 1502 | std::stringstream stringOutput; | 
|  | 1503 | stringOutput << "Available Codec2 services:"; | 
|  | 1504 | for (std::string const& name : names) { | 
|  | 1505 | stringOutput << " \"" << name << "\""; | 
|  | 1506 | } | 
|  | 1507 | LOG(INFO) << stringOutput.str(); | 
|  | 1508 | } | 
|  | 1509 |  | 
|  | 1510 | return names; | 
|  | 1511 | } | 
|  | 1512 |  | 
|  | 1513 | std::vector<std::string> const& Codec2Client::GetServiceNames() { | 
|  | 1514 | static std::vector<std::string> sServiceNames = CacheServiceNames(); | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1515 | return sServiceNames; | 
|  | 1516 | } | 
|  | 1517 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1518 | std::shared_ptr<Codec2Client> Codec2Client::CreateFromService( | 
| Pawin Vongmasa | 83d2c55 | 2020-03-05 04:36:08 -0800 | [diff] [blame] | 1519 | const char* name, | 
|  | 1520 | bool setAsPreferredCodec2ComponentStore) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1521 | size_t index = getServiceIndex(name); | 
| Pawin Vongmasa | 83d2c55 | 2020-03-05 04:36:08 -0800 | [diff] [blame] | 1522 | if (index == GetServiceNames().size()) { | 
|  | 1523 | if (setAsPreferredCodec2ComponentStore) { | 
|  | 1524 | LOG(WARNING) << "CreateFromService(" << name | 
|  | 1525 | << ") -- preferred C2ComponentStore not set."; | 
|  | 1526 | } | 
|  | 1527 | return nullptr; | 
|  | 1528 | } | 
|  | 1529 | std::shared_ptr<Codec2Client> client = _CreateFromIndex(index); | 
|  | 1530 | if (setAsPreferredCodec2ComponentStore) { | 
|  | 1531 | SetPreferredCodec2ComponentStore( | 
|  | 1532 | std::make_shared<Client2Store>(client)); | 
|  | 1533 | LOG(INFO) << "CreateFromService(" << name | 
|  | 1534 | << ") -- service set as preferred C2ComponentStore."; | 
|  | 1535 | } | 
|  | 1536 | return client; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1537 | } | 
|  | 1538 |  | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1539 | std::vector<std::shared_ptr<Codec2Client>> Codec2Client:: | 
|  | 1540 | CreateFromAllServices() { | 
|  | 1541 | std::vector<std::shared_ptr<Codec2Client>> clients( | 
|  | 1542 | GetServiceNames().size()); | 
|  | 1543 | for (size_t i = GetServiceNames().size(); i > 0; ) { | 
|  | 1544 | --i; | 
|  | 1545 | clients[i] = _CreateFromIndex(i); | 
|  | 1546 | } | 
|  | 1547 | return clients; | 
|  | 1548 | } | 
|  | 1549 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1550 | std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) { | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1551 | std::string const& name = GetServiceNames()[index]; | 
| Pawin Vongmasa | 9aac304 | 2020-03-05 02:30:32 -0800 | [diff] [blame] | 1552 | LOG(VERBOSE) << "Creating a Codec2 client to service \"" << name << "\""; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1553 |  | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1554 | if (c2_aidl::utils::IsSelected()) { | 
| Wonsik Kim | 138db0d | 2023-11-02 16:02:01 -0700 | [diff] [blame] | 1555 | if (__builtin_available(android __ANDROID_API_S__, *)) { | 
|  | 1556 | std::string instanceName = | 
|  | 1557 | ::android::base::StringPrintf("%s/%s", AidlBase::descriptor, name.c_str()); | 
|  | 1558 | if (AServiceManager_isDeclared(instanceName.c_str())) { | 
|  | 1559 | std::shared_ptr<AidlBase> baseStore = AidlBase::fromBinder( | 
|  | 1560 | ::ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str()))); | 
|  | 1561 | CHECK(baseStore) << "Codec2 AIDL service \"" << name << "\"" | 
|  | 1562 | " inaccessible for unknown reasons."; | 
|  | 1563 | LOG(VERBOSE) << "Client to Codec2 AIDL service \"" << name << "\" created"; | 
|  | 1564 | std::shared_ptr<c2_aidl::IConfigurable> configurable; | 
|  | 1565 | ::ndk::ScopedAStatus transStatus = baseStore->getConfigurable(&configurable); | 
|  | 1566 | CHECK(transStatus.isOk()) << "Codec2 AIDL service \"" << name << "\"" | 
|  | 1567 | "does not have IConfigurable."; | 
|  | 1568 | return std::make_shared<Codec2Client>(baseStore, configurable, index); | 
|  | 1569 | } else { | 
|  | 1570 | LOG(ERROR) << "Codec2 AIDL service \"" << name << "\" is not declared"; | 
|  | 1571 | } | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1572 | } else { | 
| Wonsik Kim | 138db0d | 2023-11-02 16:02:01 -0700 | [diff] [blame] | 1573 | LOG(FATAL) << "C2 AIDL cannot be selected on Android version older than 35"; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1574 | } | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1575 | } else { | 
|  | 1576 | std::string instanceName = "android.hardware.media.c2/" + name; | 
|  | 1577 | sp<HidlBase> baseStore = HidlBase::getService(name); | 
|  | 1578 | CHECK(baseStore) << "Codec2 service \"" << name << "\"" | 
|  | 1579 | " inaccessible for unknown reasons."; | 
|  | 1580 | LOG(VERBOSE) << "Client to Codec2 service \"" << name << "\" created"; | 
|  | 1581 | Return<sp<c2_hidl::IConfigurable>> transResult = baseStore->getConfigurable(); | 
|  | 1582 | CHECK(transResult.isOk()) << "Codec2 service \"" << name << "\"" | 
|  | 1583 | "does not have IConfigurable."; | 
|  | 1584 | sp<c2_hidl::IConfigurable> configurable = | 
|  | 1585 | static_cast<sp<c2_hidl::IConfigurable>>(transResult); | 
|  | 1586 | return std::make_shared<Codec2Client>(baseStore, configurable, index); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1587 | } | 
| Wonsik Kim | b613d4b | 2023-09-01 14:01:36 -0700 | [diff] [blame] | 1588 | return nullptr; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1589 | } | 
|  | 1590 |  | 
|  | 1591 | c2_status_t Codec2Client::ForAllServices( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1592 | const std::string &key, | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1593 | size_t numberOfAttempts, | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1594 | std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)> | 
|  | 1595 | predicate) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1596 | c2_status_t status = C2_NO_INIT;  // no IComponentStores present | 
|  | 1597 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1598 | // Cache the mapping key -> index of Codec2Client in Cache::List(). | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1599 | static std::mutex key2IndexMutex; | 
|  | 1600 | static std::map<std::string, size_t> key2Index; | 
|  | 1601 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1602 | // By default try all stores. However, try the last known client first. If | 
|  | 1603 | // the last known client fails, retry once. We do this by pushing the last | 
|  | 1604 | // known client in front of the list of all clients. | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1605 | std::deque<size_t> indices; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1606 | for (size_t index = Cache::List().size(); index > 0; ) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1607 | indices.push_front(--index); | 
|  | 1608 | } | 
|  | 1609 |  | 
|  | 1610 | bool wasMapped = false; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1611 | { | 
|  | 1612 | std::scoped_lock lock{key2IndexMutex}; | 
|  | 1613 | auto it = key2Index.find(key); | 
|  | 1614 | if (it != key2Index.end()) { | 
|  | 1615 | indices.push_front(it->second); | 
|  | 1616 | wasMapped = true; | 
|  | 1617 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1618 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1619 |  | 
|  | 1620 | for (size_t index : indices) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1621 | Cache& cache = Cache::List()[index]; | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1622 | for (size_t tries = numberOfAttempts; tries > 0; --tries) { | 
|  | 1623 | std::shared_ptr<Codec2Client> client{cache.getClient()}; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1624 | status = predicate(client); | 
|  | 1625 | if (status == C2_OK) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1626 | std::scoped_lock lock{key2IndexMutex}; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1627 | key2Index[key] = index; // update last known client index | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1628 | return C2_OK; | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1629 | } else if (status == C2_NO_MEMORY) { | 
|  | 1630 | return C2_NO_MEMORY; | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1631 | } else if (status == C2_TRANSACTION_FAILED) { | 
|  | 1632 | LOG(WARNING) << "\"" << key << "\" failed for service \"" | 
|  | 1633 | << client->getName() | 
|  | 1634 | << "\" due to transaction failure. " | 
|  | 1635 | << "(Service may have crashed.)" | 
|  | 1636 | << (tries > 1 ? " Retrying..." : ""); | 
|  | 1637 | cache.invalidate(); | 
|  | 1638 | continue; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1639 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1640 | if (wasMapped) { | 
|  | 1641 | LOG(INFO) << "\"" << key << "\" became invalid in service \"" | 
|  | 1642 | << client->getName() << "\". Retrying..."; | 
|  | 1643 | wasMapped = false; | 
|  | 1644 | } | 
|  | 1645 | break; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1646 | } | 
|  | 1647 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1648 | return status; // return the last status from a valid client | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1649 | } | 
|  | 1650 |  | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1651 | c2_status_t Codec2Client::CreateComponentByName( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1652 | const char* componentName, | 
|  | 1653 | const std::shared_ptr<Listener>& listener, | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1654 | std::shared_ptr<Component>* component, | 
| Pawin Vongmasa | 23c90c8 | 2019-09-03 00:44:42 -0700 | [diff] [blame] | 1655 | std::shared_ptr<Codec2Client>* owner, | 
|  | 1656 | size_t numberOfAttempts) { | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1657 | std::string key{"create:"}; | 
|  | 1658 | key.append(componentName); | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1659 | c2_status_t status = ForAllServices( | 
|  | 1660 | key, | 
|  | 1661 | numberOfAttempts, | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1662 | [owner, component, componentName, &listener]( | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1663 | const std::shared_ptr<Codec2Client> &client) | 
|  | 1664 | -> c2_status_t { | 
|  | 1665 | c2_status_t status = client->createComponent(componentName, | 
|  | 1666 | listener, | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1667 | component); | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1668 | if (status == C2_OK) { | 
|  | 1669 | if (owner) { | 
|  | 1670 | *owner = client; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1671 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1672 | } else if (status != C2_NOT_FOUND) { | 
|  | 1673 | LOG(DEBUG) << "IComponentStore(" | 
|  | 1674 | << client->getServiceName() | 
|  | 1675 | << ")::createComponent(\"" << componentName | 
|  | 1676 | << "\") returned status = " | 
|  | 1677 | << status << "."; | 
|  | 1678 | } | 
|  | 1679 | return status; | 
|  | 1680 | }); | 
|  | 1681 | if (status != C2_OK) { | 
|  | 1682 | LOG(DEBUG) << "Failed to create component \"" << componentName | 
|  | 1683 | << "\" from all known services. " | 
|  | 1684 | "Last returned status = " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1685 | } | 
| Chih-Yu Huang | b8fe079 | 2020-12-07 17:14:55 +0900 | [diff] [blame] | 1686 | return status; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1687 | } | 
|  | 1688 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1689 | std::shared_ptr<Codec2Client::Interface> Codec2Client::CreateInterfaceByName( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1690 | const char* interfaceName, | 
| Pawin Vongmasa | 23c90c8 | 2019-09-03 00:44:42 -0700 | [diff] [blame] | 1691 | std::shared_ptr<Codec2Client>* owner, | 
|  | 1692 | size_t numberOfAttempts) { | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1693 | std::string key{"create:"}; | 
|  | 1694 | key.append(interfaceName); | 
|  | 1695 | std::shared_ptr<Interface> interface; | 
|  | 1696 | c2_status_t status = ForAllServices( | 
|  | 1697 | key, | 
|  | 1698 | numberOfAttempts, | 
|  | 1699 | [owner, &interface, interfaceName]( | 
|  | 1700 | const std::shared_ptr<Codec2Client> &client) | 
|  | 1701 | -> c2_status_t { | 
|  | 1702 | c2_status_t status = client->createInterface(interfaceName, | 
|  | 1703 | &interface); | 
|  | 1704 | if (status == C2_OK) { | 
|  | 1705 | if (owner) { | 
|  | 1706 | *owner = client; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1707 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1708 | } else if (status != C2_NOT_FOUND) { | 
|  | 1709 | LOG(DEBUG) << "IComponentStore(" | 
|  | 1710 | << client->getServiceName() | 
|  | 1711 | << ")::createInterface(\"" << interfaceName | 
|  | 1712 | << "\") returned status = " | 
|  | 1713 | << status << "."; | 
|  | 1714 | } | 
|  | 1715 | return status; | 
|  | 1716 | }); | 
|  | 1717 | if (status != C2_OK) { | 
|  | 1718 | LOG(DEBUG) << "Failed to create interface \"" << interfaceName | 
|  | 1719 | << "\" from all known services. " | 
|  | 1720 | "Last returned status = " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1721 | } | 
| Pawin Vongmasa | 1e7015a | 2019-10-09 02:15:50 -0700 | [diff] [blame] | 1722 | return interface; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1723 | } | 
|  | 1724 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1725 | std::vector<C2Component::Traits> const& Codec2Client::ListComponents() { | 
|  | 1726 | static std::vector<C2Component::Traits> sList{[]() { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1727 | std::vector<C2Component::Traits> list; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1728 | for (Cache& cache : Cache::List()) { | 
|  | 1729 | std::vector<C2Component::Traits> const& traits = cache.getTraits(); | 
|  | 1730 | list.insert(list.end(), traits.begin(), traits.end()); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1731 | } | 
|  | 1732 | return list; | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1733 | }()}; | 
|  | 1734 | return sList; | 
|  | 1735 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1736 |  | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1737 | std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface( | 
|  | 1738 | char const* serviceName) { | 
| Pawin Vongmasa | 1858832 | 2019-05-18 01:52:13 -0700 | [diff] [blame] | 1739 | int32_t inputSurfaceSetting = ::android::base::GetIntProperty( | 
|  | 1740 | "debug.stagefright.c2inputsurface", int32_t(0)); | 
|  | 1741 | if (inputSurfaceSetting <= 0) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1742 | return nullptr; | 
|  | 1743 | } | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1744 | size_t index = GetServiceNames().size(); | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1745 | if (serviceName) { | 
|  | 1746 | index = getServiceIndex(serviceName); | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1747 | if (index == GetServiceNames().size()) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1748 | LOG(DEBUG) << "CreateInputSurface -- invalid service name: \"" | 
|  | 1749 | << serviceName << "\""; | 
|  | 1750 | } | 
|  | 1751 | } | 
|  | 1752 |  | 
|  | 1753 | std::shared_ptr<Codec2Client::InputSurface> inputSurface; | 
| Pawin Vongmasa | 270dd6a | 2019-04-06 04:41:15 -0700 | [diff] [blame] | 1754 | if (index != GetServiceNames().size()) { | 
| Pawin Vongmasa | 892c81d | 2019-03-12 00:56:50 -0700 | [diff] [blame] | 1755 | std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient(); | 
|  | 1756 | if (client->createInputSurface(&inputSurface) == C2_OK) { | 
|  | 1757 | return inputSurface; | 
|  | 1758 | } | 
|  | 1759 | } | 
|  | 1760 | LOG(INFO) << "CreateInputSurface -- attempting to create an input surface " | 
|  | 1761 | "from all services..."; | 
|  | 1762 | for (Cache& cache : Cache::List()) { | 
|  | 1763 | std::shared_ptr<Codec2Client> client = cache.getClient(); | 
|  | 1764 | if (client->createInputSurface(&inputSurface) == C2_OK) { | 
|  | 1765 | LOG(INFO) << "CreateInputSurface -- input surface obtained from " | 
|  | 1766 | "service \"" << client->getServiceName() << "\""; | 
|  | 1767 | return inputSurface; | 
|  | 1768 | } | 
|  | 1769 | } | 
|  | 1770 | LOG(WARNING) << "CreateInputSurface -- failed to create an input surface " | 
|  | 1771 | "from all services"; | 
|  | 1772 | return nullptr; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1773 | } | 
|  | 1774 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1775 | // Codec2Client::Interface | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1776 | Codec2Client::Interface::Interface(const sp<HidlBase>& base) | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1777 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1778 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 1779 | Return<sp<c2_hidl::IConfigurable>> transResult = | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1780 | base->getConfigurable(); | 
|  | 1781 | return transResult.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1782 | static_cast<sp<c2_hidl::IConfigurable>>(transResult) : | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1783 | nullptr; | 
|  | 1784 | }() | 
|  | 1785 | }, | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1786 | mHidlBase{base} { | 
|  | 1787 | } | 
|  | 1788 |  | 
|  | 1789 | Codec2Client::Interface::Interface(const std::shared_ptr<AidlBase>& base) | 
|  | 1790 | : Configurable{ | 
|  | 1791 | [base]() -> std::shared_ptr<c2_aidl::IConfigurable> { | 
|  | 1792 | std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable; | 
|  | 1793 | ::ndk::ScopedAStatus transStatus = | 
|  | 1794 | base->getConfigurable(&aidlConfigurable); | 
|  | 1795 | return transStatus.isOk() ? aidlConfigurable : nullptr; | 
|  | 1796 | }() | 
|  | 1797 | }, | 
|  | 1798 | mAidlBase{base} { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1799 | } | 
|  | 1800 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1801 | // Codec2Client::Component | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1802 |  | 
|  | 1803 | class Codec2Client::Component::AidlDeathManager { | 
|  | 1804 | public: | 
|  | 1805 | AidlDeathManager() | 
|  | 1806 | : mSeq(0), | 
|  | 1807 | mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) { | 
|  | 1808 | } | 
|  | 1809 |  | 
|  | 1810 | ~AidlDeathManager() = default; | 
|  | 1811 |  | 
|  | 1812 | bool linkToDeath( | 
|  | 1813 | const std::shared_ptr<Component> &comp, | 
|  | 1814 | const std::shared_ptr<Listener> &listener, | 
|  | 1815 | size_t *seqPtr) { | 
|  | 1816 | std::unique_lock lock(mMutex); | 
|  | 1817 | size_t seq = mSeq++; | 
|  | 1818 | if (!mMap.try_emplace(seq, comp, listener).second) { | 
|  | 1819 | return false; | 
|  | 1820 | } | 
|  | 1821 | if (STATUS_OK != AIBinder_linkToDeath( | 
|  | 1822 | comp->mAidlBase->asBinder().get(), mDeathRecipient.get(), (void *)seq)) { | 
|  | 1823 | mMap.erase(seq); | 
|  | 1824 | return false; | 
|  | 1825 | } | 
|  | 1826 | *seqPtr = seq; | 
|  | 1827 | return true; | 
|  | 1828 | } | 
|  | 1829 |  | 
|  | 1830 | void unlinkToDeath(size_t seq, const std::shared_ptr<AidlBase> &base) { | 
|  | 1831 | std::unique_lock lock(mMutex); | 
|  | 1832 | AIBinder_unlinkToDeath(base->asBinder().get(), mDeathRecipient.get(), (void *)seq); | 
|  | 1833 | mMap.erase(seq); | 
|  | 1834 | } | 
|  | 1835 |  | 
|  | 1836 | private: | 
|  | 1837 | std::mutex mMutex; | 
|  | 1838 | size_t mSeq; | 
|  | 1839 | typedef std::tuple<std::weak_ptr<Component>, std::weak_ptr<Listener>> Context; | 
|  | 1840 | std::map<size_t, Context> mMap; | 
|  | 1841 | ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; | 
|  | 1842 |  | 
|  | 1843 | bool extractContext(size_t seq, Context *context) { | 
|  | 1844 | std::unique_lock lock(mMutex); | 
|  | 1845 | auto node = mMap.extract(seq); | 
|  | 1846 | if (!node) { | 
|  | 1847 | return false; | 
|  | 1848 | } | 
|  | 1849 | *context = node.mapped(); | 
|  | 1850 | return true; | 
|  | 1851 | } | 
|  | 1852 |  | 
|  | 1853 | static void OnBinderDied(void *cookie) { | 
|  | 1854 | size_t seq = size_t(cookie); | 
|  | 1855 | Context context; | 
|  | 1856 | if (!Component::GetAidlDeathManager()->extractContext(seq, &context)) { | 
|  | 1857 | return; | 
|  | 1858 | } | 
|  | 1859 | std::weak_ptr<Component> weakComponent; | 
|  | 1860 | std::weak_ptr<Listener> weakListener; | 
|  | 1861 | std::tie(weakComponent, weakListener) = context; | 
|  | 1862 | if (std::shared_ptr<Listener> listener = weakListener.lock()) { | 
|  | 1863 | listener->onDeath(weakComponent); | 
|  | 1864 | } else { | 
|  | 1865 | LOG(DEBUG) << "onDeath -- listener died."; | 
|  | 1866 | } | 
|  | 1867 | } | 
|  | 1868 | }; | 
|  | 1869 |  | 
|  | 1870 | Codec2Client::Component::Component(const sp<HidlBase>& base) | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1871 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1872 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 1873 | Return<sp<c2_hidl::IComponentInterface>> transResult1 = | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1874 | base->getInterface(); | 
|  | 1875 | if (!transResult1.isOk()) { | 
|  | 1876 | return nullptr; | 
|  | 1877 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1878 | Return<sp<c2_hidl::IConfigurable>> transResult2 = | 
|  | 1879 | static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)-> | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1880 | getConfigurable(); | 
|  | 1881 | return transResult2.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1882 | static_cast<sp<c2_hidl::IConfigurable>>(transResult2) : | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1883 | nullptr; | 
|  | 1884 | }() | 
|  | 1885 | }, | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1886 | mHidlBase1_0{base}, | 
|  | 1887 | mHidlBase1_1{HidlBase1_1::castFrom(base)}, | 
|  | 1888 | mHidlBase1_2{HidlBase1_2::castFrom(base)}, | 
|  | 1889 | mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()}, | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1890 | mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} { | 
|  | 1891 | } | 
|  | 1892 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1893 | Codec2Client::Component::Component(const sp<HidlBase1_1>& base) | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1894 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1895 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 1896 | Return<sp<c2_hidl::IComponentInterface>> transResult1 = | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1897 | base->getInterface(); | 
|  | 1898 | if (!transResult1.isOk()) { | 
|  | 1899 | return nullptr; | 
|  | 1900 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1901 | Return<sp<c2_hidl::IConfigurable>> transResult2 = | 
|  | 1902 | static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)-> | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1903 | getConfigurable(); | 
|  | 1904 | return transResult2.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1905 | static_cast<sp<c2_hidl::IConfigurable>>(transResult2) : | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1906 | nullptr; | 
|  | 1907 | }() | 
|  | 1908 | }, | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1909 | mHidlBase1_0{base}, | 
|  | 1910 | mHidlBase1_1{base}, | 
|  | 1911 | mHidlBase1_2{HidlBase1_2::castFrom(base)}, | 
|  | 1912 | mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()}, | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1913 | mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} { | 
|  | 1914 | } | 
|  | 1915 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1916 | Codec2Client::Component::Component(const sp<HidlBase1_2>& base) | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1917 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1918 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 1919 | Return<sp<c2_hidl::IComponentInterface>> transResult1 = | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1920 | base->getInterface(); | 
|  | 1921 | if (!transResult1.isOk()) { | 
|  | 1922 | return nullptr; | 
|  | 1923 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1924 | Return<sp<c2_hidl::IConfigurable>> transResult2 = | 
|  | 1925 | static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)-> | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1926 | getConfigurable(); | 
|  | 1927 | return transResult2.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1928 | static_cast<sp<c2_hidl::IConfigurable>>(transResult2) : | 
| Sungtak Lee | 8577dab | 2021-03-12 02:25:50 -0800 | [diff] [blame] | 1929 | nullptr; | 
|  | 1930 | }() | 
|  | 1931 | }, | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1932 | mHidlBase1_0{base}, | 
|  | 1933 | mHidlBase1_1{base}, | 
|  | 1934 | mHidlBase1_2{base}, | 
|  | 1935 | mHidlBufferPoolSender{std::make_unique<HidlBufferPoolSender>()}, | 
|  | 1936 | mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} { | 
|  | 1937 | } | 
|  | 1938 |  | 
|  | 1939 | Codec2Client::Component::Component(const std::shared_ptr<AidlBase> &base) | 
|  | 1940 | : Configurable{ | 
|  | 1941 | [base]() -> std::shared_ptr<c2_aidl::IConfigurable> { | 
|  | 1942 | std::shared_ptr<c2_aidl::IComponentInterface> aidlIntf; | 
|  | 1943 | ::ndk::ScopedAStatus transStatus = base->getInterface(&aidlIntf); | 
|  | 1944 | if (!transStatus.isOk()) { | 
|  | 1945 | return nullptr; | 
|  | 1946 | } | 
|  | 1947 | std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable; | 
|  | 1948 | transStatus = aidlIntf->getConfigurable(&aidlConfigurable); | 
|  | 1949 | return transStatus.isOk() ? aidlConfigurable : nullptr; | 
|  | 1950 | }() | 
|  | 1951 | }, | 
|  | 1952 | mAidlBase{base}, | 
|  | 1953 | mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()}, | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 1954 | mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1955 | } | 
|  | 1956 |  | 
|  | 1957 | Codec2Client::Component::~Component() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1958 | if (mAidlDeathSeq) { | 
|  | 1959 | GetAidlDeathManager()->unlinkToDeath(*mAidlDeathSeq, mAidlBase); | 
|  | 1960 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1961 | } | 
|  | 1962 |  | 
|  | 1963 | c2_status_t Codec2Client::Component::createBlockPool( | 
|  | 1964 | C2Allocator::id_t id, | 
|  | 1965 | C2BlockPool::local_id_t* blockPoolId, | 
|  | 1966 | std::shared_ptr<Codec2Client::Configurable>* configurable) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1967 | if (mAidlBase) { | 
|  | 1968 | c2_aidl::IComponent::BlockPool aidlBlockPool; | 
| Ryan Prichard | 8d37bb0 | 2023-09-13 20:23:15 -0700 | [diff] [blame] | 1969 | ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id), | 
|  | 1970 | &aidlBlockPool); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1971 | c2_status_t status = GetC2Status(transStatus, "createBlockPool"); | 
|  | 1972 | if (status != C2_OK) { | 
|  | 1973 | return status; | 
|  | 1974 | } | 
|  | 1975 | *blockPoolId = aidlBlockPool.blockPoolId; | 
|  | 1976 | *configurable = std::make_shared<Configurable>(aidlBlockPool.configurable); | 
|  | 1977 | return C2_OK; | 
|  | 1978 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1979 | c2_status_t status; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 1980 | Return<void> transStatus = mHidlBase1_0->createBlockPool( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1981 | static_cast<uint32_t>(id), | 
|  | 1982 | [&status, blockPoolId, configurable]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1983 | c2_hidl::Status s, | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1984 | uint64_t pId, | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 1985 | const sp<c2_hidl::IConfigurable>& c) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1986 | status = static_cast<c2_status_t>(s); | 
|  | 1987 | configurable->reset(); | 
|  | 1988 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1989 | LOG(DEBUG) << "createBlockPool -- call failed: " | 
|  | 1990 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1991 | return; | 
|  | 1992 | } | 
|  | 1993 | *blockPoolId = static_cast<C2BlockPool::local_id_t>(pId); | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1994 | *configurable = std::make_shared<Configurable>(c); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1995 | }); | 
|  | 1996 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 1997 | LOG(ERROR) << "createBlockPool -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 1998 | return C2_TRANSACTION_FAILED; | 
|  | 1999 | } | 
|  | 2000 | return status; | 
|  | 2001 | } | 
|  | 2002 |  | 
|  | 2003 | c2_status_t Codec2Client::Component::destroyBlockPool( | 
|  | 2004 | C2BlockPool::local_id_t localId) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2005 | if (mAidlBase) { | 
|  | 2006 | ::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId); | 
|  | 2007 | return GetC2Status(transStatus, "destroyBlockPool"); | 
|  | 2008 | } | 
|  | 2009 | Return<c2_hidl::Status> transResult = mHidlBase1_0->destroyBlockPool( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2010 | static_cast<uint64_t>(localId)); | 
|  | 2011 | if (!transResult.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2012 | LOG(ERROR) << "destroyBlockPool -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2013 | return C2_TRANSACTION_FAILED; | 
|  | 2014 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2015 | return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2016 | } | 
|  | 2017 |  | 
| Wonsik Kim | ab34ed6 | 2019-01-31 15:28:46 -0800 | [diff] [blame] | 2018 | void Codec2Client::Component::handleOnWorkDone( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2019 | const std::list<std::unique_ptr<C2Work>> &workItems) { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2020 | // Output bufferqueue-based blocks' lifetime management | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2021 | mOutputBufferQueue->holdBufferQueueBlocks(workItems); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2022 | } | 
|  | 2023 |  | 
|  | 2024 | c2_status_t Codec2Client::Component::queue( | 
|  | 2025 | std::list<std::unique_ptr<C2Work>>* const items) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2026 | if (mAidlBase) { | 
|  | 2027 | c2_aidl::WorkBundle workBundle; | 
|  | 2028 | if (!c2_aidl::utils::ToAidl(&workBundle, *items, mAidlBufferPoolSender.get())) { | 
|  | 2029 | LOG(ERROR) << "queue -- bad input."; | 
|  | 2030 | return C2_TRANSACTION_FAILED; | 
|  | 2031 | } | 
|  | 2032 | ::ndk::ScopedAStatus transStatus = mAidlBase->queue(workBundle); | 
|  | 2033 | return GetC2Status(transStatus, "queue"); | 
|  | 2034 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2035 | c2_hidl::WorkBundle workBundle; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2036 | if (!c2_hidl::utils::objcpy(&workBundle, *items, mHidlBufferPoolSender.get())) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2037 | LOG(ERROR) << "queue -- bad input."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2038 | return C2_TRANSACTION_FAILED; | 
|  | 2039 | } | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2040 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->queue(workBundle); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2041 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2042 | LOG(ERROR) << "queue -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2043 | return C2_TRANSACTION_FAILED; | 
|  | 2044 | } | 
|  | 2045 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2046 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2047 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2048 | LOG(DEBUG) << "queue -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2049 | } | 
|  | 2050 | return status; | 
|  | 2051 | } | 
|  | 2052 |  | 
|  | 2053 | c2_status_t Codec2Client::Component::flush( | 
|  | 2054 | C2Component::flush_mode_t mode, | 
|  | 2055 | std::list<std::unique_ptr<C2Work>>* const flushedWork) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2056 | (void)mode; // Flush mode isn't supported in HIDL/AIDL yet. | 
|  | 2057 | c2_status_t status = C2_OK; | 
|  | 2058 | if (mAidlBase) { | 
|  | 2059 | c2_aidl::WorkBundle workBundle; | 
|  | 2060 | ::ndk::ScopedAStatus transStatus = mAidlBase->flush(&workBundle); | 
|  | 2061 | c2_status_t status = GetC2Status(transStatus, "flush"); | 
|  | 2062 | if (status != C2_OK) { | 
|  | 2063 | return status; | 
|  | 2064 | } | 
|  | 2065 | if (!c2_aidl::utils::FromAidl(flushedWork, workBundle)) { | 
|  | 2066 | LOG(DEBUG) << "flush -- flushedWork corrupted."; | 
|  | 2067 | return C2_CORRUPTED; | 
|  | 2068 | } | 
|  | 2069 | } else { | 
|  | 2070 | Return<void> transStatus = mHidlBase1_0->flush( | 
|  | 2071 | [&status, flushedWork]( | 
|  | 2072 | c2_hidl::Status s, const c2_hidl::WorkBundle& wb) { | 
|  | 2073 | status = static_cast<c2_status_t>(s); | 
|  | 2074 | if (status != C2_OK) { | 
|  | 2075 | LOG(DEBUG) << "flush -- call failed: " << status << "."; | 
|  | 2076 | return; | 
|  | 2077 | } | 
|  | 2078 | if (!c2_hidl::utils::objcpy(flushedWork, wb)) { | 
|  | 2079 | status = C2_CORRUPTED; | 
|  | 2080 | } else { | 
|  | 2081 | status = C2_OK; | 
|  | 2082 | } | 
|  | 2083 | }); | 
|  | 2084 | if (!transStatus.isOk()) { | 
|  | 2085 | LOG(ERROR) << "flush -- transaction failed."; | 
|  | 2086 | return C2_TRANSACTION_FAILED; | 
|  | 2087 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2088 | } | 
|  | 2089 |  | 
|  | 2090 | // Indices of flushed work items. | 
|  | 2091 | std::vector<uint64_t> flushedIndices; | 
|  | 2092 | for (const std::unique_ptr<C2Work> &work : *flushedWork) { | 
|  | 2093 | if (work) { | 
|  | 2094 | if (work->worklets.empty() | 
|  | 2095 | || !work->worklets.back() | 
|  | 2096 | || (work->worklets.back()->output.flags & | 
|  | 2097 | C2FrameData::FLAG_INCOMPLETE) == 0) { | 
|  | 2098 | // input is complete | 
|  | 2099 | flushedIndices.emplace_back( | 
|  | 2100 | work->input.ordinal.frameIndex.peeku()); | 
|  | 2101 | } | 
|  | 2102 | } | 
|  | 2103 | } | 
|  | 2104 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2105 | // Output bufferqueue-based blocks' lifetime management | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2106 | mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2107 |  | 
|  | 2108 | return status; | 
|  | 2109 | } | 
|  | 2110 |  | 
|  | 2111 | c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2112 | if (mAidlBase) { | 
|  | 2113 | ::ndk::ScopedAStatus transStatus = mAidlBase->drain( | 
|  | 2114 | mode == C2Component::DRAIN_COMPONENT_WITH_EOS); | 
|  | 2115 | return GetC2Status(transStatus, "drain"); | 
|  | 2116 | } | 
|  | 2117 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->drain( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2118 | mode == C2Component::DRAIN_COMPONENT_WITH_EOS); | 
|  | 2119 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2120 | LOG(ERROR) << "drain -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2121 | return C2_TRANSACTION_FAILED; | 
|  | 2122 | } | 
|  | 2123 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2124 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2125 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2126 | LOG(DEBUG) << "drain -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2127 | } | 
|  | 2128 | return status; | 
|  | 2129 | } | 
|  | 2130 |  | 
|  | 2131 | c2_status_t Codec2Client::Component::start() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2132 | if (mAidlBase) { | 
|  | 2133 | ::ndk::ScopedAStatus transStatus = mAidlBase->start(); | 
|  | 2134 | return GetC2Status(transStatus, "start"); | 
|  | 2135 | } | 
|  | 2136 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->start(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2137 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2138 | LOG(ERROR) << "start -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2139 | return C2_TRANSACTION_FAILED; | 
|  | 2140 | } | 
|  | 2141 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2142 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2143 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2144 | LOG(DEBUG) << "start -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2145 | } | 
|  | 2146 | return status; | 
|  | 2147 | } | 
|  | 2148 |  | 
|  | 2149 | c2_status_t Codec2Client::Component::stop() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2150 | if (mAidlBase) { | 
|  | 2151 | ::ndk::ScopedAStatus transStatus = mAidlBase->stop(); | 
|  | 2152 | return GetC2Status(transStatus, "stop"); | 
|  | 2153 | } | 
|  | 2154 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->stop(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2155 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2156 | LOG(ERROR) << "stop -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2157 | return C2_TRANSACTION_FAILED; | 
|  | 2158 | } | 
|  | 2159 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2160 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2161 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2162 | LOG(DEBUG) << "stop -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2163 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2164 | return status; | 
|  | 2165 | } | 
|  | 2166 |  | 
|  | 2167 | c2_status_t Codec2Client::Component::reset() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2168 | if (mAidlBase) { | 
|  | 2169 | ::ndk::ScopedAStatus transStatus = mAidlBase->reset(); | 
|  | 2170 | return GetC2Status(transStatus, "reset"); | 
|  | 2171 | } | 
|  | 2172 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->reset(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2173 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2174 | LOG(ERROR) << "reset -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2175 | return C2_TRANSACTION_FAILED; | 
|  | 2176 | } | 
|  | 2177 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2178 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2179 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2180 | LOG(DEBUG) << "reset -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2181 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2182 | return status; | 
|  | 2183 | } | 
|  | 2184 |  | 
|  | 2185 | c2_status_t Codec2Client::Component::release() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2186 | if (mAidlBase) { | 
|  | 2187 | ::ndk::ScopedAStatus transStatus = mAidlBase->release(); | 
|  | 2188 | return GetC2Status(transStatus, "release"); | 
|  | 2189 | } | 
|  | 2190 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->release(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2191 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2192 | LOG(ERROR) << "release -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2193 | return C2_TRANSACTION_FAILED; | 
|  | 2194 | } | 
|  | 2195 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2196 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2197 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2198 | LOG(DEBUG) << "release -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2199 | } | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2200 | return status; | 
|  | 2201 | } | 
|  | 2202 |  | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2203 | c2_status_t Codec2Client::Component::configureVideoTunnel( | 
|  | 2204 | uint32_t avSyncHwId, | 
|  | 2205 | native_handle_t** sidebandHandle) { | 
|  | 2206 | *sidebandHandle = nullptr; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2207 | if (mAidlBase) { | 
|  | 2208 | ::aidl::android::hardware::common::NativeHandle handle; | 
|  | 2209 | ::ndk::ScopedAStatus transStatus = mAidlBase->configureVideoTunnel(avSyncHwId, &handle); | 
|  | 2210 | c2_status_t status = GetC2Status(transStatus, "configureVideoTunnel"); | 
|  | 2211 | if (status != C2_OK) { | 
|  | 2212 | return status; | 
|  | 2213 | } | 
|  | 2214 | if (isAidlNativeHandleEmpty(handle)) { | 
|  | 2215 | LOG(DEBUG) << "configureVideoTunnel -- empty handle returned"; | 
|  | 2216 | } else { | 
|  | 2217 | *sidebandHandle = dupFromAidl(handle); | 
|  | 2218 | } | 
|  | 2219 | return C2_OK; | 
|  | 2220 | } | 
|  | 2221 | if (!mHidlBase1_1) { | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2222 | return C2_OMITTED; | 
|  | 2223 | } | 
|  | 2224 | c2_status_t status{}; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2225 | Return<void> transStatus = mHidlBase1_1->configureVideoTunnel(avSyncHwId, | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2226 | [&status, sidebandHandle]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2227 | c2_hidl::Status s, hardware::hidl_handle const& h) { | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2228 | status = static_cast<c2_status_t>(s); | 
|  | 2229 | if (h.getNativeHandle()) { | 
|  | 2230 | *sidebandHandle = native_handle_clone(h.getNativeHandle()); | 
|  | 2231 | } | 
|  | 2232 | }); | 
|  | 2233 | if (!transStatus.isOk()) { | 
|  | 2234 | LOG(ERROR) << "configureVideoTunnel -- transaction failed."; | 
|  | 2235 | return C2_TRANSACTION_FAILED; | 
|  | 2236 | } | 
|  | 2237 | return status; | 
|  | 2238 | } | 
|  | 2239 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2240 | c2_status_t Codec2Client::Component::setOutputSurface( | 
|  | 2241 | C2BlockPool::local_id_t blockPoolId, | 
|  | 2242 | const sp<IGraphicBufferProducer>& surface, | 
| Sungtak Lee | db14cba | 2021-04-10 00:50:23 -0700 | [diff] [blame] | 2243 | uint32_t generation, | 
|  | 2244 | int maxDequeueCount) { | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2245 | uint64_t bqId = 0; | 
|  | 2246 | sp<IGraphicBufferProducer> nullIgbp; | 
|  | 2247 | sp<HGraphicBufferProducer2> nullHgbp; | 
| Pawin Vongmasa | 3866c7e | 2019-01-31 05:21:29 -0800 | [diff] [blame] | 2248 |  | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2249 | sp<HGraphicBufferProducer2> igbp = surface ? | 
|  | 2250 | surface->getHalInterface<HGraphicBufferProducer2>() : nullHgbp; | 
|  | 2251 | if (surface && !igbp) { | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 2252 | igbp = new B2HGraphicBufferProducer2(surface); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2253 | } | 
|  | 2254 |  | 
| Sungtak Lee | fb57902 | 2022-05-10 06:36:15 +0000 | [diff] [blame] | 2255 | std::scoped_lock lock(mOutputMutex); | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 2256 | std::shared_ptr<SurfaceSyncObj> syncObj; | 
|  | 2257 |  | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2258 | if (!surface) { | 
| Sungtak Lee | db14cba | 2021-04-10 00:50:23 -0700 | [diff] [blame] | 2259 | mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr); | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2260 | } else if (surface->getUniqueId(&bqId) != OK) { | 
|  | 2261 | LOG(ERROR) << "setOutputSurface -- " | 
|  | 2262 | "cannot obtain bufferqueue id."; | 
|  | 2263 | bqId = 0; | 
| Sungtak Lee | db14cba | 2021-04-10 00:50:23 -0700 | [diff] [blame] | 2264 | mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr); | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2265 | } else { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2266 | mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount, | 
|  | 2267 | mHidlBase1_2 ? &syncObj : nullptr); | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2268 | } | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 2269 |  | 
|  | 2270 | // set consumer bits | 
|  | 2271 | // TODO: should this get incorporated into setOutputSurface method so that consumer bits | 
|  | 2272 | // can be set atomically? | 
|  | 2273 | uint64_t consumerUsage = kDefaultConsumerUsage; | 
|  | 2274 | { | 
|  | 2275 | if (surface) { | 
| Sungtak Lee | 46a69d6 | 2023-08-12 07:24:24 +0000 | [diff] [blame] | 2276 | uint64_t usage = 0; | 
|  | 2277 | status_t err = surface->getConsumerUsage(&usage); | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 2278 | if (err != NO_ERROR) { | 
|  | 2279 | ALOGD("setOutputSurface -- failed to get consumer usage bits (%d/%s). ignoring", | 
|  | 2280 | err, asString(err)); | 
|  | 2281 | } else { | 
|  | 2282 | // Note: we are adding the default usage because components must support | 
|  | 2283 | // producing output frames that can be displayed an all output surfaces. | 
|  | 2284 |  | 
|  | 2285 | // TODO: do not set usage for tunneled scenario. It is unclear if consumer usage | 
|  | 2286 | // is meaningful in a tunneled scenario; on one hand output buffers exist, but | 
|  | 2287 | // they do not exist inside of C2 scope. Any buffer usage shall be communicated | 
|  | 2288 | // through the sideband channel. | 
|  | 2289 |  | 
| Sungtak Lee | 46a69d6 | 2023-08-12 07:24:24 +0000 | [diff] [blame] | 2290 | consumerUsage = usage | kDefaultConsumerUsage; | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 2291 | } | 
|  | 2292 | } | 
|  | 2293 |  | 
|  | 2294 | C2StreamUsageTuning::output outputUsage{ | 
|  | 2295 | 0u, C2AndroidMemoryUsage::FromGrallocUsage(consumerUsage).expected}; | 
|  | 2296 | std::vector<std::unique_ptr<C2SettingResult>> failures; | 
|  | 2297 | c2_status_t err = config({&outputUsage}, C2_MAY_BLOCK, &failures); | 
|  | 2298 | if (err != C2_OK) { | 
|  | 2299 | ALOGD("setOutputSurface -- failed to set consumer usage (%d/%s)", | 
|  | 2300 | err, asString(err)); | 
|  | 2301 | } | 
|  | 2302 | } | 
|  | 2303 | ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s", | 
|  | 2304 | generation, (long long)consumerUsage, syncObj ? " sync" : ""); | 
| Sungtak Lee | 0851581 | 2019-06-05 11:16:32 -0700 | [diff] [blame] | 2305 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2306 | if (mAidlBase) { | 
|  | 2307 | // FIXME | 
|  | 2308 | return C2_OMITTED; | 
|  | 2309 | } | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2310 | Return<c2_hidl::Status> transStatus = syncObj ? | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2311 | mHidlBase1_2->setOutputSurfaceWithSyncObj( | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 2312 | static_cast<uint64_t>(blockPoolId), | 
|  | 2313 | bqId == 0 ? nullHgbp : igbp, *syncObj) : | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2314 | mHidlBase1_0->setOutputSurface( | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 2315 | static_cast<uint64_t>(blockPoolId), | 
|  | 2316 | bqId == 0 ? nullHgbp : igbp); | 
| Lajos Molnar | 78aa7c9 | 2021-02-18 21:39:01 -0800 | [diff] [blame] | 2317 |  | 
| Sungtak Lee | 8e2e2c6 | 2023-01-17 18:29:34 +0000 | [diff] [blame] | 2318 | mOutputBufferQueue->expireOldWaiters(); | 
|  | 2319 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2320 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2321 | LOG(ERROR) << "setOutputSurface -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2322 | return C2_TRANSACTION_FAILED; | 
|  | 2323 | } | 
|  | 2324 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2325 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2326 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2327 | LOG(DEBUG) << "setOutputSurface -- call failed: " << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2328 | } | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 2329 | ALOGD("Surface configure completed"); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2330 | return status; | 
|  | 2331 | } | 
|  | 2332 |  | 
|  | 2333 | status_t Codec2Client::Component::queueToOutputSurface( | 
|  | 2334 | const C2ConstGraphicBlock& block, | 
|  | 2335 | const QueueBufferInput& input, | 
|  | 2336 | QueueBufferOutput* output) { | 
| Arun Johnson | 7ba6707 | 2023-11-06 22:23:04 +0000 | [diff] [blame] | 2337 | ScopedTrace trace(ATRACE_TAG,"Codec2Client::Component::queueToOutputSurface"); | 
| Pawin Vongmasa | bf69de9 | 2019-10-29 06:21:27 -0700 | [diff] [blame] | 2338 | return mOutputBufferQueue->outputBuffer(block, input, output); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2339 | } | 
|  | 2340 |  | 
| Brian Lindahl | c953b46 | 2023-01-27 16:21:43 -0700 | [diff] [blame] | 2341 | void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) { | 
|  | 2342 | mOutputBufferQueue->pollForRenderedFrames(delta); | 
|  | 2343 | } | 
|  | 2344 |  | 
| Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame] | 2345 | void Codec2Client::Component::setOutputSurfaceMaxDequeueCount( | 
|  | 2346 | int maxDequeueCount) { | 
|  | 2347 | mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount); | 
|  | 2348 | } | 
|  | 2349 |  | 
| Sungtak Lee | c7da7a0 | 2022-05-05 08:45:33 +0000 | [diff] [blame] | 2350 | void Codec2Client::Component::stopUsingOutputSurface( | 
|  | 2351 | C2BlockPool::local_id_t blockPoolId) { | 
| Sungtak Lee | fb57902 | 2022-05-10 06:36:15 +0000 | [diff] [blame] | 2352 | std::scoped_lock lock(mOutputMutex); | 
| Sungtak Lee | c7da7a0 | 2022-05-05 08:45:33 +0000 | [diff] [blame] | 2353 | mOutputBufferQueue->stop(); | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2354 | if (mAidlBase) { | 
|  | 2355 | // FIXME | 
|  | 2356 | return; | 
|  | 2357 | } | 
|  | 2358 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface( | 
| Sungtak Lee | c7da7a0 | 2022-05-05 08:45:33 +0000 | [diff] [blame] | 2359 | static_cast<uint64_t>(blockPoolId), nullptr); | 
|  | 2360 | if (!transStatus.isOk()) { | 
|  | 2361 | LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed."; | 
|  | 2362 | } else { | 
|  | 2363 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2364 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Sungtak Lee | c7da7a0 | 2022-05-05 08:45:33 +0000 | [diff] [blame] | 2365 | if (status != C2_OK) { | 
|  | 2366 | LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: " | 
|  | 2367 | << status << "."; | 
|  | 2368 | } | 
|  | 2369 | } | 
| Sungtak Lee | 8e2e2c6 | 2023-01-17 18:29:34 +0000 | [diff] [blame] | 2370 | mOutputBufferQueue->expireOldWaiters(); | 
| Sungtak Lee | c7da7a0 | 2022-05-05 08:45:33 +0000 | [diff] [blame] | 2371 | } | 
|  | 2372 |  | 
| Sungtak Lee | 214ce61 | 2023-11-01 10:01:13 +0000 | [diff] [blame] | 2373 | void Codec2Client::Component::onBufferReleasedFromOutputSurface( | 
|  | 2374 | uint32_t generation) { | 
| Sungtak Lee | 6700cc9 | 2023-11-22 18:04:05 +0000 | [diff] [blame] | 2375 | mOutputBufferQueue->onBufferReleased(generation); | 
| Sungtak Lee | 214ce61 | 2023-11-01 10:01:13 +0000 | [diff] [blame] | 2376 | } | 
|  | 2377 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2378 | c2_status_t Codec2Client::Component::connectToInputSurface( | 
|  | 2379 | const std::shared_ptr<InputSurface>& inputSurface, | 
|  | 2380 | std::shared_ptr<InputSurfaceConnection>* connection) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2381 | if (mAidlBase) { | 
|  | 2382 | // FIXME | 
|  | 2383 | return C2_OMITTED; | 
|  | 2384 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2385 | c2_status_t status; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2386 | Return<void> transStatus = mHidlBase1_0->connectToInputSurface( | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2387 | inputSurface->mBase, | 
|  | 2388 | [&status, connection]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2389 | c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2390 | status = static_cast<c2_status_t>(s); | 
|  | 2391 | if (status != C2_OK) { | 
|  | 2392 | LOG(DEBUG) << "connectToInputSurface -- call failed: " | 
|  | 2393 | << status << "."; | 
|  | 2394 | return; | 
|  | 2395 | } | 
|  | 2396 | *connection = std::make_shared<InputSurfaceConnection>(c); | 
|  | 2397 | }); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2398 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2399 | LOG(ERROR) << "connectToInputSurface -- transaction failed"; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2400 | return C2_TRANSACTION_FAILED; | 
|  | 2401 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2402 | return status; | 
|  | 2403 | } | 
|  | 2404 |  | 
|  | 2405 | c2_status_t Codec2Client::Component::connectToOmxInputSurface( | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 2406 | const sp<HGraphicBufferProducer1>& producer, | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2407 | const sp<HGraphicBufferSource>& source, | 
|  | 2408 | std::shared_ptr<InputSurfaceConnection>* connection) { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2409 | if (mAidlBase) { | 
|  | 2410 | LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL"; | 
|  | 2411 | return C2_OMITTED; | 
|  | 2412 | } | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2413 | c2_status_t status; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2414 | Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface( | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2415 | producer, source, | 
|  | 2416 | [&status, connection]( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2417 | c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2418 | status = static_cast<c2_status_t>(s); | 
|  | 2419 | if (status != C2_OK) { | 
|  | 2420 | LOG(DEBUG) << "connectToOmxInputSurface -- call failed: " | 
|  | 2421 | << status << "."; | 
|  | 2422 | return; | 
|  | 2423 | } | 
|  | 2424 | *connection = std::make_shared<InputSurfaceConnection>(c); | 
|  | 2425 | }); | 
|  | 2426 | if (!transStatus.isOk()) { | 
|  | 2427 | LOG(ERROR) << "connectToOmxInputSurface -- transaction failed."; | 
|  | 2428 | return C2_TRANSACTION_FAILED; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2429 | } | 
|  | 2430 | return status; | 
|  | 2431 | } | 
|  | 2432 |  | 
|  | 2433 | c2_status_t Codec2Client::Component::disconnectFromInputSurface() { | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2434 | if (mAidlBase) { | 
|  | 2435 | // FIXME | 
|  | 2436 | return C2_OMITTED; | 
|  | 2437 | } | 
|  | 2438 | Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface(); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2439 | if (!transStatus.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2440 | LOG(ERROR) << "disconnectToInputSurface -- transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2441 | return C2_TRANSACTION_FAILED; | 
|  | 2442 | } | 
|  | 2443 | c2_status_t status = | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2444 | static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2445 | if (status != C2_OK) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2446 | LOG(DEBUG) << "disconnectFromInputSurface -- call failed: " | 
|  | 2447 | << status << "."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2448 | } | 
|  | 2449 | return status; | 
|  | 2450 | } | 
|  | 2451 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2452 | Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() { | 
|  | 2453 | // This object never gets destructed | 
|  | 2454 | static AidlDeathManager *sManager = new AidlDeathManager(); | 
|  | 2455 | return sManager; | 
|  | 2456 | } | 
|  | 2457 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2458 | c2_status_t Codec2Client::Component::setDeathListener( | 
|  | 2459 | const std::shared_ptr<Component>& component, | 
|  | 2460 | const std::shared_ptr<Listener>& listener) { | 
|  | 2461 |  | 
|  | 2462 | struct HidlDeathRecipient : public hardware::hidl_death_recipient { | 
|  | 2463 | std::weak_ptr<Component> component; | 
|  | 2464 | std::weak_ptr<Listener> base; | 
|  | 2465 |  | 
|  | 2466 | virtual void serviceDied( | 
|  | 2467 | uint64_t /* cookie */, | 
|  | 2468 | const wp<::android::hidl::base::V1_0::IBase>& /* who */ | 
|  | 2469 | ) override { | 
|  | 2470 | if (std::shared_ptr<Codec2Client::Listener> listener = base.lock()) { | 
|  | 2471 | listener->onDeath(component); | 
|  | 2472 | } else { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2473 | LOG(DEBUG) << "onDeath -- listener died."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2474 | } | 
|  | 2475 | } | 
|  | 2476 | }; | 
|  | 2477 |  | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2478 | if (component->mAidlBase) { | 
|  | 2479 | size_t seq; | 
|  | 2480 | if (GetAidlDeathManager()->linkToDeath(component, listener, &seq)) { | 
|  | 2481 | component->mAidlDeathSeq = seq; | 
|  | 2482 | } | 
|  | 2483 | return C2_OK; | 
|  | 2484 | } | 
|  | 2485 |  | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2486 | sp<HidlDeathRecipient> deathRecipient = new HidlDeathRecipient(); | 
|  | 2487 | deathRecipient->base = listener; | 
|  | 2488 | deathRecipient->component = component; | 
|  | 2489 |  | 
|  | 2490 | component->mDeathRecipient = deathRecipient; | 
| Wonsik Kim | e8e9815 | 2022-12-16 16:04:17 -0800 | [diff] [blame] | 2491 | Return<bool> transResult = component->mHidlBase1_0->linkToDeath( | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2492 | component->mDeathRecipient, 0); | 
|  | 2493 | if (!transResult.isOk()) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2494 | LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2495 | return C2_TRANSACTION_FAILED; | 
|  | 2496 | } | 
|  | 2497 | if (!static_cast<bool>(transResult)) { | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2498 | LOG(DEBUG) << "setDeathListener -- linkToDeath() call failed."; | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2499 | return C2_CORRUPTED; | 
|  | 2500 | } | 
|  | 2501 | return C2_OK; | 
|  | 2502 | } | 
|  | 2503 |  | 
|  | 2504 | // Codec2Client::InputSurface | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2505 | Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base) | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2506 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2507 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 2508 | Return<sp<c2_hidl::IConfigurable>> transResult = | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2509 | base->getConfigurable(); | 
|  | 2510 | return transResult.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2511 | static_cast<sp<c2_hidl::IConfigurable>>(transResult) : | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2512 | nullptr; | 
|  | 2513 | }() | 
|  | 2514 | }, | 
|  | 2515 | mBase{base}, | 
|  | 2516 | mGraphicBufferProducer{new | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 2517 | H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> { | 
|  | 2518 | Return<sp<HGraphicBufferProducer2>> transResult = | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2519 | base->getGraphicBufferProducer(); | 
|  | 2520 | return transResult.isOk() ? | 
| Pawin Vongmasa | ef939bf | 2019-03-03 04:44:59 -0800 | [diff] [blame] | 2521 | static_cast<sp<HGraphicBufferProducer2>>(transResult) : | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2522 | nullptr; | 
|  | 2523 | }())} { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2524 | } | 
|  | 2525 |  | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2526 | sp<IGraphicBufferProducer> | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2527 | Codec2Client::InputSurface::getGraphicBufferProducer() const { | 
|  | 2528 | return mGraphicBufferProducer; | 
|  | 2529 | } | 
|  | 2530 |  | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2531 | sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2532 | return mBase; | 
|  | 2533 | } | 
|  | 2534 |  | 
|  | 2535 | // Codec2Client::InputSurfaceConnection | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2536 | Codec2Client::InputSurfaceConnection::InputSurfaceConnection( | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2537 | const sp<c2_hidl::IInputSurfaceConnection>& base) | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2538 | : Configurable{ | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2539 | [base]() -> sp<c2_hidl::IConfigurable> { | 
|  | 2540 | Return<sp<c2_hidl::IConfigurable>> transResult = | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2541 | base->getConfigurable(); | 
|  | 2542 | return transResult.isOk() ? | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2543 | static_cast<sp<c2_hidl::IConfigurable>>(transResult) : | 
| Pawin Vongmasa | 1c75a23 | 2019-01-09 04:41:52 -0800 | [diff] [blame] | 2544 | nullptr; | 
|  | 2545 | }() | 
|  | 2546 | }, | 
|  | 2547 | mBase{base} { | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2548 | } | 
|  | 2549 |  | 
|  | 2550 | c2_status_t Codec2Client::InputSurfaceConnection::disconnect() { | 
| Wonsik Kim | c8fc2c3 | 2022-12-12 14:43:00 -0800 | [diff] [blame] | 2551 | Return<c2_hidl::Status> transResult = mBase->disconnect(); | 
|  | 2552 | return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult)); | 
| Pawin Vongmasa | 3665390 | 2018-11-15 00:10:25 -0800 | [diff] [blame] | 2553 | } | 
|  | 2554 |  | 
|  | 2555 | }  // namespace android |