1 /*
2 * Copyright (c) 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 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 <array>
17 #include "codec_image_config.h"
18 #include "codec_log_wrapper.h"
19 namespace {
20 constexpr char NODE_IMAGE_HARDWARE_ENCODERS[] = "ImageHwEncoders";
21 constexpr char NODE_IMAGE_HARDWARE_DECODERS[] = "ImageHwDecoders";
22
23 constexpr char CODEC_CONFIG_KEY_ROLE[] = "role";
24 constexpr char CODEC_CONFIG_KEY_TYPE[] = "type";
25 constexpr char CODEC_CONFIG_KEY_NAME[] = "name";
26 constexpr char CODEC_CONFIG_KEY_MAX_SAMPLE[] = "maxSample";
27 constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth";
28 constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight";
29 constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth";
30 constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight";
31 constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst";
32 constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment";
33 constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment";
34 constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec";
35 constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts";
36 }
37 namespace OHOS {
38 namespace HDI {
39 namespace Codec {
40 namespace Image {
41 namespace V2_0 {
42 CodecImageConfig CodecImageConfig::config_;
43
CodecImageConfig()44 CodecImageConfig::CodecImageConfig()
45 {
46 node_.name = nullptr;
47 node_.hashValue = 0;
48 node_.attrData = nullptr;
49 node_.parent = nullptr;
50 node_.child = nullptr;
51 node_.sibling = nullptr;
52 }
53
Init(const struct DeviceResourceNode & node)54 void CodecImageConfig::Init(const struct DeviceResourceNode &node)
55 {
56 node_ = node;
57 const uint32_t count = 2; // encoder and decoder
58 const static std::array<std::string, count> codecGroupsNodeName = {
59 NODE_IMAGE_HARDWARE_ENCODERS,
60 NODE_IMAGE_HARDWARE_DECODERS
61 };
62 for (uint32_t index = 0; index < count; index++) {
63 if (GetGroupCapabilities(codecGroupsNodeName[index]) != HDF_SUCCESS) {
64 continue;
65 }
66 }
67 CODEC_LOGI("Init Run....capList_.size=%{public}zu", capList_.size());
68 }
69
GetInstance()70 CodecImageConfig *CodecImageConfig::GetInstance()
71 {
72 return &config_;
73 }
74
GetImageCapabilityList(std::vector<CodecImageCapability> & capList)75 int32_t CodecImageConfig::GetImageCapabilityList(std::vector<CodecImageCapability> &capList)
76 {
77 size_t size = capList_.size();
78 CODEC_LOGI("size[%{public}zu]", size);
79 if (size == 0) {
80 return HDF_FAILURE;
81 }
82 auto first = capList_.begin();
83 auto last = capList_.end();
84 capList.assign(first, last);
85 return HDF_SUCCESS;
86 }
87
GetGroupCapabilities(const std::string & nodeName)88 int32_t CodecImageConfig::GetGroupCapabilities(const std::string &nodeName)
89 {
90 const struct DeviceResourceNode *codecGroupNode = nullptr;
91 struct DeviceResourceNode *childNode = nullptr;
92 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
93 CHECK_AND_RETURN_RET_LOG(iface != nullptr, HDF_ERR_INVALID_PARAM, "iface is nullptr");
94
95 codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str());
96 CHECK_AND_RETURN_RET_LOG(codecGroupNode != nullptr, HDF_FAILURE, "failed to get child node: %{public}s!",
97 nodeName.c_str());
98
99 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode)
100 {
101 CodecImageCapability cap;
102 if (GetOneCapability(*iface, *childNode, cap) != HDF_SUCCESS) {
103 CODEC_LOGE("GetOneCapability failed, name is %{public}s!", cap.name.c_str());
104 }
105 capList_.push_back(cap);
106 }
107
108 return HDF_SUCCESS;
109 }
110
GetOneCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecImageCapability & cap)111 int32_t CodecImageConfig::GetOneCapability(const struct DeviceResourceIface &iface,
112 const struct DeviceResourceNode &childNode, CodecImageCapability &cap)
113 {
114 const char *name = nullptr;
115 auto ret = iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &name, "");
116 CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, HDF_FAILURE, "get attr %{public}s err!", CODEC_CONFIG_KEY_NAME);
117 CHECK_AND_RETURN_RET_LOG(name != nullptr && strlen(name) != 0, HDF_FAILURE, "compName is nullptr or empty!");
118 cap.name = name;
119
120 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, reinterpret_cast<uint32_t *>(&cap.role),
121 CODEC_IMAGE_INVALID) != HDF_SUCCESS) {
122 cap.role = CODEC_IMAGE_INVALID;
123 CODEC_LOGE("failed to get role for: %{public}s! Discarded", childNode.name);
124 return HDF_FAILURE;
125 }
126
127 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, reinterpret_cast<uint32_t *>(&cap.type),
128 CODEC_IMAGE_TYPE_INVALID) != HDF_SUCCESS) {
129 cap.role = CODEC_IMAGE_INVALID;
130 cap.type = CODEC_IMAGE_TYPE_INVALID;
131 CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name);
132 return HDF_FAILURE;
133 }
134
135 cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
136
137 ConfigUintNodeAttr nodeAttrs[] = {
138 {CODEC_CONFIG_KEY_MIN_WIDTH, cap.minWidth, 0},
139 {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.minHeight, 0},
140 {CODEC_CONFIG_KEY_MAX_WIDTH, cap.maxWidth, 0},
141 {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.maxHeight, 0},
142 {CODEC_CONFIG_KEY_MAX_INST, cap.maxInst, 0},
143 {CODEC_CONFIG_KEY_MAX_SAMPLE, cap.maxSample, 0},
144 {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.widthAlignment, 0},
145 {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.heightAlignment, 0}};
146
147 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
148 for (int32_t i = 0; i < count; i++) {
149 auto err = iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(),
150 reinterpret_cast<uint32_t *>(&nodeAttrs[i].value), nodeAttrs[i].defaultValue);
151
152 CHECK_AND_RETURN_RET_LOG(err == HDF_SUCCESS, HDF_FAILURE, "failed to get %{public}s.%{public}s!",
153 childNode.name, nodeAttrs[i].attrName.c_str());
154 }
155
156 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.supportPixFmts};
157 ret = GetUintTableConfig(iface, childNode, attr);
158 CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, HDF_FAILURE, "get uint table config [%{public}s] err!",
159 attr.attrName.c_str());
160
161 return HDF_SUCCESS;
162 }
163
GetUintTableConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,ConfigUintArrayNodeAttr & attr)164 int32_t CodecImageConfig::GetUintTableConfig(const struct DeviceResourceIface &iface,
165 const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr)
166 {
167 CHECK_AND_RETURN_RET_LOG(!attr.attrName.empty(), HDF_ERR_INVALID_PARAM, "failed, invalid attr");
168
169 int32_t count = iface.GetElemNum(&node, attr.attrName.c_str());
170 CHECK_AND_RETURN_RET_LOG(count >= 0, HDF_FAILURE, "%{public}s table size: count[%{public}d] < 0!",
171 attr.attrName.c_str(), count);
172
173 if (count > 0) {
174 std::unique_ptr<int32_t[]> array = std::make_unique<int32_t[]>(count);
175 iface.GetUint32Array(&node, attr.attrName.c_str(), reinterpret_cast<uint32_t *>(array.get()), count, 0);
176 attr.vec.assign(array.get(), array.get() + count);
177 }
178 return HDF_SUCCESS;
179 }
180 } // V2_0
181 } // Image
182 } // Codec
183 } // HDI
184 } // OHOS
185