1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef AV_CODEC_ENGIN_BASE_FACTORY_H
17 #define AV_CODEC_ENGIN_BASE_FACTORY_H
18 
19 #include <functional>
20 #include <unordered_map>
21 
22 namespace OHOS {
23 namespace MediaAVCodec {
24 template <typename I, typename Identity, typename... Args>
25 class AVCodecBaseFactory {
26 public:
27     using self = AVCodecBaseFactory<I, Identity, Args...>;
28 
29     template <typename... TS>
make_sharePtr(const Identity & k,TS &&...args)30     static std::shared_ptr<I> make_sharePtr(const Identity &k, TS &&...args)
31     {
32         auto it = builders().find(k);
33         if (it == builders().end())
34             return nullptr;
35         return it->second(std::forward<TS>(args)...);
36     }
37 
38     template <typename T>
39     struct CodecRegister : public I {
40         friend T;
avRegisterCodecRegister41         static bool avRegister()
42         {
43             const auto r = T::Identify();
44             AVCodecBaseFactory::builders()[r] = [](Args &&...args) -> std::shared_ptr<I> {
45                 return std::make_shared<T>(std::forward<Args>(args)...);
46             };
47             return true;
48         }
49         static bool registered;
50 
51     private:
CodecRegisterCodecRegister52         CodecRegister() : I()
53         {
54             (void)registered;
55         }
56     };
57 
58 private:
59     friend I;
60     AVCodecBaseFactory() = default;
61     using builder = std::function<std::shared_ptr<I>(Args...)>;
62 
builders()63     static auto &builders()
64     {
65         static std::unordered_map<Identity, builder> box;
66         return box;
67     }
68 };
69 
70 template <typename I, typename Identify, typename... Args>
71 template <typename T>
72 bool AVCodecBaseFactory<I, Identify, Args...>::CodecRegister<T>::registered =
73     AVCodecBaseFactory<I, Identify, Args...>::CodecRegister<T>::avRegister();
74 } // namespace MediaAVCodec
75 } // namespace OHOS
76 
77 #endif