1 /*
2  * Copyright (c) 2023-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 #if defined(VIDEO_SUPPORT)
16 
17 #define HST_LOG_TAG "HdiCodecManager"
18 
19 #include "hdi_codec_manager.h"
20 #include "foundation/utils/constants.h"
21 #include "foundation/log.h"
22 #include "hdf_base.h"
23 #include "hdi_codec_adapter.h"
24 #include "plugin/common/plugin_caps_builder.h"
25 
26 namespace OHOS {
27 namespace Media {
28 namespace Plugin {
29 namespace CodecAdapter {
GetInstance()30 HdiCodecManager& HdiCodecManager::GetInstance()
31 {
32     static HdiCodecManager impl;
33     return impl;
34 }
35 
HdiCodecManager()36 HdiCodecManager::HdiCodecManager()
37 {
38     Init();
39 }
40 
~HdiCodecManager()41 HdiCodecManager::~HdiCodecManager()
42 {
43     Reset();
44 }
45 
CreateComponent(const Plugin::Any & component,uint32_t & id,const std::string & name,const Plugin::Any & appData,const Plugin::Any & callbacks)46 int32_t HdiCodecManager::CreateComponent(const Plugin::Any& component, uint32_t& id, const std::string& name,
47                                          const Plugin::Any& appData, const Plugin::Any& callbacks)
48 {
49     MEDIA_LOG_I("CreateComponent Start");
50     if (!mgr_) {
51         Init();
52         FALSE_RETURN_V_MSG(mgr_ != nullptr, HDF_FAILURE, "mgr is nullptr");
53     }
54     auto codecComponent = Plugin::AnyCast<CodecComponentType**>(component);
55     FALSE_RETURN_V_MSG(codecComponent != nullptr, HDF_FAILURE, "component is nullptr");
56     return mgr_->CreateComponent(codecComponent, &id, const_cast<char *>(name.c_str()),
57         Plugin::AnyCast<int64_t>(appData), Plugin::AnyCast<CodecCallbackType*>(callbacks));
58 }
59 
DestroyComponent(const Plugin::Any & component,uint32_t id)60 int32_t HdiCodecManager::DestroyComponent(const Plugin::Any& component, uint32_t id)
61 {
62     MEDIA_LOG_I("DestroyComponent Start");
63     FALSE_RETURN_V_MSG(mgr_ != nullptr, HDF_FAILURE, "mgr_ is nullptr");
64     (void)component;
65     return mgr_->DestroyComponent(id);
66 }
67 
RegisterCodecPlugins(const std::shared_ptr<OHOS::Media::Plugin::Register> & reg)68 Status HdiCodecManager::RegisterCodecPlugins(const std::shared_ptr<OHOS::Media::Plugin::Register>& reg)
69 {
70     MEDIA_LOG_I("RegisterCodecPlugins Start");
71     std::string packageName = "HdiCodecAdapter";
72     if (!mgr_) {
73         MEDIA_LOG_E("Codec package " PUBLIC_LOG_S " has no valid component manager", packageName.c_str());
74         return Status::ERROR_INVALID_DATA;
75     }
76     InitCaps();
77     for (auto codecCapability : codecCapabilitys_) {
78         if (codecCapability.pluginType != PluginType::VIDEO_DECODER &&
79             codecCapability.pluginType != PluginType::VIDEO_ENCODER) {
80             MEDIA_LOG_W("Plugin does not belong to video codec, pluginType: " PUBLIC_LOG_D32,
81                         codecCapability.pluginType);
82             continue;
83         }
84         CodecPluginDef def;
85         def.rank = 100; // 100 default rank
86         def.codecMode = CodecMode::HARDWARE;
87         def.pluginType = codecCapability.pluginType;
88         def.name = packageName + "." + codecCapability.name;
89         def.inCaps = codecCapability.inCaps;
90         def.outCaps = codecCapability.outCaps;
91         auto pluginMime = codecCapability.pluginMime;
92         def.creator = [pluginMime] (const std::string& name) -> std::shared_ptr<CodecPlugin> {
93             return std::make_shared<HdiCodecAdapter>(name, pluginMime);
94         };
95         if (reg->AddPlugin(def) != Status::OK) {
96             MEDIA_LOG_E("Add plugin " PUBLIC_LOG_S " failed", def.name.c_str());
97         }
98         MEDIA_LOG_DD("pluginType: " PUBLIC_LOG_D32 ", pluginName: " PUBLIC_LOG_S, def.pluginType, def.name.c_str());
99     }
100     return Status::OK;
101 }
102 
UnRegisterCodecPlugins()103 Status HdiCodecManager::UnRegisterCodecPlugins()
104 {
105     MEDIA_LOG_I("UnRegisterCodecPlugins Start");
106     return Status::OK;
107 }
108 
Init()109 void HdiCodecManager::Init()
110 {
111     MEDIA_LOG_I("Init Start");
112     mgr_ = GetCodecComponentManager();
113 }
114 
Reset()115 void HdiCodecManager::Reset()
116 {
117     MEDIA_LOG_I("Reset Start");
118     CodecComponentManagerRelease();
119     mgr_ = nullptr;
120 }
121 
AddHdiCap(const CodecCompCapability & hdiCap)122 void HdiCodecManager::AddHdiCap(const CodecCompCapability& hdiCap)
123 {
124     MEDIA_LOG_DD("AddHdiCap Start");
125     auto pluginType = GetCodecType(hdiCap.type);
126     if (pluginType == PluginType::VIDEO_DECODER || pluginType == PluginType::VIDEO_ENCODER) {
127         CodecCapability codecCapability;
128         CapabilityBuilder incapBuilder;
129         CapabilityBuilder outcapBuilder;
130         auto mime = GetCodecMime(hdiCap.role);
131         if (mime == "video/unknown") {
132             return;
133         }
134         if (pluginType == PluginType::VIDEO_DECODER) {
135             incapBuilder.SetMime(mime);
136             if (mime == MEDIA_MIME_VIDEO_H264 || mime == MEDIA_MIME_VIDEO_H265) {
137                 incapBuilder.SetVideoBitStreamFormatList({VideoBitStreamFormat::ANNEXB});
138             }
139             outcapBuilder.SetMime(MEDIA_MIME_VIDEO_RAW);
140             outcapBuilder.SetVideoPixelFormatList(GetCodecFormats(hdiCap.port.video));
141         } else {
142             incapBuilder.SetMime(MEDIA_MIME_VIDEO_RAW);
143             incapBuilder.SetVideoPixelFormatList(GetCodecFormats(hdiCap.port.video));
144             outcapBuilder.SetMime(mime);
145         }
146         codecCapability.inCaps.push_back(incapBuilder.Build());
147         codecCapability.outCaps.push_back(outcapBuilder.Build());
148         codecCapability.pluginType = pluginType;
149         codecCapability.pluginMime = mime;
150         codecCapability.name = hdiCap.compName;
151         codecCapabilitys_.push_back(codecCapability);
152     }
153 }
154 
InitCaps()155 void HdiCodecManager::InitCaps()
156 {
157     MEDIA_LOG_I("InitCaps Start");
158     auto len = mgr_->GetComponentNum();
159     CodecCompCapability hdiCaps[len];
160     auto ret = mgr_->GetComponentCapabilityList(hdiCaps, len);
161     FALSE_RETURN_MSG(ret == HDF_SUCCESS, "GetComponentCapabilityList fail");
162     for (auto i = 0; i < len; ++i) {
163         AddHdiCap(hdiCaps[i]);
164     }
165 }
166 
GetCodecFormats(const CodecVideoPortCap & port)167 std::vector<VideoPixelFormat> HdiCodecManager::GetCodecFormats(const CodecVideoPortCap& port)
168 {
169     int32_t index = 0;
170     std::vector<VideoPixelFormat> formats;
171     while (index < PIX_FORMAT_NUM && port.supportPixFmts[index] > 0) {
172         switch (port.supportPixFmts[index]) {
173             case GRAPHIC_PIXEL_FMT_YCBCR_420_SP:
174                 formats.push_back(VideoPixelFormat::NV12);
175                 break;
176             case GRAPHIC_PIXEL_FMT_YCRCB_420_SP:
177                 formats.push_back(VideoPixelFormat::NV21);
178                 break;
179             case GRAPHIC_PIXEL_FMT_YCBCR_420_P:
180                 formats.push_back(VideoPixelFormat::YUV420P);
181                 break;
182             case GRAPHIC_PIXEL_FMT_RGBA_8888:
183                 formats.push_back(VideoPixelFormat::RGBA);
184                 break;
185             case GRAPHIC_PIXEL_FMT_BGRA_8888:
186                 formats.push_back(VideoPixelFormat::BGRA);
187                 break;
188             default:
189                 MEDIA_LOG_W("Unknown Format" PUBLIC_LOG_D32, port.supportPixFmts[index]);
190         }
191         index++;
192     }
193     return formats;
194 }
195 
GetCodecType(const CodecType & hdiType)196 PluginType HdiCodecManager::GetCodecType(const CodecType& hdiType)
197 {
198     switch (hdiType) {
199         case VIDEO_DECODER:
200             return PluginType::VIDEO_DECODER;
201         case VIDEO_ENCODER:
202             return PluginType::VIDEO_ENCODER;
203         case AUDIO_DECODER:
204             return PluginType::AUDIO_DECODER;
205         case AUDIO_ENCODER:
206             return PluginType::AUDIO_ENCODER;
207         default:
208             return PluginType::INVALID_TYPE;
209     }
210 }
211 
GetCodecMime(const AvCodecRole & role)212 std::string HdiCodecManager::GetCodecMime(const AvCodecRole& role)
213 {
214     switch (role) {
215         case MEDIA_ROLETYPE_VIDEO_AVC:
216             return MEDIA_MIME_VIDEO_H264;
217         case MEDIA_ROLETYPE_VIDEO_HEVC:
218             return MEDIA_MIME_VIDEO_H265;
219         default:
220             return "video/unknown";
221     }
222 }
223 } // namespace CodecAdapter
224 } // namespace Plugin
225 } // namespace Media
226 } // namespace OHOS
227 #endif