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 16#include "codec_config_parser.h" 17#include <osal_mem.h> 18#include <securec.h> 19#include <OMX_IVCommon.h> 20#include "codec_log_wrapper.h" 21 22#ifdef __ARCH64__ 23#define MASK_NUM_LIMIT 64 24#else 25#define MASK_NUM_LIMIT 32 26#endif 27 28static int32_t GetGroupCapabilitiesNumber(const struct DeviceResourceNode *node, 29 const char *nodeName, int32_t *num) 30{ 31 if (node == NULL || nodeName == NULL || num == NULL) { 32 CODEC_LOGE("failed for codec %{public}s, invalid param!", nodeName); 33 return HDF_ERR_INVALID_PARAM; 34 } 35 36 int32_t result = 0; 37 *num = result; 38 const struct DeviceResourceNode *codecGroupNode = NULL; 39 struct DeviceResourceNode *childNode = NULL; 40 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 41 if (iface == NULL) { 42 CODEC_LOGE("failed, iface NULL!"); 43 return HDF_FAILURE; 44 } 45 46 codecGroupNode = iface->GetChildNode(node, nodeName); 47 if (codecGroupNode == NULL) { 48 CODEC_LOGE("failed to get child node %{public}s!", nodeName); 49 return HDF_FAILURE; 50 } 51 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) { 52 result++; 53 } 54 *num = result; 55 56 return HDF_SUCCESS; 57} 58 59static int32_t GetUintTableConfig(const struct DeviceResourceIface *iface, 60 const struct DeviceResourceNode *node, ConfigUintArrayNodeAttr *attr) 61{ 62 if (iface == NULL || node == NULL || attr == NULL) { 63 CODEC_LOGE("invalid param!"); 64 return HDF_ERR_INVALID_PARAM; 65 } 66 if (attr->array == NULL || attr->attrName == NULL) { 67 CODEC_LOGE("invalid attr!"); 68 return HDF_ERR_INVALID_PARAM; 69 } 70 71 int32_t count = iface->GetElemNum(node, attr->attrName); 72 if (count < 0 || count >= attr->length) { 73 CODEC_LOGE("%{public}s table size: %{public}d incorrect or exceed max size %{public}d!", attr->attrName, 74 count, attr->length - 1); 75 return HDF_FAILURE; 76 } 77 78 if (count > 0) { 79 iface->GetUint32Array(node, attr->attrName, (uint32_t *)attr->array, count, 0); 80 } 81 attr->array[count] = attr->endValue; 82 83 return HDF_SUCCESS; 84} 85 86static int32_t GetMaskedConfig(const struct DeviceResourceIface *iface, 87 const struct DeviceResourceNode *node, const char *attrName, uint32_t *mask) 88{ 89 if (iface == NULL || node == NULL || attrName == NULL || mask == NULL) { 90 CODEC_LOGE("invalid param!"); 91 return HDF_ERR_INVALID_PARAM; 92 } 93 94 uint32_t *values = NULL; 95 int32_t count = iface->GetElemNum(node, attrName); 96 97 *mask = 0; 98 if (count < 0 || count > MASK_NUM_LIMIT) { 99 CODEC_LOGE("count %{public}d incorrect!", count); 100 return HDF_FAILURE; 101 } 102 103 if (count > 0) { 104 values = (uint32_t *)OsalMemAlloc(sizeof(uint32_t) * count); 105 if (values == NULL) { 106 CODEC_LOGE("failed to allocate mem for %{public}s!", attrName); 107 return HDF_FAILURE; 108 } 109 iface->GetUint32Array(node, attrName, values, count, 0); 110 for (int32_t index = 0; index < count; index++) { 111 *mask |= values[index]; 112 } 113 OsalMemFree(values); 114 } 115 116 return HDF_SUCCESS; 117} 118 119static int32_t GetVideoPortCapability(const struct DeviceResourceIface *iface, 120 const struct DeviceResourceNode *childNode, CodecCompCapability *cap) 121{ 122 if (iface == NULL || childNode == NULL || cap == NULL) { 123 CODEC_LOGE("invalid param!"); 124 return HDF_ERR_INVALID_PARAM; 125 } 126 127 ConfigUintNodeAttr nodeAttrs[] = { 128 {CODEC_CONFIG_KEY_MIN_WIDTH, (uint32_t*)&cap->port.video.minSize.width, 0}, 129 {CODEC_CONFIG_KEY_MIN_HEIGHT, (uint32_t*)&cap->port.video.minSize.height, 0}, 130 {CODEC_CONFIG_KEY_MAX_WIDTH, (uint32_t*)&cap->port.video.maxSize.width, 0}, 131 {CODEC_CONFIG_KEY_MAX_HEIGHT, (uint32_t*)&cap->port.video.maxSize.height, 0}, 132 {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, (uint32_t*)&cap->port.video.whAlignment.widthAlignment, 0}, 133 {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, (uint32_t*)&cap->port.video.whAlignment.heightAlignment, 0}, 134 {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, (uint32_t*)&cap->port.video.blockCount.min, 0}, 135 {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, (uint32_t*)&cap->port.video.blockCount.max, 0}, 136 {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, (uint32_t*)&cap->port.video.blocksPerSecond.min, 0}, 137 {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, (uint32_t*)&cap->port.video.blocksPerSecond.max, 0}, 138 {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, (uint32_t*)&cap->port.video.blockSize.width, 0}, 139 {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, (uint32_t*)&cap->port.video.blockSize.height, 0}, 140 {CODEC_CONFIG_KEY_MIN_FRAME_RATE, (uint32_t *)&cap->port.video.frameRate.min, 0}, 141 {CODEC_CONFIG_KEY_MAX_FRAME_RATE, (uint32_t *)&cap->port.video.frameRate.max, 0} 142 }; 143 144 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr); 145 for (int32_t i = 0; i < count; i++) { 146 if (iface->GetUint32(childNode, nodeAttrs[i].attrName, nodeAttrs[i].valueAddr, 147 nodeAttrs[i].defaultValue) != HDF_SUCCESS) { 148 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode->name, nodeAttrs[i].attrName); 149 return HDF_FAILURE; 150 } 151 } 152 153 ConfigUintArrayNodeAttr arrayAttrs[] = { 154 {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap->port.video.supportPixFmts, PIX_FORMAT_NUM, OMX_COLOR_FormatUnused}, 155 {CODEC_CONFIG_KEY_BITE_RATE_MODE, (int32_t *)cap->port.video.bitRatemode, BIT_RATE_MODE_NUM, 156 BIT_RATE_MODE_INVALID}, 157 {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap->port.video.measuredFrameRate, MEASURED_FRAME_RATE_NUM, 0} 158 }; 159 160 count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr); 161 for (int32_t i = 0; i < count; i++) { 162 if (GetUintTableConfig(iface, childNode, &arrayAttrs[i]) != HDF_SUCCESS) { 163 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode->name, nodeAttrs[i].attrName); 164 return HDF_FAILURE; 165 } 166 } 167 return HDF_SUCCESS; 168} 169 170static int32_t GetAudioPortCapability(const struct DeviceResourceIface *iface, 171 const struct DeviceResourceNode *childNode, CodecCompCapability *cap) 172{ 173 if (iface == NULL || childNode == NULL || cap == NULL) { 174 CODEC_LOGE("invalid param!"); 175 return HDF_ERR_INVALID_PARAM; 176 } 177 178 ConfigUintArrayNodeAttr arrayAttrs[] = { 179 {CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap->port.audio.sampleFormats, SAMPLE_FMT_NUM, AUDIO_SAMPLE_FMT_INVALID}, 180 {CODEC_CONFIG_KEY_SAMPLE_RATE, cap->port.audio.sampleRate, SAMPLE_RATE_NUM, AUD_SAMPLE_RATE_INVALID}, 181 {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap->port.audio.channelLayouts, CHANNEL_NUM, -1}, 182 {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap->port.audio.channelCount, CHANNEL_NUM, -1} 183 }; 184 185 int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr); 186 for (int32_t i = 0; i < count; i++) { 187 if (GetUintTableConfig(iface, childNode, &arrayAttrs[i]) != HDF_SUCCESS) { 188 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode->name, arrayAttrs[i].attrName); 189 return HDF_FAILURE; 190 } 191 } 192 193 return HDF_SUCCESS; 194} 195 196static int32_t GetMiscOfCapability(const struct DeviceResourceIface *iface, 197 const struct DeviceResourceNode *childNode, CodecCompCapability *cap) 198{ 199 if (iface == NULL || childNode == NULL || cap == NULL) { 200 CODEC_LOGE("invalid param!"); 201 return HDF_ERR_INVALID_PARAM; 202 } 203 204 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES, 205 cap->supportProfiles, PROFILE_NUM, INVALID_PROFILE}; 206 if (GetUintTableConfig(iface, childNode, &attr) != HDF_SUCCESS) { 207 return HDF_FAILURE; 208 } 209 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_INST, (uint32_t*)&cap->maxInst, 0) != HDF_SUCCESS) { 210 return HDF_FAILURE; 211 } 212 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK, 213 (uint32_t *)&cap->processModeMask) != HDF_SUCCESS) { 214 return HDF_FAILURE; 215 } 216 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, &cap->capsMask) != HDF_SUCCESS) { 217 return HDF_FAILURE; 218 } 219 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MIN_BITRATE, (uint32_t*)&(cap->bitRate.min), 0) != HDF_SUCCESS) { 220 return HDF_FAILURE; 221 } 222 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_BITRATE, (uint32_t*)&(cap->bitRate.max), 0) != HDF_SUCCESS) { 223 return HDF_FAILURE; 224 } 225 226 return HDF_SUCCESS; 227} 228 229static int32_t GetOneCapability(const struct DeviceResourceIface *iface, 230 const struct DeviceResourceNode *childNode, CodecCompCapability *cap, bool isVideoGroup) 231{ 232 if (iface == NULL || childNode == NULL || cap == NULL) { 233 CODEC_LOGE("invalid param!"); 234 return HDF_ERR_INVALID_PARAM; 235 } 236 237 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_ROLE, 238 (uint32_t*)&cap->role, MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) { 239 cap->role = MEDIA_ROLETYPE_INVALID; 240 CODEC_LOGE("failed to get mime for: %{public}s! Discarded", childNode->name); 241 return HDF_FAILURE; 242 } 243 244 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_TYPE, (uint32_t*)&cap->type, INVALID_TYPE) != HDF_SUCCESS) { 245 cap->role = MEDIA_ROLETYPE_INVALID; 246 cap->type = INVALID_TYPE; 247 CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode->name); 248 return HDF_FAILURE; 249 } 250 251 const char *compName = NULL; 252 if (iface->GetString(childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) { 253 cap->role = MEDIA_ROLETYPE_INVALID; 254 return HDF_FAILURE; 255 } 256 if (compName == NULL || strlen(compName) >= NAME_LENGTH || strlen(compName) == 0) { 257 cap->role = MEDIA_ROLETYPE_INVALID; 258 return HDF_FAILURE; 259 } 260 int32_t ret = strcpy_s(cap->compName, NAME_LENGTH, compName); 261 if (ret != EOK) { 262 CODEC_LOGE("strcpy_s is failed, error code: %{public}d!", ret); 263 return HDF_FAILURE; 264 } 265 cap->isSoftwareCodec = iface->GetBool(childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC); 266 cap->canSwapWidthHeight = iface->GetBool(childNode, CODEC_CONFIG_KEY_CAN_SWAP_WIDTH_HEIGHT); 267 268 if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) { 269 cap->role = MEDIA_ROLETYPE_INVALID; 270 return HDF_FAILURE; 271 } 272 273 if (isVideoGroup) { 274 if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) { 275 cap->role = MEDIA_ROLETYPE_INVALID; 276 return HDF_FAILURE; 277 } 278 } else { 279 if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) { 280 cap->role = MEDIA_ROLETYPE_INVALID; 281 return HDF_FAILURE; 282 } 283 } 284 285 return HDF_SUCCESS; 286} 287 288static int32_t GetGroupCapabilities(const struct DeviceResourceNode *node, 289 const char *nodeName, CodecCapablityGroup *capsGroup) 290{ 291 if (node == NULL || nodeName == NULL || capsGroup == NULL) { 292 CODEC_LOGE("invalid param!"); 293 return HDF_ERR_INVALID_PARAM; 294 } 295 296 CodecCompCapability *cap = NULL; 297 int32_t index = 0; 298 bool isVideoGroup = true; 299 const struct DeviceResourceNode *codecGroupNode = NULL; 300 struct DeviceResourceNode *childNode = NULL; 301 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 302 if (iface == NULL) { 303 CODEC_LOGE("iface NULL!"); 304 return HDF_ERR_INVALID_PARAM; 305 } 306 307 codecGroupNode = iface->GetChildNode(node, nodeName); 308 if (codecGroupNode == NULL) { 309 CODEC_LOGE("failed to get child node: %{public}s!", nodeName); 310 return HDF_FAILURE; 311 } 312 313 if (strstr(nodeName, "Video") == NULL) { 314 isVideoGroup = false; 315 } 316 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) { 317 cap = &(capsGroup->capablitis[index++]); 318 if (cap == NULL) { 319 continue; 320 } 321 if (GetOneCapability(iface, childNode, cap, isVideoGroup) != HDF_SUCCESS) { 322 CODEC_LOGE("GetOneCapability failed, role is %{public}d!", cap->role); 323 } 324 } 325 326 return HDF_SUCCESS; 327} 328 329int32_t LoadCodecCapabilityFromHcs(const struct DeviceResourceNode *node, CodecCapablites *caps) 330{ 331 if (node == NULL || caps == NULL) { 332 CODEC_LOGE("invalid param!"); 333 return HDF_ERR_INVALID_PARAM; 334 } 335 CodecCapablityGroup *codecCapGroup = NULL; 336 int32_t index; 337 int32_t codecNum = 0; 338 339 char *codecGroupsNodeName[] = { 340 NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS, NODE_VIDEO_SOFTWARE_ENCODERS, 341 NODE_VIDEO_SOFTWARE_DECODERS, NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS, 342 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS 343 }; 344 CodecCapablityGroup *codecCapGroups[] = { 345 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup), 346 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup), 347 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup), 348 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup) 349 }; 350 351 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) { 352 if (GetGroupCapabilitiesNumber(node, codecGroupsNodeName[index], &codecNum) == HDF_SUCCESS) { 353 codecCapGroup = codecCapGroups[index]; 354 if (codecNum > 0) { 355 codecCapGroup->num = codecNum; 356 codecCapGroup->capablitis 357 = (CodecCompCapability *)OsalMemAlloc(sizeof(CodecCompCapability) * codecNum); 358 } else { 359 codecCapGroup->capablitis = NULL; 360 codecCapGroup->num = 0; 361 } 362 if (codecNum > 0 && codecCapGroup->capablitis == NULL) { 363 codecCapGroup->num = 0; 364 CODEC_LOGE("MemAlloc for capability group failed!"); 365 return HDF_FAILURE; 366 } 367 caps->total += codecCapGroup->num; 368 } 369 } 370 371 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) { 372 if (GetGroupCapabilities(node, codecGroupsNodeName[index], codecCapGroups[index]) != HDF_SUCCESS) { 373 CODEC_LOGE("GetGroupCapabilities failed index: %{public}d!", index); 374 return HDF_FAILURE; 375 } 376 } 377 caps->inited = true; 378 return HDF_SUCCESS; 379} 380 381int32_t ClearCapabilityGroup(CodecCapablites *caps) 382{ 383 if (caps == NULL) { 384 CODEC_LOGE("invalid param!"); 385 return HDF_ERR_INVALID_PARAM; 386 } 387 388 int32_t index; 389 CodecCapablityGroup *codecCapGroup = NULL; 390 CodecCapablityGroup *codecCapGroups[] = { 391 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup), 392 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup), 393 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup), 394 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup) 395 }; 396 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) { 397 codecCapGroup = codecCapGroups[index]; 398 if (codecCapGroup->capablitis != NULL) { 399 OsalMemFree(codecCapGroup->capablitis); 400 codecCapGroup->num = 0; 401 codecCapGroup->capablitis = NULL; 402 } 403 } 404 caps->inited = false; 405 caps->total = 0; 406 return HDF_SUCCESS; 407} 408