• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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 #include "codec_component_config.h"
16 #include <cinttypes>
17 #include <osal_mem.h>
18 #include "codec_log_wrapper.h"
19 #include "codec_hcb_util.h"
20 
21 #define CODEC_CONFIG_NAME "media_codec_capabilities"
22 
23 namespace {
24     constexpr int32_t MASK_NUM_LIMIT = 32;
25     constexpr char NODE_VIDEO_HARDWARE_ENCODERS[] = "VideoHwEncoders";
26     constexpr char NODE_VIDEO_HARDWARE_DECODERS[] = "VideoHwDecoders";
27     constexpr char NODE_VIDEO_SOFTWARE_ENCODERS[] = "VideoSwEncoders";
28     constexpr char NODE_VIDEO_SOFTWARE_DECODERS[] = "VideoSwDecoders";
29     constexpr char NODE_AUDIO_HARDWARE_ENCODERS[] = "AudioHwEncoders";
30     constexpr char NODE_AUDIO_HARDWARE_DECODERS[] = "AudioHwDecoders";
31     constexpr char NODE_AUDIO_SOFTWARE_ENCODERS[] = "AudioSwEncoders";
32     constexpr char NODE_AUDIO_SOFTWARE_DECODERS[] = "AudioSwDecoders";
33 
34     constexpr char CODEC_CONFIG_KEY_ROLE[] = "role";
35     constexpr char CODEC_CONFIG_KEY_TYPE[] = "type";
36     constexpr char CODEC_CONFIG_KEY_NAME[] = "name";
37     constexpr char CODEC_CONFIG_KEY_SUPPORT_PROFILES[] = "supportProfiles";
38     constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst";
39     constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec";
40     constexpr char CODEC_CONFIG_KEY_PROCESS_MODE_MASK[] = "processModeMask";
41     constexpr char CODEC_CONFIG_KEY_CAPS_MASK[] = "capsMask";
42     constexpr char CODEC_CONFIG_KEY_MIN_BITRATE[] = "minBitRate";
43     constexpr char CODEC_CONFIG_KEY_MAX_BITRATE[] = "maxBitRate";
44 
45     constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth";
46     constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight";
47     constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth";
48     constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight";
49     constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment";
50     constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment";
51     constexpr char CODEC_CONFIG_KEY_MIN_BLOCK_COUNT[] = "minBlockCount";
52     constexpr char CODEC_CONFIG_KEY_MAX_BLOCK_COUNT[] = "maxBlockCount";
53     constexpr char CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND[] = "minBlocksPerSecond";
54     constexpr char CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND[] = "maxBlocksPerSecond";
55     constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts";
56     constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH[] = "blockSizeWidth";
57     constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT[] = "blockSizeHeight";
58     constexpr char CODEC_CONFIG_KEY_MIN_FRAME_RATE[] = "minFrameRate";
59     constexpr char CODEC_CONFIG_KEY_MAX_FRAME_RATE[] = "maxFrameRate";
60     constexpr char CODEC_CONFIG_KEY_BITE_RATE_MODE[] = "bitRateMode";
61     constexpr char CODEC_CONFIG_KEY_MESURED_FRAME_RATE[] = "measuredFrameRate";
62     constexpr char CODEC_CONFIG_KEY_CAN_SWAP_WIDTH_HEIGHT[] = "canSwapWidthHeight";
63 
64     constexpr char CODEC_CONFIG_KEY_SAMPLE_FORMATS[] = "sampleFormats";
65     constexpr char CODEC_CONFIG_KEY_SAMPLE_RATE[] = "sampleRate";
66     constexpr char CODEC_CONFIG_KEY_CHANNEL_LAYOUTS[] = "channelLayouts";
67     constexpr char CODEC_CONFIG_KEY_CHANNEL_COUNT[] = "channelCount";
68 }
69 
70 using namespace OHOS::HDI::Codec::V1_0;
71 namespace OHOS {
72 namespace Codec {
73 namespace Omx {
74 CodecComponentConfig CodecComponentConfig::config_;
CodecComponentConfig()75 CodecComponentConfig::CodecComponentConfig()
76 {
77     node_.name = nullptr;
78     node_.hashValue = 0;
79     node_.attrData = nullptr;
80     node_.parent = nullptr;
81     node_.child = nullptr;
82     node_.sibling = nullptr;
83 }
84 
Init(const DeviceResourceNode & node)85 void CodecComponentConfig::Init(const DeviceResourceNode &node)
86 {
87     node_ = node;
88     std::string codecGroupsNodeName[] = {NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
89                                          NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
90                                          NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
91                                          NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS};
92     int count = sizeof(codecGroupsNodeName) / sizeof(std::string);
93     for (int index = 0; index < count; index++) {
94         if (GetGroupCapabilities(codecGroupsNodeName[index]) != HDF_SUCCESS) {
95             continue;
96         }
97     }
98     CODEC_LOGD("Init Run....capList_.size=%{public}zu", capList_.size());
99 }
100 
CodecCompCapabilityInit()101 int32_t CodecComponentConfig::CodecCompCapabilityInit()
102 {
103     const struct DeviceResourceNode *rootNode = HdfGetHcsRootNode();
104     if (rootNode == nullptr) {
105         CODEC_LOGE("GetRootNode failed");
106         return HDF_FAILURE;
107     }
108     const struct DeviceResourceNode *codecNode = HcsGetNodeByMatchAttr(rootNode, CODEC_CONFIG_NAME);
109     if (codecNode == nullptr) {
110         CODEC_LOGE("codecNode is nullptr");
111         return HDF_FAILURE;
112     }
113     OHOS::Codec::Omx::CodecComponentConfig::GetInstance()->Init(*codecNode);
114     return HDF_SUCCESS;
115 }
116 
GetInstance()117 CodecComponentConfig *CodecComponentConfig::GetInstance()
118 {
119     return &config_;
120 }
121 
GetComponentNum(int32_t & count)122 int32_t CodecComponentConfig::GetComponentNum(int32_t &count)
123 {
124     count = static_cast<int32_t>(capList_.size());
125     CODEC_LOGD("enter, count = %{public}d", count);
126     return HDF_SUCCESS;
127 }
128 
GetComponentCapabilityList(std::vector<CodecCompCapability> & capList,int32_t count)129 int32_t CodecComponentConfig::GetComponentCapabilityList(std::vector<CodecCompCapability> &capList, int32_t count)
130 {
131     CODEC_LOGD("count[%{public}d], size[%{public}zu]", count, capList_.size());
132     if (count > static_cast<int32_t>(capList_.size())) {
133         CODEC_LOGW("count[%{public}d] is too large", count);
134         count = static_cast<int32_t>(capList_.size());
135     }
136     auto first = capList_.begin();
137     auto last = capList_.begin() + count;
138     capList.assign(first, last);
139     return HDF_SUCCESS;
140 }
141 
GetGroupCapabilities(const std::string & nodeName)142 int32_t CodecComponentConfig::GetGroupCapabilities(const std::string &nodeName)
143 {
144     bool isVideoGroup = true;
145     const struct DeviceResourceNode *codecGroupNode = NULL;
146     struct DeviceResourceNode *childNode = NULL;
147     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
148     if (iface == NULL) {
149         CODEC_LOGE(" failed, iface NULL!");
150         return HDF_ERR_INVALID_PARAM;
151     }
152 
153     codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str());
154     if (codecGroupNode == NULL) {
155         CODEC_LOGE("failed to get child node: %{public}s!", nodeName.c_str());
156         return HDF_FAILURE;
157     }
158 
159     if (nodeName.find("Video") == std::string::npos) {
160         isVideoGroup = false;
161     }
162 
163     DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode)
164     {
165         CodecCompCapability cap;
166         if (GetOneCapability(*iface, *childNode, cap, isVideoGroup) != HDF_SUCCESS) {
167             CODEC_LOGE("GetOneCapability failed, role is %{public}d!", cap.role);
168         }
169         capList_.push_back(cap);
170     }
171 
172     return HDF_SUCCESS;
173 }
174 
GetOneCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap,bool isVideoGroup)175 int32_t CodecComponentConfig::GetOneCapability(const struct DeviceResourceIface &iface,
176                                                const struct DeviceResourceNode &childNode, CodecCompCapability &cap,
177                                                bool isVideoGroup)
178 {
179     if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, reinterpret_cast<uint32_t *>(&cap.role),
180                         MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) {
181         cap.role = MEDIA_ROLETYPE_INVALID;
182         CODEC_LOGE("failed to get mime for: %{public}s! Discarded", childNode.name);
183         return HDF_FAILURE;
184     }
185 
186     if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, reinterpret_cast<uint32_t *>(&cap.type), INVALID_TYPE) !=
187         HDF_SUCCESS) {
188         cap.role = MEDIA_ROLETYPE_INVALID;
189         cap.type = INVALID_TYPE;
190         CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name);
191         return HDF_FAILURE;
192     }
193 
194     const char *compName = NULL;
195     if (iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
196         cap.role = MEDIA_ROLETYPE_INVALID;
197         CODEC_LOGE("get attr %{public}s err!", CODEC_CONFIG_KEY_NAME);
198         return HDF_FAILURE;
199     }
200     if (compName == NULL || strlen(compName) == 0) {
201         cap.role = MEDIA_ROLETYPE_INVALID;
202         CODEC_LOGE("compName is null or empty!");
203         return HDF_FAILURE;
204     }
205     cap.compName = compName;
206 
207     cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
208     cap.canSwapWidthHeight = iface.GetBool(&childNode, CODEC_CONFIG_KEY_CAN_SWAP_WIDTH_HEIGHT);
209 
210     if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) {
211         cap.role = MEDIA_ROLETYPE_INVALID;
212         CODEC_LOGE("get misc cap  err!");
213         return HDF_FAILURE;
214     }
215 
216     if (isVideoGroup) {
217         if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
218             cap.role = MEDIA_ROLETYPE_INVALID;
219             CODEC_LOGE("get video port cap  err!");
220             return HDF_FAILURE;
221         }
222     } else {
223         if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
224             cap.role = MEDIA_ROLETYPE_INVALID;
225             CODEC_LOGE("get audio port cap  err!");
226             return HDF_FAILURE;
227         }
228     }
229 
230     return HDF_SUCCESS;
231 }
232 
GetMiscOfCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)233 int32_t CodecComponentConfig::GetMiscOfCapability(const struct DeviceResourceIface &iface,
234                                                   const struct DeviceResourceNode &childNode, CodecCompCapability &cap)
235 {
236     ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES, cap.supportProfiles};
237     if (GetUintTableConfig(iface, childNode, attr) != HDF_SUCCESS) {
238         CODEC_LOGE("get uint table config [%{public}s] err!", attr.attrName.c_str());
239         return HDF_FAILURE;
240     }
241 
242     if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_INST, reinterpret_cast<uint32_t *>(&cap.maxInst), 0) !=
243         HDF_SUCCESS) {
244         CODEC_LOGE("get uint32 config [%{public}s] err!", attr.attrName.c_str());
245         return HDF_FAILURE;
246     }
247     if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK,
248                         reinterpret_cast<uint32_t &>(cap.processModeMask)) != HDF_SUCCESS) {
249         CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
250         return HDF_FAILURE;
251     }
252     if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, static_cast<uint32_t &>(cap.capsMask)) !=
253         HDF_SUCCESS) {
254         CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
255         return HDF_FAILURE;
256     }
257     if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MIN_BITRATE, reinterpret_cast<uint32_t *>(&cap.bitRate.min), 0) !=
258         HDF_SUCCESS) {
259         CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
260         return HDF_FAILURE;
261     }
262     if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_BITRATE, reinterpret_cast<uint32_t *>(&cap.bitRate.max), 0) !=
263         HDF_SUCCESS) {
264         CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
265         return HDF_FAILURE;
266     }
267 
268     return HDF_SUCCESS;
269 }
270 
GetUintTableConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,ConfigUintArrayNodeAttr & attr)271 int32_t CodecComponentConfig::GetUintTableConfig(const struct DeviceResourceIface &iface,
272                                                  const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr)
273 {
274     if (attr.attrName.empty()) {
275         CODEC_LOGE("failed, invalid attr!");
276         return HDF_ERR_INVALID_PARAM;
277     }
278 
279     int32_t count = iface.GetElemNum(&node, attr.attrName.c_str());
280     if (count < 0) {
281         CODEC_LOGE("%{public}s table size: count[%{public}d] < 0!", attr.attrName.c_str(), count);
282         return HDF_FAILURE;
283     }
284     if (count > 0) {
285         std::unique_ptr<int32_t[]> array = std::make_unique<int32_t[]>(count);
286         iface.GetUint32Array(&node, attr.attrName.c_str(), reinterpret_cast<uint32_t *>(array.get()), count, 0);
287         attr.vec.assign(array.get(), array.get() + count);
288     }
289     return HDF_SUCCESS;
290 }
291 
GetMaskedConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,const std::string & attrName,uint32_t & mask)292 int32_t CodecComponentConfig::GetMaskedConfig(const struct DeviceResourceIface &iface,
293                                               const struct DeviceResourceNode &node, const std::string &attrName,
294                                               uint32_t &mask)
295 {
296     int32_t count = iface.GetElemNum(&node, attrName.c_str());
297 
298     mask = 0;
299     if (count < 0 || count > MASK_NUM_LIMIT) {
300         CODEC_LOGE("failed, count %{public}d incorrect!", count);
301         return HDF_FAILURE;
302     }
303 
304     if (count > 0) {
305         std::unique_ptr<uint32_t[]> values = std::make_unique<uint32_t[]>(count);
306         iface.GetUint32Array(&node, attrName.c_str(), values.get(), count, 0);
307         for (int32_t index = 0; index < count; index++) {
308             mask |= values[index];
309         }
310     }
311 
312     return HDF_SUCCESS;
313 }
314 
GetVideoPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)315 int32_t CodecComponentConfig::GetVideoPortCapability(const struct DeviceResourceIface &iface,
316                                                      const struct DeviceResourceNode &childNode,
317                                                      CodecCompCapability &cap)
318 {
319     ConfigUintNodeAttr nodeAttrs[] = {
320         {CODEC_CONFIG_KEY_MIN_WIDTH, cap.port.video.minSize.width, 0},
321         {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.port.video.minSize.height, 0},
322         {CODEC_CONFIG_KEY_MAX_WIDTH, cap.port.video.maxSize.width, 0},
323         {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.port.video.maxSize.height, 0},
324         {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.port.video.whAlignment.widthAlignment, 0},
325         {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.port.video.whAlignment.heightAlignment, 0},
326         {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, cap.port.video.blockCount.min, 0},
327         {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, cap.port.video.blockCount.max, 0},
328         {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.min, 0},
329         {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.max, 0},
330         {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, cap.port.video.blockSize.width, 0},
331         {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, cap.port.video.blockSize.height, 0},
332         {CODEC_CONFIG_KEY_MIN_FRAME_RATE, cap.port.video.frameRate.min, 0},
333         {CODEC_CONFIG_KEY_MAX_FRAME_RATE, cap.port.video.frameRate.max, 0}};
334 
335     int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
336     for (int32_t i = 0; i < count; i++) {
337         if (iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(),
338                             reinterpret_cast<uint32_t *>(&nodeAttrs[i].value),
339                             nodeAttrs[i].defaultValue) != HDF_SUCCESS) {
340             CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
341             return HDF_FAILURE;
342         }
343     }
344     ConfigUintArrayNodeAttr arrayAttrs[] = {
345         {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.port.video.supportPixFmts},
346         {CODEC_CONFIG_KEY_BITE_RATE_MODE, reinterpret_cast<std::vector<int32_t> &>(cap.port.video.bitRatemode)},
347         {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap.port.video.measuredFrameRate}};
348 
349     count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
350     for (int32_t i = 0; i < count; i++) {
351         if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
352             CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
353             return HDF_FAILURE;
354         }
355     }
356     return HDF_SUCCESS;
357 }
358 
GetAudioPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)359 int32_t CodecComponentConfig::GetAudioPortCapability(const struct DeviceResourceIface &iface,
360                                                      const struct DeviceResourceNode &childNode,
361                                                      CodecCompCapability &cap)
362 {
363     ConfigUintArrayNodeAttr arrayAttrs[] = {{CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap.port.audio.sampleFormats},
364                                             {CODEC_CONFIG_KEY_SAMPLE_RATE, cap.port.audio.sampleRate},
365                                             {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap.port.audio.channelLayouts},
366                                             {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap.port.audio.channelCount}};
367 
368     int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
369     for (int32_t i = 0; i < count; i++) {
370         if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
371             CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, arrayAttrs[i].attrName.c_str());
372             return HDF_FAILURE;
373         }
374     }
375 
376     return HDF_SUCCESS;
377 }
378 }  // namespace Omx
379 }  // namespace Codec
380 }  // namespace OHOS