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