C2Store.cpp revision 644ade33117e336116ec97fca4c12d8245c12676
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>
31493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar#include <unistd.h> // getpagesize
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <map>
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <memory>
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <mutex>
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
40493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar * Returns the preferred component store in this process to access its interface.
41493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar */
42493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore();
43493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
44493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar/**
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * The platform allocator store provides basic allocator-types for the framework based on ion and
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * gralloc. Allocators are not meant to be updatable.
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Provide allocator based on ashmem
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Make this allocator store extendable
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
54493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2PlatformAllocatorStoreImpl();
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t fetchAllocator(
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const override {
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override {
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return "android.allocator-store";
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
68493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    void setComponentStore(std::shared_ptr<C2ComponentStore> store);
69493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
70493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    ~C2PlatformAllocatorStoreImpl() override = default;
71493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton ion allocator
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchIonAllocator();
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton gralloc allocator
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
78493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
7938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    /// returns a shared-singleton bufferqueue supporting gralloc allocator
8038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
8138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
82493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    /// component store to use
83493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
84493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                                        // dependencies
85493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreReadLock; // must protect only read/write of _mComponentStore
86493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> _mComponentStore;
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    allocator->reset();
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: should we implement a generic registry for all, and use that?
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::ION:
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_LINEAR:
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchIonAllocator();
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::GRALLOC:
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_GRAPHIC:
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchGrallocAllocator();
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    case C2PlatformAllocatorStore::BUFFERQUEUE:
10838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        *allocator = fetchBufferQueueAllocator();
10938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        break;
11038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (*allocator == nullptr) {
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NO_MEMORY;
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
120493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
121493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
122493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::mutex gIonAllocatorMutex;
123493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::weak_ptr<C2AllocatorIon> gIonAllocator;
124493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
125493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid UseComponentStoreForIonAllocator(
126493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        const std::shared_ptr<C2AllocatorIon> allocator,
127493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> store) {
128493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2AllocatorIon::UsageMapperFn mapper;
129493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t minUsage = 0;
130493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t maxUsage = C2MemoryUsage(C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE).expected;
131493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    size_t blockSize = getpagesize();
132493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
133493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // query min and max usage as well as block size via supported values
134493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2StoreIonUsageInfo usageInfo;
135493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::vector<C2FieldSupportedValuesQuery> query = {
136493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.usage)),
137493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.capacity)),
138493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
139493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    c2_status_t res = store->querySupportedValues_sm(query);
140493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (res == C2_OK) {
141493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[0].status == C2_OK) {
142493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[0].values;
143493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::FLAGS && !fsv.values.empty()) {
144493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                minUsage = fsv.values[0].u64;
145493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                maxUsage = 0;
146493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                for (C2Value::Primitive v : fsv.values) {
147493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    maxUsage |= v.u64;
148493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
149493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
150493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
151493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[1].status == C2_OK) {
152493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[1].values;
153493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::RANGE && fsv.range.step.u32 > 0) {
154493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                blockSize = fsv.range.step.u32;
155493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
156493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
157493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
158493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        mapper = [store](C2MemoryUsage usage, size_t capacity,
159493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                         size_t *align, unsigned *heapMask, unsigned *flags) -> c2_status_t {
160493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (capacity > UINT32_MAX) {
161493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                return C2_BAD_VALUE;
162493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
163493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            C2StoreIonUsageInfo usageInfo = { usage.expected, capacity };
164493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::vector<std::unique_ptr<C2SettingResult>> failures; // TODO: remove
165493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            c2_status_t res = store->config_sm({&usageInfo}, &failures);
166493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (res == C2_OK) {
167493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *align = usageInfo.minAlignment;
168493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *heapMask = usageInfo.heapMask;
169493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *flags = usageInfo.allocFlags;
170493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
171493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            return res;
172493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        };
173493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
174493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
175493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    allocator->setUsageMapper(mapper, minUsage, maxUsage, blockSize);
176493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
177493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
178493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
179493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
180493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid C2PlatformAllocatorStoreImpl::setComponentStore(std::shared_ptr<C2ComponentStore> store) {
181493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // technically this set lock is not needed, but is here for safety in case we add more
182493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // getter orders
183493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(_mComponentStoreSetLock);
184493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
185493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
186493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        _mComponentStore = store;
187493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
188493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator;
189493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
190493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
191493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocator = gIonAllocator.lock();
192493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
193493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocator) {
194493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, store);
195493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
196493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
197493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
199493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
200493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator = gIonAllocator.lock();
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
202493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> componentStore;
203493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        {
204493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
205493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            componentStore = _mComponentStore;
206493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
208493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, componentStore);
209493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gIonAllocator = allocator;
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2Allocator> grallocAllocator;
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        grallocAllocator = allocator;
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
22638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Leestd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchBufferQueueAllocator() {
22738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::mutex mutex;
22838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::weak_ptr<C2Allocator> grallocAllocator;
22938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::lock_guard<std::mutex> lock(mutex);
23038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
23138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    if (allocator == nullptr) {
23238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        allocator = std::make_shared<C2AllocatorGralloc>(
23338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, true);
23438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        grallocAllocator = allocator;
23538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    }
23638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    return allocator;
23738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee}
23838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
239493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
240493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPreferredComponentStoreMutex;
241493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
242493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
243493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPlatformAllocatorStoreMutex;
244493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::weak_ptr<C2PlatformAllocatorStoreImpl> gPlatformAllocatorStore;
245493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
246493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
248493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
249493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> store = gPlatformAllocatorStore.lock();
250493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (store == nullptr) {
251493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store = std::make_shared<C2PlatformAllocatorStoreImpl>();
252493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store->setComponentStore(GetPreferredCodec2ComponentStore());
253493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPlatformAllocatorStore = store;
254493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
255493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return store;
256493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
257493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
258493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> componentStore) {
259493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    static std::mutex mutex;
260493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(mutex); // don't interleve set-s
261493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
262493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update preferred store
263493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
264493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
265493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPreferredComponentStore = componentStore;
266493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
267493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
268493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update platform allocator's store as well if it is alive
269493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> allocatorStore;
270493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
271493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
272493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore = gPlatformAllocatorStore.lock();
273493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
274493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocatorStore) {
275493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore->setComponentStore(componentStore);
276493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
277493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
278493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
279493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore() {
280493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
281493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return gPreferredComponentStore ? gPreferredComponentStore : GetCodec2PlatformComponentStore();
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
28439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leenamespace {
28539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
28639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeclass _C2BlockPoolCache {
28739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leepublic:
28839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
28939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
29039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t _createBlockPool(
2918060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
2928060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
2938060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t poolId,
29439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
29539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2AllocatorStore> allocatorStore =
29639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                GetCodec2PlatformAllocatorStore();
29739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2Allocator> allocator;
29839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        c2_status_t res = C2_NOT_FOUND;
29939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
30039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        switch(allocatorId) {
30139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            case C2PlatformAllocatorStore::ION:
3024a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2AllocatorStore::DEFAULT_LINEAR:
30339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
30439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
30539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
306878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
30739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2PooledBlockPool>(
30839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
30939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
310878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3118060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
31239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
31339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
3144a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2PlatformAllocatorStore::GRALLOC:
3154a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2AllocatorStore::DEFAULT_GRAPHIC:
3164a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                res = allocatorStore->fetchAllocator(
3174a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
3184a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                if (res == C2_OK) {
3194a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    std::shared_ptr<C2BlockPool> ptr =
3204a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        std::make_shared<C2PooledBlockPool>(allocator, poolId);
3214a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    *pool = ptr;
3224a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    mBlockPools[poolId] = ptr;
3234a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    mComponents[poolId] = component;
3244a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                }
3254a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                break;
32638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            case C2PlatformAllocatorStore::BUFFERQUEUE:
32739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
32838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                        C2PlatformAllocatorStore::BUFFERQUEUE, &allocator);
32939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
330878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
33139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2BufferQueueBlockPool>(
33239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
33339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
334878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3358060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
33639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
33739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
33839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            default:
33939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
34039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
34139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return res;
34239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
34339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
34439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t createBlockPool(
3458060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
3468060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3478060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
3488060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        return _createBlockPool(allocatorId, component, mBlockPoolSeqId++, pool);
34939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
35039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3518060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    bool getBlockPool(
3528060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t blockPoolId,
3538060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3548060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
35589eabf0d6b92d93eced043ce4abd2ac527c0374aPawin Vongmasa        // TODO: use one iterator for multiple blockpool type scalability.
3568060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        std::shared_ptr<C2BlockPool> ptr;
357878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        auto it = mBlockPools.find(blockPoolId);
358878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (it != mBlockPools.end()) {
359878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            ptr = it->second.lock();
3608060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!ptr) {
361878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                mBlockPools.erase(it);
3628060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
3638060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
3648060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
3658060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
3668060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    *pool = ptr;
3678060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
3688060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
36939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
37039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
37139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return false;
37239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
37339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
37439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeprivate:
37539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    C2BlockPool::local_id_t mBlockPoolSeqId;
3768060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee
377878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
3788060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<const C2Component>> mComponents;
37939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee};
38039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
38139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
38239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::make_unique<_C2BlockPoolCache>();
38339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::mutex sBlockPoolCacheMutex;
38439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
38539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee} // anynymous namespace
38639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t GetCodec2BlockPool(
3884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
39139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator;
3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = C2_NOT_FOUND;
3954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
39639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    if (id >= C2BlockPool::PLATFORM_START) {
3978060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        if (sBlockPoolCache->getBlockPool(id, component, pool)) {
39839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            return C2_OK;
39939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
40039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
40139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_LINEAR:
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
4064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_GRAPHIC:
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
41539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    // TODO: remove this. this is temporary
41639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    case C2BlockPool::PLATFORM_START:
4178060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        res = sBlockPoolCache->_createBlockPool(
41838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, component, id, pool);
41939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        break;
4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t CreateCodec2BlockPool(
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlatformAllocatorStore::id_t allocatorId,
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component> component,
4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
43239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
4338060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    return sBlockPoolCache->createBlockPool(allocatorId, component, pool);
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformComponentStore : public C2ComponentStore {
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override;
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedValues_sm(
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedParams_nb(
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t query_sm(
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &stackParams,
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param::Index> &heapParamIndices,
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createInterface(
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createComponent(
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2Component> *const component) override;
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t copyBuffer(
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t config_sm(
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &params,
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2PlatformComponentStore();
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual ~C2PlatformComponentStore() override = default;
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loaded component module.
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo provide a way to add traits to known components here to avoid loading the .so-s
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for listComponents
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentModule : public C2ComponentFactory,
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            public std::enable_shared_from_this<ComponentModule> {
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createComponent(
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2Component> *component,
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createInterface(
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \returns the traits of the component in this module.
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component::Traits> getTraits();
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates an uninitialized component module.
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param name[in]  component name.
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentModule()
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mInit(C2_NO_INIT),
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mLibHandle(nullptr),
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              createFactory(nullptr),
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              destroyFactory(nullptr),
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mComponentFactory(nullptr) {
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Initializes a component module with a given library path. Must be called exactly once.
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param libPath[in] library path (or name)
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t init(std::string libPath);
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual ~ComponentModule() override;
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    protected:
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::recursive_mutex mLock; ///< lock protecting mTraits
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t mInit; ///< initialization result
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        void *mLibHandle; ///< loaded library handle
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loadable component module.
5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo make this also work for enumerations
5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentLoader {
5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Load the component module.
5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * This method simply returns the component module if it is already currently loaded, or
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * attempts to load it if it is not.
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *                    This will be nullptr on error.
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            c2_status_t res = C2_OK;
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::lock_guard<std::mutex> lock(mMutex);
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<ComponentModule> localModule = mModule.lock();
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (localModule == nullptr) {
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                localModule = std::make_shared<ComponentModule>();
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                res = localModule->init(mLibPath);
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (res == C2_OK) {
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mModule = localModule;
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *module = localModule;
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return res;
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates a component loader for a specific library path (or name).
5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader(std::string libPath)
5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mLibPath(libPath) {}
5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mMutex; ///< mutex guarding the module
5734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::string mLibPath; ///< library path (or name)
5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
577493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    struct Interface : public C2InterfaceHelper {
578493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
579493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
580493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        Interface(std::shared_ptr<C2ReflectorHelper> reflector)
581493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            : C2InterfaceHelper(reflector) {
582493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            setDerivedInstance(this);
583493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
584493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            struct Setter {
585493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                static C2R setIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
586493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().heapMask = ~0;
587493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().allocFlags = 0;
588493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().minAlignment = 0;
589493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    return C2R::Ok();
590493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
591493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            };
592493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
593493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            addParameter(
594493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                DefineParam(mIonUsageInfo, "ion-usage")
595493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withDefault(new C2StoreIonUsageInfo())
596493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withFields({
597493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, usage).flags({C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
598493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
599493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, heapMask).any(),
600493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, allocFlags).flags({}),
601493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, minAlignment).equalTo(0)
602493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                })
603493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withSetter(Setter::setIonUsage)
604493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .build());
605493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
606493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
607493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
6084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Retrieves the component loader for a component.
6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \return a non-ref-holding pointer to the component loader.
6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_OK        the component loader has been successfully retrieved
6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NO_MEMORY not enough memory to locate the component loader
6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NOT_FOUND could not locate the component to be loaded
6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      corrupted (this can happen if the name does not refer to an already
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      identified component but some components could not be loaded due to
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      bad library)
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_REFUSED   permission denied to find the component loader for the named component
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      (this can happen if the name does not refer to an already identified
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      component but some components could not be loaded due to lack of
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      permissions)
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t findComponent(C2String name, ComponentLoader **loader);
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::map<C2String, ComponentLoader> mComponents; ///< list of components
6289fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mReflector;
629493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    Interface mInterface;
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) {
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("loading dll");
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle == nullptr) {
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // could be access/symbol or simply not being there
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror());
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mInit = C2_CORRUPTED;
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        createFactory =
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory =
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mComponentFactory = createFactory();
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mComponentFactory == nullptr) {
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("could not create factory in %s", libPath.c_str());
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_NO_MEMORY;
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_OK;
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mInit;
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformComponentStore::ComponentModule::~ComponentModule() {
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (destroyFactory && mComponentFactory) {
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory(mComponentFactory);
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle) {
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("unloading dll");
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        dlclose(mLibHandle);
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2ComponentInterface*)> deleter) {
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createInterface(
6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting interface
6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete interface first
6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2Component> *component,
6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2Component*)> deleter) {
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createComponent(
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, component, [module, deleter](C2Component *p) mutable {
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting component
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete component first
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
6994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
7004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_lock<std::recursive_mutex> lock(mLock);
7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mTraits) {
7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2ComponentInterface> intf;
7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = createInterface(0, &intf);
7074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res != C2_OK) {
7084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("failed to create interface: %d", res);
7094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return nullptr;
7104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
7114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
7134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (traits) {
7144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->name = intf->getName();
7154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this from interface properly.
7164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            bool encoder = (traits->name.find("encoder") != std::string::npos);
7174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t mediaTypeIndex = encoder ? C2PortMimeConfig::output::PARAM_TYPE
7184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    : C2PortMimeConfig::input::PARAM_TYPE;
7194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> params;
7204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
7214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (res != C2_OK) {
7224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: %d", res);
7234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (params.size() != 1u) {
7264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
7274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2PortMimeConfig *mediaTypeConfig = (C2PortMimeConfig *)(params[0].get());
7304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mediaTypeConfig == nullptr) {
7314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query media type");
7324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->mediaType = mediaTypeConfig->m.value;
7354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this properly.
7364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->rank = 0x200;
737a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa
738a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            // TODO: define these values properly
739a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            bool decoder = (traits->name.find("decoder") != std::string::npos);
740a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            traits->kind =
741a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    decoder ? C2Component::KIND_DECODER :
742a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    encoder ? C2Component::KIND_ENCODER :
743a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    C2Component::KIND_OTHER;
744a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
745a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_AUDIO;
746a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
747a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_VIDEO;
748a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
749a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_IMAGE;
750a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else {
751a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_OTHER;
752a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            }
7534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
7544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mTraits = traits;
7564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mTraits;
7584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7609fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik KimC2PlatformComponentStore::C2PlatformComponentStore()
761493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    : mReflector(std::make_shared<C2ReflectorHelper>()),
762493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar      mInterface(mReflector) {
7634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: move this also into a .so so it can be updated
7645c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.decoder", "libstagefright_soft_c2avcdec.so");
7655c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.encoder", "libstagefright_soft_c2avcenc.so");
7665c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.decoder", "libstagefright_soft_c2aacdec.so");
7675c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.encoder", "libstagefright_soft_c2aacenc.so");
7685c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.decoder", "libstagefright_soft_c2amrnbdec.so");
7695c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.encoder", "libstagefright_soft_c2amrnbenc.so");
7705c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.decoder", "libstagefright_soft_c2amrwbdec.so");
7715c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.encoder", "libstagefright_soft_c2amrwbenc.so");
7725c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.hevc.decoder", "libstagefright_soft_c2hevcdec.so");
7735c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.alaw.decoder", "libstagefright_soft_c2g711alawdec.so");
7745c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.mlaw.decoder", "libstagefright_soft_c2g711mlawdec.so");
7755c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg2.decoder", "libstagefright_soft_c2mpeg2dec.so");
7765c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.decoder", "libstagefright_soft_c2h263dec.so");
7775c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.encoder", "libstagefright_soft_c2h263enc.so");
7785c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.decoder", "libstagefright_soft_c2mpeg4dec.so");
7795c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.encoder", "libstagefright_soft_c2mpeg4enc.so");
7805c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mp3.decoder", "libstagefright_soft_c2mp3dec.so");
7815c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vorbis.decoder", "libstagefright_soft_c2vorbisdec.so");
7825c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.opus.decoder", "libstagefright_soft_c2opusdec.so");
7835c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.decoder", "libstagefright_soft_c2vp8dec.so");
7845c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.decoder", "libstagefright_soft_c2vp9dec.so");
7855c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.encoder", "libstagefright_soft_c2vp8enc.so");
7865c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.encoder", "libstagefright_soft_c2vp9enc.so");
7875c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.raw.decoder", "libstagefright_soft_c2rawdec.so");
7885c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.decoder", "libstagefright_soft_c2flacdec.so");
7895c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.encoder", "libstagefright_soft_c2flacenc.so");
7905c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.gsm.decoder", "libstagefright_soft_c2gsmdec.so");
791644ade33117e336116ec97fca4c12d8245c12676Rakesh Kumar    mComponents.emplace("c2.android.xaac.decoder", "libstagefright_soft_c2xaacdec.so");
7924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::copyBuffer(
7954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
7964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)src;
7974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)dst;
7984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OMITTED;
7994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::query_sm(
8024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &stackParams,
8034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param::Index> &heapParamIndices,
8044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
805493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
8064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::config_sm(
8094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &params,
8104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
811493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.config(params, C2_MAY_BLOCK, failures);
8124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
8154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 500ms.
8164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<const C2Component::Traits>> list;
8174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (auto &it : mComponents) {
8184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader &loader = it.second;
8194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = loader.fetchModule(&module);
8214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
8234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (traits) {
8244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                list.push_back(traits);
8254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
8264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return list;
8294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) {
8324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = nullptr;
8334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto pos = mComponents.find(name);
8344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: check aliases
8354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (pos == mComponents.end()) {
8364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
8374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = &pos->second;
8394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
8404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createComponent(
8434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2Component> *const component) {
8444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
8464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createComponent(0, component);
8544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createInterface(
8604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
8614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
8634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createInterface(0, interface);
8714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedParams_nb(
8774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
878493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedParams(params);
8794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedValues_sm(
8824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2FieldSupportedValuesQuery> &fields) const {
883493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
8844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2String C2PlatformComponentStore::getName() const {
8874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return "android.componentStore.platform";
8884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
8919fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    return mReflector;
8924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
8954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
8964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2ComponentStore> platformStore;
8974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
8984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
8994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (store == nullptr) {
9004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        store = std::make_shared<C2PlatformComponentStore>();
9014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        platformStore = store;
9024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
9034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return store;
9044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
907