Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2021 The Android Open Source Project |
| 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 |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 18 | #define LOG_TAG "Codec2-Component-Aidl" |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 19 | #include <android-base/logging.h> |
| 20 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 21 | #include <codec2/aidl/Component.h> |
| 22 | #include <codec2/aidl/ComponentStore.h> |
| 23 | #include <codec2/aidl/InputBufferManager.h> |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 24 | |
| 25 | #ifndef __ANDROID_APEX__ |
| 26 | #include <FilterWrapper.h> |
| 27 | #endif |
| 28 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 29 | #include <android/binder_auto_utils.h> |
| 30 | #include <android/binder_interface_utils.h> |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 31 | #include <utils/Timers.h> |
| 32 | |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 33 | #include <C2Debug.h> |
| 34 | #include <C2PlatformSupport.h> |
| 35 | |
| 36 | #include <chrono> |
| 37 | #include <thread> |
| 38 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 39 | namespace aidl { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 40 | namespace android { |
| 41 | namespace hardware { |
| 42 | namespace media { |
| 43 | namespace c2 { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 44 | namespace utils { |
| 45 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 46 | using ::aidl::android::hardware::common::NativeHandle; |
| 47 | using ::aidl::android::hardware::media::bufferpool2::IClientManager; |
| 48 | using ::ndk::ScopedAStatus; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 49 | |
| 50 | // ComponentListener wrapper |
| 51 | struct Component::Listener : public C2Component::Listener { |
| 52 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 53 | Listener(const std::shared_ptr<Component>& component) : |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 54 | mComponent(component), |
| 55 | mListener(component->mListener) { |
| 56 | } |
| 57 | |
| 58 | virtual void onError_nb( |
| 59 | std::weak_ptr<C2Component> /* c2component */, |
| 60 | uint32_t errorCode) override { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 61 | std::shared_ptr<IComponentListener> listener = mListener.lock(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 62 | if (listener) { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 63 | ScopedAStatus transStatus = listener->onError(Status{Status::OK}, errorCode); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 64 | if (!transStatus.isOk()) { |
| 65 | LOG(ERROR) << "Component::Listener::onError_nb -- " |
| 66 | << "transaction failed."; |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | virtual void onTripped_nb( |
| 72 | std::weak_ptr<C2Component> /* c2component */, |
| 73 | std::vector<std::shared_ptr<C2SettingResult>> c2settingResult |
| 74 | ) override { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 75 | std::shared_ptr<IComponentListener> listener = mListener.lock(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 76 | if (listener) { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 77 | std::vector<SettingResult> settingResults(c2settingResult.size()); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 78 | size_t ix = 0; |
| 79 | for (const std::shared_ptr<C2SettingResult> &c2result : |
| 80 | c2settingResult) { |
| 81 | if (c2result) { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 82 | if (!ToAidl(&settingResults[ix++], *c2result)) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 83 | break; |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | settingResults.resize(ix); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 88 | ScopedAStatus transStatus = listener->onTripped(settingResults); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 89 | if (!transStatus.isOk()) { |
| 90 | LOG(ERROR) << "Component::Listener::onTripped_nb -- " |
| 91 | << "transaction failed."; |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | virtual void onWorkDone_nb( |
| 97 | std::weak_ptr<C2Component> /* c2component */, |
| 98 | std::list<std::unique_ptr<C2Work>> c2workItems) override { |
| 99 | for (const std::unique_ptr<C2Work>& work : c2workItems) { |
| 100 | if (work) { |
| 101 | if (work->worklets.empty() |
| 102 | || !work->worklets.back() |
| 103 | || (work->worklets.back()->output.flags & |
| 104 | C2FrameData::FLAG_INCOMPLETE) == 0) { |
| 105 | InputBufferManager:: |
| 106 | unregisterFrameData(mListener, work->input); |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 111 | std::shared_ptr<IComponentListener> listener = mListener.lock(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 112 | if (listener) { |
| 113 | WorkBundle workBundle; |
| 114 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 115 | std::shared_ptr<Component> strongComponent = mComponent.lock(); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 116 | if (!ToAidl(&workBundle, c2workItems, strongComponent ? |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 117 | &strongComponent->mBufferPoolSender : nullptr)) { |
| 118 | LOG(ERROR) << "Component::Listener::onWorkDone_nb -- " |
| 119 | << "received corrupted work items."; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 120 | return; |
| 121 | } |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 122 | ScopedAStatus transStatus = listener->onWorkDone(workBundle); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 123 | if (!transStatus.isOk()) { |
| 124 | LOG(ERROR) << "Component::Listener::onWorkDone_nb -- " |
| 125 | << "transaction failed."; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 126 | return; |
| 127 | } |
Sungtak Lee | 72dfba6 | 2023-09-07 23:26:30 +0000 | [diff] [blame] | 128 | // If output blocks are originally owned by the client(not by HAL), |
| 129 | // return the ownership to the client. (Since the blocks are |
| 130 | // transferred to the client here.) |
| 131 | ReturnOutputBlocksToClientIfNeeded(c2workItems); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 132 | } |
| 133 | } |
| 134 | |
| 135 | protected: |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 136 | std::weak_ptr<Component> mComponent; |
| 137 | std::weak_ptr<IComponentListener> mListener; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 138 | }; |
| 139 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 140 | // Component::DeathContext |
| 141 | struct Component::DeathContext { |
| 142 | std::weak_ptr<Component> mWeakComp; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 143 | }; |
| 144 | |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 145 | // Component |
| 146 | Component::Component( |
| 147 | const std::shared_ptr<C2Component>& component, |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 148 | const std::shared_ptr<IComponentListener>& listener, |
| 149 | const std::shared_ptr<ComponentStore>& store, |
| 150 | const std::shared_ptr<IClientManager>& clientPoolManager) |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 151 | : mComponent{component}, |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 152 | mInterface{SharedRefBase::make<ComponentInterface>( |
| 153 | component->intf(), store->getParameterCache())}, |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 154 | mListener{listener}, |
| 155 | mStore{store}, |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 156 | mBufferPoolSender{clientPoolManager}, |
| 157 | mDeathContext(nullptr) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 158 | // Retrieve supported parameters from store |
| 159 | // TODO: We could cache this per component/interface type |
| 160 | mInit = mInterface->status(); |
| 161 | } |
| 162 | |
| 163 | c2_status_t Component::status() const { |
| 164 | return mInit; |
| 165 | } |
| 166 | |
| 167 | // Methods from ::android::hardware::media::c2::V1_1::IComponent |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 168 | ScopedAStatus Component::queue(const WorkBundle& workBundle) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 169 | std::list<std::unique_ptr<C2Work>> c2works; |
| 170 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 171 | if (!FromAidl(&c2works, workBundle)) { |
| 172 | return ScopedAStatus::fromServiceSpecificError(Status::CORRUPTED); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | // Register input buffers. |
| 176 | for (const std::unique_ptr<C2Work>& work : c2works) { |
| 177 | if (work) { |
| 178 | InputBufferManager:: |
| 179 | registerFrameData(mListener, work->input); |
| 180 | } |
| 181 | } |
| 182 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 183 | c2_status_t err = mComponent->queue_nb(&c2works); |
| 184 | if (err == C2_OK) { |
| 185 | return ScopedAStatus::ok(); |
| 186 | } |
| 187 | return ScopedAStatus::fromServiceSpecificError(err); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 188 | } |
| 189 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 190 | ScopedAStatus Component::flush(WorkBundle *flushedWorkBundle) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 191 | std::list<std::unique_ptr<C2Work>> c2flushedWorks; |
| 192 | c2_status_t c2res = mComponent->flush_sm( |
| 193 | C2Component::FLUSH_COMPONENT, |
| 194 | &c2flushedWorks); |
| 195 | |
| 196 | // Unregister input buffers. |
| 197 | for (const std::unique_ptr<C2Work>& work : c2flushedWorks) { |
| 198 | if (work) { |
| 199 | if (work->worklets.empty() |
| 200 | || !work->worklets.back() |
| 201 | || (work->worklets.back()->output.flags & |
| 202 | C2FrameData::FLAG_INCOMPLETE) == 0) { |
| 203 | InputBufferManager:: |
| 204 | unregisterFrameData(mListener, work->input); |
| 205 | } |
| 206 | } |
| 207 | } |
| 208 | |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 209 | if (c2res == C2_OK) { |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 210 | if (!ToAidl(flushedWorkBundle, c2flushedWorks, &mBufferPoolSender)) { |
| 211 | c2res = C2_CORRUPTED; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 212 | } |
| 213 | } |
Sungtak Lee | 72dfba6 | 2023-09-07 23:26:30 +0000 | [diff] [blame] | 214 | // If output blocks are originally owned by the client(not by HAL), |
| 215 | // return the ownership to the client. (Since the blocks are |
| 216 | // transferred to the client here.) |
| 217 | ReturnOutputBlocksToClientIfNeeded(c2flushedWorks); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 218 | if (c2res == C2_OK) { |
| 219 | return ScopedAStatus::ok(); |
| 220 | } |
| 221 | return ScopedAStatus::fromServiceSpecificError(c2res); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 222 | } |
| 223 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 224 | ScopedAStatus Component::drain(bool withEos) { |
| 225 | c2_status_t res = mComponent->drain_nb(withEos ? |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 226 | C2Component::DRAIN_COMPONENT_WITH_EOS : |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 227 | C2Component::DRAIN_COMPONENT_NO_EOS); |
| 228 | if (res == C2_OK) { |
| 229 | return ScopedAStatus::ok(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 230 | } |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 231 | return ScopedAStatus::fromServiceSpecificError(res); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | namespace /* unnamed */ { |
| 235 | |
| 236 | struct BlockPoolIntf : public ConfigurableC2Intf { |
| 237 | BlockPoolIntf(const std::shared_ptr<C2BlockPool>& pool) |
| 238 | : ConfigurableC2Intf{ |
| 239 | "C2BlockPool:" + |
| 240 | (pool ? std::to_string(pool->getLocalId()) : "null"), |
| 241 | 0}, |
| 242 | mPool{pool} { |
| 243 | } |
| 244 | |
| 245 | virtual c2_status_t config( |
| 246 | const std::vector<C2Param*>& params, |
| 247 | c2_blocking_t mayBlock, |
| 248 | std::vector<std::unique_ptr<C2SettingResult>>* const failures |
| 249 | ) override { |
| 250 | (void)params; |
| 251 | (void)mayBlock; |
| 252 | (void)failures; |
| 253 | return C2_OK; |
| 254 | } |
| 255 | |
| 256 | virtual c2_status_t query( |
| 257 | const std::vector<C2Param::Index>& indices, |
| 258 | c2_blocking_t mayBlock, |
| 259 | std::vector<std::unique_ptr<C2Param>>* const params |
| 260 | ) const override { |
| 261 | (void)indices; |
| 262 | (void)mayBlock; |
| 263 | (void)params; |
| 264 | return C2_OK; |
| 265 | } |
| 266 | |
| 267 | virtual c2_status_t querySupportedParams( |
| 268 | std::vector<std::shared_ptr<C2ParamDescriptor>>* const params |
| 269 | ) const override { |
| 270 | (void)params; |
| 271 | return C2_OK; |
| 272 | } |
| 273 | |
| 274 | virtual c2_status_t querySupportedValues( |
| 275 | std::vector<C2FieldSupportedValuesQuery>& fields, |
| 276 | c2_blocking_t mayBlock) const override { |
| 277 | (void)fields; |
| 278 | (void)mayBlock; |
| 279 | return C2_OK; |
| 280 | } |
| 281 | |
| 282 | protected: |
| 283 | std::shared_ptr<C2BlockPool> mPool; |
| 284 | }; |
| 285 | |
| 286 | } // unnamed namespace |
| 287 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 288 | ScopedAStatus Component::createBlockPool( |
| 289 | const IComponent::BlockPoolAllocator &allocator, |
| 290 | IComponent::BlockPool *blockPool) { |
| 291 | std::shared_ptr<C2BlockPool> c2BlockPool; |
| 292 | static constexpr IComponent::BlockPoolAllocator::Tag ALLOCATOR_ID = |
| 293 | IComponent::BlockPoolAllocator::allocatorId; |
| 294 | static constexpr IComponent::BlockPoolAllocator::Tag IGBA = |
Sungtak Lee | 0489c87 | 2023-10-28 01:18:46 +0000 | [diff] [blame] | 295 | IComponent::BlockPoolAllocator::allocator; |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 296 | c2_status_t status = C2_OK; |
Sungtak Lee | aa71b5c | 2023-11-04 09:21:15 +0000 | [diff] [blame] | 297 | ::android::C2PlatformAllocatorDesc allocatorParam; |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 298 | switch (allocator.getTag()) { |
Sungtak Lee | aa71b5c | 2023-11-04 09:21:15 +0000 | [diff] [blame] | 299 | case ALLOCATOR_ID: { |
| 300 | allocatorParam.allocatorId = |
| 301 | allocator.get<IComponent::BlockPoolAllocator::allocatorId>(); |
| 302 | } |
| 303 | break; |
| 304 | case IGBA: { |
| 305 | allocatorParam.allocatorId = ::android::C2PlatformAllocatorStore::IGBA; |
| 306 | allocatorParam.igba = |
| 307 | allocator.get<IComponent::BlockPoolAllocator::allocator>().igba; |
| 308 | allocatorParam.waitableFd.reset( |
| 309 | allocator.get<IComponent::BlockPoolAllocator::allocator>() |
| 310 | .waitableFd.dup().release()); |
| 311 | } |
| 312 | break; |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 313 | default: |
Sungtak Lee | aa71b5c | 2023-11-04 09:21:15 +0000 | [diff] [blame] | 314 | return ScopedAStatus::fromServiceSpecificError(C2_CORRUPTED); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 315 | } |
Sungtak Lee | aa71b5c | 2023-11-04 09:21:15 +0000 | [diff] [blame] | 316 | #ifdef __ANDROID_APEX__ |
| 317 | status = ::android::CreateCodec2BlockPool( |
| 318 | allocatorParam, |
| 319 | mComponent, |
| 320 | &c2BlockPool); |
| 321 | #else |
| 322 | status = ComponentStore::GetFilterWrapper()->createBlockPool( |
| 323 | allocatorParam, |
| 324 | mComponent, |
| 325 | &c2BlockPool); |
| 326 | #endif |
| 327 | if (status != C2_OK) { |
| 328 | return ScopedAStatus::fromServiceSpecificError(status); |
| 329 | } |
| 330 | { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 331 | mBlockPoolsMutex.lock(); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 332 | mBlockPools.emplace(c2BlockPool->getLocalId(), c2BlockPool); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 333 | mBlockPoolsMutex.unlock(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 334 | } |
| 335 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 336 | blockPool->blockPoolId = c2BlockPool ? c2BlockPool->getLocalId() : 0; |
| 337 | blockPool->configurable = SharedRefBase::make<CachedConfigurable>( |
| 338 | std::make_unique<BlockPoolIntf>(c2BlockPool)); |
Sungtak Lee | aa71b5c | 2023-11-04 09:21:15 +0000 | [diff] [blame] | 339 | return ScopedAStatus::ok(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 340 | } |
| 341 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 342 | ScopedAStatus Component::destroyBlockPool(int64_t blockPoolId) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 343 | std::lock_guard<std::mutex> lock(mBlockPoolsMutex); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 344 | if (mBlockPools.erase(blockPoolId) == 1) { |
| 345 | return ScopedAStatus::ok(); |
| 346 | } |
| 347 | return ScopedAStatus::fromServiceSpecificError(Status::CORRUPTED); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 348 | } |
| 349 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 350 | ScopedAStatus Component::start() { |
| 351 | c2_status_t status = mComponent->start(); |
| 352 | if (status == C2_OK) { |
| 353 | return ScopedAStatus::ok(); |
| 354 | } |
| 355 | return ScopedAStatus::fromServiceSpecificError(status); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 356 | } |
| 357 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 358 | ScopedAStatus Component::stop() { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 359 | InputBufferManager::unregisterFrameData(mListener); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 360 | c2_status_t status = mComponent->stop(); |
| 361 | if (status == C2_OK) { |
| 362 | return ScopedAStatus::ok(); |
| 363 | } |
| 364 | return ScopedAStatus::fromServiceSpecificError(status); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 365 | } |
| 366 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 367 | ScopedAStatus Component::reset() { |
| 368 | c2_status_t status = mComponent->reset(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 369 | { |
| 370 | std::lock_guard<std::mutex> lock(mBlockPoolsMutex); |
| 371 | mBlockPools.clear(); |
| 372 | } |
| 373 | InputBufferManager::unregisterFrameData(mListener); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 374 | if (status == C2_OK) { |
| 375 | return ScopedAStatus::ok(); |
| 376 | } |
| 377 | return ScopedAStatus::fromServiceSpecificError(status); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 378 | } |
| 379 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 380 | ScopedAStatus Component::release() { |
| 381 | c2_status_t status = mComponent->release(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 382 | { |
| 383 | std::lock_guard<std::mutex> lock(mBlockPoolsMutex); |
| 384 | mBlockPools.clear(); |
| 385 | } |
| 386 | InputBufferManager::unregisterFrameData(mListener); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 387 | if (status == C2_OK) { |
| 388 | return ScopedAStatus::ok(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 389 | } |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 390 | return ScopedAStatus::fromServiceSpecificError(status); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 391 | } |
| 392 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 393 | ScopedAStatus Component::getInterface( |
| 394 | std::shared_ptr<IComponentInterface> *intf) { |
| 395 | *intf = mInterface; |
| 396 | return ScopedAStatus::ok(); |
| 397 | } |
| 398 | |
| 399 | ScopedAStatus Component::configureVideoTunnel( |
| 400 | int32_t avSyncHwId, NativeHandle *handle) { |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 401 | (void)avSyncHwId; |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 402 | (void)handle; |
| 403 | return ScopedAStatus::fromServiceSpecificError(Status::OMITTED); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 404 | } |
| 405 | |
Sungtak Lee | 95fa087 | 2024-01-04 10:24:12 +0000 | [diff] [blame] | 406 | ScopedAStatus Component::connectToInputSurface( |
| 407 | const std::shared_ptr<IInputSurface>& inputSurface, |
| 408 | std::shared_ptr<IInputSurfaceConnection> *connection) { |
| 409 | // TODO |
| 410 | (void)inputSurface; |
| 411 | (void)connection; |
| 412 | return ScopedAStatus::fromServiceSpecificError(Status::OMITTED); |
| 413 | } |
| 414 | |
| 415 | ScopedAStatus Component::asInputSink( |
| 416 | std::shared_ptr<IInputSink> *sink) { |
| 417 | // TODO |
| 418 | (void)sink; |
| 419 | return ScopedAStatus::fromServiceSpecificError(Status::OMITTED); |
| 420 | } |
| 421 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 422 | void Component::initListener(const std::shared_ptr<Component>& self) { |
Wonsik Kim | 8e2a19f | 2023-08-30 11:05:45 -0700 | [diff] [blame] | 423 | if (__builtin_available(android __ANDROID_API_T__, *)) { |
| 424 | std::shared_ptr<C2Component::Listener> c2listener = |
| 425 | std::make_shared<Listener>(self); |
| 426 | c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK); |
| 427 | if (res != C2_OK) { |
| 428 | mInit = res; |
| 429 | } |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 430 | |
Wonsik Kim | 8e2a19f | 2023-08-30 11:05:45 -0700 | [diff] [blame] | 431 | mDeathRecipient = ::ndk::ScopedAIBinder_DeathRecipient( |
| 432 | AIBinder_DeathRecipient_new(OnBinderDied)); |
Wonsik Kim | 8e35c06 | 2023-10-17 13:40:56 -0700 | [diff] [blame] | 433 | mDeathContext = new DeathContext{ref<Component>()}; |
Wonsik Kim | 8e2a19f | 2023-08-30 11:05:45 -0700 | [diff] [blame] | 434 | AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), OnBinderUnlinked); |
| 435 | AIBinder_linkToDeath(mListener->asBinder().get(), mDeathRecipient.get(), mDeathContext); |
| 436 | } else { |
| 437 | mInit = C2_NO_INIT; |
| 438 | } |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 439 | } |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 440 | |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 441 | // static |
| 442 | void Component::OnBinderDied(void *cookie) { |
| 443 | DeathContext *context = (DeathContext *)cookie; |
| 444 | std::shared_ptr<Component> comp = context->mWeakComp.lock(); |
| 445 | if (comp) { |
| 446 | comp->release(); |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 447 | } |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 448 | } |
| 449 | |
| 450 | // static |
| 451 | void Component::OnBinderUnlinked(void *cookie) { |
| 452 | delete (DeathContext *)cookie; |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 453 | } |
| 454 | |
| 455 | Component::~Component() { |
| 456 | InputBufferManager::unregisterFrameData(mListener); |
| 457 | mStore->reportComponentDeath(this); |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 458 | if (mDeathRecipient.get()) { |
| 459 | AIBinder_unlinkToDeath(mListener->asBinder().get(), mDeathRecipient.get(), mDeathContext); |
| 460 | } |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 461 | } |
| 462 | |
| 463 | } // namespace utils |
Wonsik Kim | 5ec480f | 2023-07-11 14:25:55 -0700 | [diff] [blame] | 464 | } // namespace c2 |
| 465 | } // namespace media |
| 466 | } // namespace hardware |
| 467 | } // namespace android |
Wonsik Kim | f003264 | 2023-07-20 14:42:27 -0700 | [diff] [blame] | 468 | } // namespace aidl |