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