C2Store.cpp revision 51ea56a991d6371e35c8d0bb5001e721cc63f8ee
14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2017 The Android Open Source Project
34344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
44344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Licensed under the Apache License, Version 2.0 (the "License");
54344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * you may not use this file except in compliance with the License.
64344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * You may obtain a copy of the License at
74344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
84344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *      http://www.apache.org/licenses/LICENSE-2.0
94344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Unless required by applicable law or agreed to in writing, software
114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * distributed under the License is distributed on an "AS IS" BASIS,
124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * See the License for the specific language governing permissions and
144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * limitations under the License.
154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#define LOG_TAG "C2Store"
1839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#define LOG_NDEBUG 0
1939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#include <utils/Log.h>
2039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2AllocatorGralloc.h>
224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2AllocatorIon.h>
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2BufferPriv.h>
2439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#include <C2BqBufferPriv.h>
254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2Component.h>
2651ea56a991d6371e35c8d0bb5001e721cc63f8eeLajos Molnar#include <C2Config.h>
274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2PlatformSupport.h>
289fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim#include <util/C2InterfaceHelper.h>
294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <dlfcn.h>
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <map>
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <memory>
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <mutex>
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * The platform allocator store provides basic allocator-types for the framework based on ion and
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * gralloc. Allocators are not meant to be updatable.
414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Provide allocator based on ashmem
434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Make this allocator store extendable
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2PlatformAllocatorStoreImpl(
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /* ionmapper */
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    );
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t fetchAllocator(
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const override {
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override {
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return "android.allocator-store";
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton ion allocator
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchIonAllocator();
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton gralloc allocator
694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    allocator->reset();
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: should we implement a generic registry for all, and use that?
804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::ION:
814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_LINEAR:
824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchIonAllocator();
834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::GRALLOC:
864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_GRAPHIC:
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchGrallocAllocator();
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (*allocator == nullptr) {
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NO_MEMORY;
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2Allocator> ionAllocator;
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator = ionAllocator.lock();
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ionAllocator = allocator;
1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2Allocator> grallocAllocator;
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        grallocAllocator = allocator;
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
1214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
1244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::make_shared<C2PlatformAllocatorStoreImpl>();
1254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leenamespace {
12839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
12939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeclass _C2BlockPoolCache {
13039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leepublic:
13139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
13239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
13339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t _createBlockPool(
1348060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
1358060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
1368060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t poolId,
13739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
13839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2AllocatorStore> allocatorStore =
13939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                GetCodec2PlatformAllocatorStore();
14039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2Allocator> allocator;
14139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        c2_status_t res = C2_NOT_FOUND;
14239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
14339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        switch(allocatorId) {
14439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            case C2PlatformAllocatorStore::ION:
14539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
14639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
14739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
14839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    std::shared_ptr<C2PooledBlockPool> ptr =
14939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2PooledBlockPool>(
15039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
15139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
15239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    mIonBlockPools[poolId] = ptr;
1538060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
15439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
15539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
15639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            case C2PlatformAllocatorStore::GRALLOC:
15739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
15839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                        C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
15939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
16039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    std::shared_ptr<C2BufferQueueBlockPool> ptr =
16139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2BufferQueueBlockPool>(
16239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
16339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
16439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    mBqBlockPools[poolId] = ptr;
1658060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
16639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
16739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
16839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            default:
16939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
17039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
17139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return res;
17239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
17339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
17439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t createBlockPool(
1758060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
1768060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
1778060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
1788060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        return _createBlockPool(allocatorId, component, mBlockPoolSeqId++, pool);
17939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
18039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
1818060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    bool getBlockPool(
1828060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t blockPoolId,
1838060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
1848060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
18539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        // TODO: use one iterator for mulitple blockpool type scalability.
1868060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        std::shared_ptr<C2BlockPool> ptr;
18739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        auto ionIt = mIonBlockPools.find(blockPoolId);
18839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        if (ionIt != mIonBlockPools.end()) {
1898060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            ptr = ionIt->second.lock();
1908060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!ptr) {
1918060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mIonBlockPools.erase(ionIt);
1928060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
1938060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
1948060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
1958060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
1968060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    *pool = ptr;
1978060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
1988060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
19939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
20039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
20139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        auto bqIt = mBqBlockPools.find(blockPoolId);
20239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        if (bqIt != mBqBlockPools.end()) {
2038060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            ptr = bqIt->second.lock();
2048060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!ptr) {
2058060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mBqBlockPools.erase(bqIt);
2068060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
2078060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
2088060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
2098060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
2108060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    *pool = ptr;
2118060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
2128060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
21339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
21439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
21539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return false;
21639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
21739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
2188060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    bool setBufferQueue(
2198060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t blockPoolId,
2208060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
2218060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            const sp<HGraphicBufferProducer> &producer) {
22239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        auto bqIt = mBqBlockPools.find(blockPoolId);
22339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        if (bqIt != mBqBlockPools.end()) {
22439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            std::shared_ptr<C2BufferQueueBlockPool> pool = bqIt->second.lock();
2258060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!pool) {
2268060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mBqBlockPools.erase(bqIt);
2278060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
2288060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
2298060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
2308060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
2318060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    pool->configureProducer(producer);
2328060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
2338060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
23439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
23539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
23639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return false;
23739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
23839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
23939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeprivate:
24039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    C2BlockPool::local_id_t mBlockPoolSeqId;
24139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2PooledBlockPool>> mIonBlockPools;
24239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BufferQueueBlockPool>> mBqBlockPools;
2438060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee
2448060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<const C2Component>> mComponents;
24539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee};
24639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
24739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
24839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::make_unique<_C2BlockPoolCache>();
24939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::mutex sBlockPoolCacheMutex;
25039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
25139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee} // anynymous namespace
25239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t GetCodec2BlockPool(
2544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
2554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
2564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
2574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!component) {
2584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_BAD_VALUE;
2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
26039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator;
2634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = C2_NOT_FOUND;
2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
26539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    if (id >= C2BlockPool::PLATFORM_START) {
2668060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        if (sBlockPoolCache->getBlockPool(id, component, pool)) {
26739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            return C2_OK;
26839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
26939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
27039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_LINEAR:
2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
2764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_GRAPHIC:
2794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
2804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
2814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
28439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    // TODO: remove this. this is temporary
28539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    case C2BlockPool::PLATFORM_START:
2868060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        res = sBlockPoolCache->_createBlockPool(
2878060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                C2PlatformAllocatorStore::GRALLOC, component, id, pool);
28839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        break;
2894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
2904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
2914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t CreateCodec2BlockPool(
2964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlatformAllocatorStore::id_t allocatorId,
2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component> component,
2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!component) {
3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_BAD_VALUE;
3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
30439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
3058060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    return sBlockPoolCache->createBlockPool(allocatorId, component, pool);
3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformComponentStore : public C2ComponentStore {
3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
3114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override;
3134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedValues_sm(
3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
3154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedParams_nb(
3164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
3174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t query_sm(
3184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &stackParams,
3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param::Index> &heapParamIndices,
3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
3214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createInterface(
3224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
3234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createComponent(
3244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2Component> *const component) override;
3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t copyBuffer(
3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t config_sm(
3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &params,
3294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
3304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2PlatformComponentStore();
3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual ~C2PlatformComponentStore() override = default;
3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loaded component module.
3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo provide a way to add traits to known components here to avoid loading the .so-s
3404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for listComponents
3414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentModule : public C2ComponentFactory,
3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            public std::enable_shared_from_this<ComponentModule> {
3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createComponent(
3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2Component> *component,
3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
3474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createInterface(
3484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
3494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
3504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
3524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \returns the traits of the component in this module.
3534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
3544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component::Traits> getTraits();
3554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
3574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates an uninitialized component module.
3584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
3594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param name[in]  component name.
3604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
3614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
3624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
3634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentModule()
3644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mInit(C2_NO_INIT),
3654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mLibHandle(nullptr),
3664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              createFactory(nullptr),
3674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              destroyFactory(nullptr),
3684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mComponentFactory(nullptr) {
3694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
3724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Initializes a component module with a given library path. Must be called exactly once.
3734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
3744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
3754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
3764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param libPath[in] library path (or name)
3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
3784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
3794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
3804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
3834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
3844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
3854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t init(std::string libPath);
3864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual ~ComponentModule() override;
3884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    protected:
3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::recursive_mutex mLock; ///< lock protecting mTraits
3914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t mInit; ///< initialization result
3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        void *mLibHandle; ///< loaded library handle
3964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
3974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loadable component module.
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo make this also work for enumerations
4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentLoader {
4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Load the component module.
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * This method simply returns the component module if it is already currently loaded, or
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * attempts to load it if it is not.
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *                    This will be nullptr on error.
4154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
4194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded
4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            c2_status_t res = C2_OK;
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::lock_guard<std::mutex> lock(mMutex);
4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<ComponentModule> localModule = mModule.lock();
4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (localModule == nullptr) {
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                localModule = std::make_shared<ComponentModule>();
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                res = localModule->init(mLibPath);
4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (res == C2_OK) {
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mModule = localModule;
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *module = localModule;
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return res;
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates a component loader for a specific library path (or name).
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader(std::string libPath)
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mLibPath(libPath) {}
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mMutex; ///< mutex guarding the module
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::string mLibPath; ///< library path (or name)
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Retrieves the component loader for a component.
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \return a non-ref-holding pointer to the component loader.
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_OK        the component loader has been successfully retrieved
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NO_MEMORY not enough memory to locate the component loader
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NOT_FOUND could not locate the component to be loaded
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      corrupted (this can happen if the name does not refer to an already
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      identified component but some components could not be loaded due to
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      bad library)
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_REFUSED   permission denied to find the component loader for the named component
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      (this can happen if the name does not refer to an already identified
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      component but some components could not be loaded due to lack of
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      permissions)
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t findComponent(C2String name, ComponentLoader **loader);
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::map<C2String, ComponentLoader> mComponents; ///< list of components
4699fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mReflector;
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) {
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("loading dll");
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle == nullptr) {
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // could be access/symbol or simply not being there
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror());
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mInit = C2_CORRUPTED;
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        createFactory =
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory =
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mComponentFactory = createFactory();
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mComponentFactory == nullptr) {
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("could not create factory in %s", libPath.c_str());
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_NO_MEMORY;
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_OK;
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mInit;
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformComponentStore::ComponentModule::~ComponentModule() {
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (destroyFactory && mComponentFactory) {
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory(mComponentFactory);
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle) {
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("unloading dll");
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        dlclose(mLibHandle);
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2ComponentInterface*)> deleter) {
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createInterface(
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting interface
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete interface first
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2Component> *component,
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2Component*)> deleter) {
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createComponent(
5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, component, [module, deleter](C2Component *p) mutable {
5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting component
5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete component first
5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_lock<std::recursive_mutex> lock(mLock);
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mTraits) {
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2ComponentInterface> intf;
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = createInterface(0, &intf);
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res != C2_OK) {
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("failed to create interface: %d", res);
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return nullptr;
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (traits) {
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->name = intf->getName();
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this from interface properly.
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            bool encoder = (traits->name.find("encoder") != std::string::npos);
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t mediaTypeIndex = encoder ? C2PortMimeConfig::output::PARAM_TYPE
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    : C2PortMimeConfig::input::PARAM_TYPE;
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> params;
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (res != C2_OK) {
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: %d", res);
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (params.size() != 1u) {
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2PortMimeConfig *mediaTypeConfig = (C2PortMimeConfig *)(params[0].get());
5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mediaTypeConfig == nullptr) {
5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query media type");
5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
5734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->mediaType = mediaTypeConfig->m.value;
5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this properly.
5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->rank = 0x200;
5774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mTraits = traits;
5804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mTraits;
5824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5849fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik KimC2PlatformComponentStore::C2PlatformComponentStore()
5859fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    : mReflector(std::make_shared<C2ReflectorHelper>()) {
5864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: move this also into a .so so it can be updated
5874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.avc.decoder", "libstagefright_soft_c2avcdec.so");
5884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.avc.encoder", "libstagefright_soft_c2avcenc.so");
5894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.aac.decoder", "libstagefright_soft_c2aacdec.so");
5904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.aac.encoder", "libstagefright_soft_c2aacenc.so");
5914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.amrnb.decoder", "libstagefright_soft_c2amrnbdec.so");
5924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.amrnb.encoder", "libstagefright_soft_c2amrnbenc.so");
5934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.amrwb.decoder", "libstagefright_soft_c2amrwbdec.so");
5944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.amrwb.encoder", "libstagefright_soft_c2amrwbenc.so");
5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.hevc.decoder", "libstagefright_soft_c2hevcdec.so");
5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.g711.alaw.decoder", "libstagefright_soft_c2g711alawdec.so");
5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.g711.mlaw.decoder", "libstagefright_soft_c2g711mlawdec.so");
5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.mpeg2.decoder", "libstagefright_soft_c2mpeg2dec.so");
5994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.h263.decoder", "libstagefright_soft_c2h263dec.so");
6004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.h263.encoder", "libstagefright_soft_c2h263enc.so");
6014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.mpeg4.decoder", "libstagefright_soft_c2mpeg4dec.so");
6024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.mpeg4.encoder", "libstagefright_soft_c2mpeg4enc.so");
6034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.mp3.decoder", "libstagefright_soft_c2mp3dec.so");
6044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.vorbis.decoder", "libstagefright_soft_c2vorbisdec.so");
6054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.opus.decoder", "libstagefright_soft_c2opusdec.so");
6064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.vp8.decoder", "libstagefright_soft_c2vp8dec.so");
6074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.vp9.decoder", "libstagefright_soft_c2vp9dec.so");
6084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.vp8.encoder", "libstagefright_soft_c2vp8enc.so");
6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.vp9.encoder", "libstagefright_soft_c2vp9enc.so");
6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.raw.decoder", "libstagefright_soft_c2rawdec.so");
6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.flac.decoder", "libstagefright_soft_c2flacdec.so");
6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.flac.encoder", "libstagefright_soft_c2flacenc.so");
6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mComponents.emplace("c2.google.gsm.decoder", "libstagefright_soft_c2gsmdec.so");
6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::copyBuffer(
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)src;
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)dst;
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OMITTED;
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::query_sm(
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &stackParams,
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param::Index> &heapParamIndices,
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // there are no supported configs
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)heapParams;
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX;
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::config_sm(
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &params,
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // there are no supported configs
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)failures;
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return params.empty() ? C2_OK : C2_BAD_INDEX;
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 500ms.
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<const C2Component::Traits>> list;
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (auto &it : mComponents) {
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader &loader = it.second;
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = loader.fetchModule(&module);
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (traits) {
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                list.push_back(traits);
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return list;
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) {
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = nullptr;
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto pos = mComponents.find(name);
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: check aliases
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (pos == mComponents.end()) {
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = &pos->second;
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createComponent(
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2Component> *const component) {
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createComponent(0, component);
6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createInterface(
6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createInterface(0, interface);
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
7004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedParams_nb(
7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // there are no supported config params
7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)params;
7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
7074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedValues_sm(
7104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2FieldSupportedValuesQuery> &fields) const {
7114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // there are no supported config params
7124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return fields.empty() ? C2_OK : C2_BAD_INDEX;
7134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2String C2PlatformComponentStore::getName() const {
7164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return "android.componentStore.platform";
7174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
7209fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    return mReflector;
7214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
7244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
7254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2ComponentStore> platformStore;
7264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
7274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
7284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (store == nullptr) {
7294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        store = std::make_shared<C2PlatformComponentStore>();
7304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        platformStore = store;
7314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return store;
7334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
736