1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <array> 17094332d3Sopenharmony_ci#include "codec_image_config.h" 18094332d3Sopenharmony_ci#include "codec_log_wrapper.h" 19094332d3Sopenharmony_cinamespace { 20094332d3Sopenharmony_ci constexpr char NODE_IMAGE_HARDWARE_ENCODERS[] = "ImageHwEncoders"; 21094332d3Sopenharmony_ci constexpr char NODE_IMAGE_HARDWARE_DECODERS[] = "ImageHwDecoders"; 22094332d3Sopenharmony_ci 23094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_ROLE[] = "role"; 24094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_TYPE[] = "type"; 25094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_NAME[] = "name"; 26094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MAX_SAMPLE[] = "maxSample"; 27094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth"; 28094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight"; 29094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth"; 30094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight"; 31094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst"; 32094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment"; 33094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment"; 34094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec"; 35094332d3Sopenharmony_ci constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts"; 36094332d3Sopenharmony_ci} 37094332d3Sopenharmony_cinamespace OHOS { 38094332d3Sopenharmony_cinamespace HDI { 39094332d3Sopenharmony_cinamespace Codec { 40094332d3Sopenharmony_cinamespace Image { 41094332d3Sopenharmony_cinamespace V2_0 { 42094332d3Sopenharmony_ciCodecImageConfig CodecImageConfig::config_; 43094332d3Sopenharmony_ci 44094332d3Sopenharmony_ciCodecImageConfig::CodecImageConfig() 45094332d3Sopenharmony_ci{ 46094332d3Sopenharmony_ci node_.name = nullptr; 47094332d3Sopenharmony_ci node_.hashValue = 0; 48094332d3Sopenharmony_ci node_.attrData = nullptr; 49094332d3Sopenharmony_ci node_.parent = nullptr; 50094332d3Sopenharmony_ci node_.child = nullptr; 51094332d3Sopenharmony_ci node_.sibling = nullptr; 52094332d3Sopenharmony_ci} 53094332d3Sopenharmony_ci 54094332d3Sopenharmony_civoid CodecImageConfig::Init(const struct DeviceResourceNode &node) 55094332d3Sopenharmony_ci{ 56094332d3Sopenharmony_ci node_ = node; 57094332d3Sopenharmony_ci const uint32_t count = 2; // encoder and decoder 58094332d3Sopenharmony_ci const static std::array<std::string, count> codecGroupsNodeName = { 59094332d3Sopenharmony_ci NODE_IMAGE_HARDWARE_ENCODERS, 60094332d3Sopenharmony_ci NODE_IMAGE_HARDWARE_DECODERS 61094332d3Sopenharmony_ci }; 62094332d3Sopenharmony_ci for (uint32_t index = 0; index < count; index++) { 63094332d3Sopenharmony_ci if (GetGroupCapabilities(codecGroupsNodeName[index]) != HDF_SUCCESS) { 64094332d3Sopenharmony_ci continue; 65094332d3Sopenharmony_ci } 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci CODEC_LOGI("Init Run....capList_.size=%{public}zu", capList_.size()); 68094332d3Sopenharmony_ci} 69094332d3Sopenharmony_ci 70094332d3Sopenharmony_ciCodecImageConfig *CodecImageConfig::GetInstance() 71094332d3Sopenharmony_ci{ 72094332d3Sopenharmony_ci return &config_; 73094332d3Sopenharmony_ci} 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_ciint32_t CodecImageConfig::GetImageCapabilityList(std::vector<CodecImageCapability> &capList) 76094332d3Sopenharmony_ci{ 77094332d3Sopenharmony_ci size_t size = capList_.size(); 78094332d3Sopenharmony_ci CODEC_LOGI("size[%{public}zu]", size); 79094332d3Sopenharmony_ci if (size == 0) { 80094332d3Sopenharmony_ci return HDF_FAILURE; 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci auto first = capList_.begin(); 83094332d3Sopenharmony_ci auto last = capList_.end(); 84094332d3Sopenharmony_ci capList.assign(first, last); 85094332d3Sopenharmony_ci return HDF_SUCCESS; 86094332d3Sopenharmony_ci} 87094332d3Sopenharmony_ci 88094332d3Sopenharmony_ciint32_t CodecImageConfig::GetGroupCapabilities(const std::string &nodeName) 89094332d3Sopenharmony_ci{ 90094332d3Sopenharmony_ci const struct DeviceResourceNode *codecGroupNode = nullptr; 91094332d3Sopenharmony_ci struct DeviceResourceNode *childNode = nullptr; 92094332d3Sopenharmony_ci struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 93094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(iface != nullptr, HDF_ERR_INVALID_PARAM, "iface is nullptr"); 94094332d3Sopenharmony_ci 95094332d3Sopenharmony_ci codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str()); 96094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(codecGroupNode != nullptr, HDF_FAILURE, "failed to get child node: %{public}s!", 97094332d3Sopenharmony_ci nodeName.c_str()); 98094332d3Sopenharmony_ci 99094332d3Sopenharmony_ci DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) 100094332d3Sopenharmony_ci { 101094332d3Sopenharmony_ci CodecImageCapability cap; 102094332d3Sopenharmony_ci if (GetOneCapability(*iface, *childNode, cap) != HDF_SUCCESS) { 103094332d3Sopenharmony_ci CODEC_LOGE("GetOneCapability failed, name is %{public}s!", cap.name.c_str()); 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci capList_.push_back(cap); 106094332d3Sopenharmony_ci } 107094332d3Sopenharmony_ci 108094332d3Sopenharmony_ci return HDF_SUCCESS; 109094332d3Sopenharmony_ci} 110094332d3Sopenharmony_ci 111094332d3Sopenharmony_ciint32_t CodecImageConfig::GetOneCapability(const struct DeviceResourceIface &iface, 112094332d3Sopenharmony_ci const struct DeviceResourceNode &childNode, CodecImageCapability &cap) 113094332d3Sopenharmony_ci{ 114094332d3Sopenharmony_ci const char *name = nullptr; 115094332d3Sopenharmony_ci auto ret = iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &name, ""); 116094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, HDF_FAILURE, "get attr %{public}s err!", CODEC_CONFIG_KEY_NAME); 117094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(name != nullptr && strlen(name) != 0, HDF_FAILURE, "compName is nullptr or empty!"); 118094332d3Sopenharmony_ci cap.name = name; 119094332d3Sopenharmony_ci 120094332d3Sopenharmony_ci if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, reinterpret_cast<uint32_t *>(&cap.role), 121094332d3Sopenharmony_ci CODEC_IMAGE_INVALID) != HDF_SUCCESS) { 122094332d3Sopenharmony_ci cap.role = CODEC_IMAGE_INVALID; 123094332d3Sopenharmony_ci CODEC_LOGE("failed to get role for: %{public}s! Discarded", childNode.name); 124094332d3Sopenharmony_ci return HDF_FAILURE; 125094332d3Sopenharmony_ci } 126094332d3Sopenharmony_ci 127094332d3Sopenharmony_ci if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, reinterpret_cast<uint32_t *>(&cap.type), 128094332d3Sopenharmony_ci CODEC_IMAGE_TYPE_INVALID) != HDF_SUCCESS) { 129094332d3Sopenharmony_ci cap.role = CODEC_IMAGE_INVALID; 130094332d3Sopenharmony_ci cap.type = CODEC_IMAGE_TYPE_INVALID; 131094332d3Sopenharmony_ci CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name); 132094332d3Sopenharmony_ci return HDF_FAILURE; 133094332d3Sopenharmony_ci } 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_ci cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC); 136094332d3Sopenharmony_ci 137094332d3Sopenharmony_ci ConfigUintNodeAttr nodeAttrs[] = { 138094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MIN_WIDTH, cap.minWidth, 0}, 139094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.minHeight, 0}, 140094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MAX_WIDTH, cap.maxWidth, 0}, 141094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.maxHeight, 0}, 142094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MAX_INST, cap.maxInst, 0}, 143094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_MAX_SAMPLE, cap.maxSample, 0}, 144094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.widthAlignment, 0}, 145094332d3Sopenharmony_ci {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.heightAlignment, 0}}; 146094332d3Sopenharmony_ci 147094332d3Sopenharmony_ci int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr); 148094332d3Sopenharmony_ci for (int32_t i = 0; i < count; i++) { 149094332d3Sopenharmony_ci auto err = iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(), 150094332d3Sopenharmony_ci reinterpret_cast<uint32_t *>(&nodeAttrs[i].value), nodeAttrs[i].defaultValue); 151094332d3Sopenharmony_ci 152094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(err == HDF_SUCCESS, HDF_FAILURE, "failed to get %{public}s.%{public}s!", 153094332d3Sopenharmony_ci childNode.name, nodeAttrs[i].attrName.c_str()); 154094332d3Sopenharmony_ci } 155094332d3Sopenharmony_ci 156094332d3Sopenharmony_ci ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.supportPixFmts}; 157094332d3Sopenharmony_ci ret = GetUintTableConfig(iface, childNode, attr); 158094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, HDF_FAILURE, "get uint table config [%{public}s] err!", 159094332d3Sopenharmony_ci attr.attrName.c_str()); 160094332d3Sopenharmony_ci 161094332d3Sopenharmony_ci return HDF_SUCCESS; 162094332d3Sopenharmony_ci} 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ciint32_t CodecImageConfig::GetUintTableConfig(const struct DeviceResourceIface &iface, 165094332d3Sopenharmony_ci const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr) 166094332d3Sopenharmony_ci{ 167094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(!attr.attrName.empty(), HDF_ERR_INVALID_PARAM, "failed, invalid attr"); 168094332d3Sopenharmony_ci 169094332d3Sopenharmony_ci int32_t count = iface.GetElemNum(&node, attr.attrName.c_str()); 170094332d3Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(count >= 0, HDF_FAILURE, "%{public}s table size: count[%{public}d] < 0!", 171094332d3Sopenharmony_ci attr.attrName.c_str(), count); 172094332d3Sopenharmony_ci 173094332d3Sopenharmony_ci if (count > 0) { 174094332d3Sopenharmony_ci std::unique_ptr<int32_t[]> array = std::make_unique<int32_t[]>(count); 175094332d3Sopenharmony_ci iface.GetUint32Array(&node, attr.attrName.c_str(), reinterpret_cast<uint32_t *>(array.get()), count, 0); 176094332d3Sopenharmony_ci attr.vec.assign(array.get(), array.get() + count); 177094332d3Sopenharmony_ci } 178094332d3Sopenharmony_ci return HDF_SUCCESS; 179094332d3Sopenharmony_ci} 180094332d3Sopenharmony_ci} // V2_0 181094332d3Sopenharmony_ci} // Image 182094332d3Sopenharmony_ci} // Codec 183094332d3Sopenharmony_ci} // HDI 184094332d3Sopenharmony_ci} // OHOS 185