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