1 /*
2 * Copyright 2020 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string.h>
18
19 #include "mpp_mem.h"
20 #include "mpp_2str.h"
21 #include "mpp_debug.h"
22 #include "mpp_common.h"
23
24 #include "hal_info.h"
25
26 typedef struct HalInfoImpl_t {
27 MppCtxType type;
28 MppCodingType coding;
29
30 RK_U32 updated;
31 RK_U32 elem_nb;
32 /* info data for output */
33 MppDevInfoCfg *elems;
34 } HalInfoImpl;
35
hal_info_init(HalInfo * ctx,MppCtxType type,MppCodingType coding)36 MPP_RET hal_info_init(HalInfo *ctx, MppCtxType type, MppCodingType coding)
37 {
38 if (NULL == ctx) {
39 mpp_err_f("found NULL input ctx\n");
40 return MPP_ERR_NULL_PTR;
41 }
42
43 MPP_RET ret = MPP_NOK;
44 RK_U32 elem_nb = (type == MPP_CTX_DEC) ? (ENC_INFO_BUTT) : (DEC_INFO_BUTT);
45 HalInfoImpl *impl = mpp_calloc_size(HalInfoImpl, sizeof(HalInfoImpl) +
46 sizeof(MppDevInfoCfg) * elem_nb);
47 if (impl) {
48 impl->type = type;
49 impl->coding = coding;
50 impl->elem_nb = elem_nb;
51 impl->elems = (MppDevInfoCfg *)(impl + 1);
52 ret = MPP_OK;
53 }
54
55 *ctx = impl;
56
57 return ret;
58 }
59
hal_info_deinit(HalInfo ctx)60 MPP_RET hal_info_deinit(HalInfo ctx)
61 {
62 MPP_FREE(ctx);
63 return MPP_OK;
64 }
65
hal_info_set(HalInfo ctx,RK_U32 type,RK_U32 flag,RK_U64 data)66 MPP_RET hal_info_set(HalInfo ctx, RK_U32 type, RK_U32 flag, RK_U64 data)
67 {
68 if (NULL == ctx) {
69 mpp_err_f("found NULL input ctx\n");
70 return MPP_ERR_NULL_PTR;
71 }
72
73 if (flag <= CODEC_INFO_FLAG_NULL || flag >= CODEC_INFO_FLAG_BUTT) {
74 mpp_err_f("found invalid flag %d\n", flag);
75 return MPP_ERR_VALUE;
76 }
77
78 HalInfoImpl *info = (HalInfoImpl *)ctx;
79 MppDevInfoCfg *elems = NULL;
80
81 switch (info->type) {
82 case MPP_CTX_DEC : {
83 if (type <= DEC_INFO_BASE || type >= DEC_INFO_BUTT) {
84 mpp_err_f("found invalid dec info type %d [%d:%d]\n",
85 type, DEC_INFO_BASE, DEC_INFO_BUTT);
86 return MPP_ERR_VALUE;
87 }
88
89 /* shift enum base */
90 type -= DEC_INFO_BASE;
91 } break;
92 case MPP_CTX_ENC : {
93 if (type <= ENC_INFO_BASE || type >= ENC_INFO_BUTT) {
94 mpp_err_f("found invalid enc info type %d [%d:%d]\n",
95 type, ENC_INFO_BASE, ENC_INFO_BUTT);
96 return MPP_ERR_VALUE;
97 }
98
99 /* shift enum base */
100 type -= ENC_INFO_BASE;
101 } break;
102 default : {
103 mpp_err_f("found invalid ctx type %d\n", info->type);
104 return MPP_ERR_VALUE;
105 } break;
106 }
107
108 elems = &info->elems[type];
109
110 if (elems->type != type || elems->flag != flag || elems->data != data) {
111 /* set enc info */
112 elems->type = type;
113 elems->flag = flag;
114 elems->data = data;
115 info->updated |= (1 << type);
116 }
117
118 return MPP_OK;
119 }
120
hal_info_get(HalInfo ctx,MppDevInfoCfg * data,RK_S32 * size)121 MPP_RET hal_info_get(HalInfo ctx, MppDevInfoCfg *data, RK_S32 *size)
122 {
123 if (NULL == ctx) {
124 mpp_err_f("found NULL input ctx\n");
125 return MPP_ERR_NULL_PTR;
126 }
127
128 if (NULL == data || NULL == size || *size == 0) {
129 mpp_err_f("found invalid output cfg data %p size %p\n", data, size);
130 return MPP_ERR_NULL_PTR;
131 }
132
133 HalInfoImpl *info = (HalInfoImpl *)ctx;
134 if (!info->updated) {
135 *size = 0;
136 return MPP_OK;
137 }
138
139 RK_S32 max_size = *size;
140 RK_S32 elem_size = sizeof(info->elems[0]);
141 RK_S32 out_size = 0;
142 RK_S32 type_max = 0;
143 RK_S32 i;
144
145 switch (info->type) {
146 case MPP_CTX_DEC : {
147 type_max = DEC_INFO_BUTT - DEC_INFO_BASE;
148 } break;
149 case MPP_CTX_ENC : {
150 type_max = ENC_INFO_BUTT - ENC_INFO_BASE;
151 } break;
152 default : {
153 mpp_err_f("found invalid ctx type %d\n", info->type);
154 return MPP_ERR_VALUE;
155 } break;
156 }
157
158 for (i = 0; i < type_max; i++) {
159 if (!(info->updated & (1 << i)))
160 continue;
161
162 if (out_size + elem_size > max_size) {
163 mpp_err_f("out data size %d is too small for %d\n",
164 max_size, out_size + elem_size);
165 break;
166 }
167
168 memcpy(data, &info->elems[i], elem_size);
169 data++;
170 out_size += elem_size;
171 info->updated &= ~(1 << i);
172 }
173
174 *size = out_size;
175 return MPP_OK;
176 }
177
hal_info_to_string(HalInfo ctx,RK_U32 type,void * val)178 RK_U64 hal_info_to_string(HalInfo ctx, RK_U32 type, void *val)
179 {
180 RK_U64 ret = 0;
181
182 if (NULL == ctx || NULL == val) {
183 mpp_err_f("found NULL input ctx %p val %p\n", ctx, val);
184 return ret;
185 }
186
187 HalInfoImpl *info = (HalInfoImpl *)ctx;
188 const char *str = NULL;
189
190 switch (info->type) {
191 case MPP_CTX_DEC : {
192 switch (type) {
193 case DEC_INFO_FORMAT : {
194 MppCodingType coding = *((MppCodingType *)val);
195
196 mpp_assert(coding == info->coding);
197 str = strof_coding_type(coding);
198 } break;
199 default : {
200 } break;
201 }
202 } break;
203 case MPP_CTX_ENC : {
204 switch (type) {
205 case ENC_INFO_FORMAT : {
206 MppCodingType coding = *((MppCodingType *)val);
207
208 mpp_assert(coding == info->coding);
209 str = strof_coding_type(coding);
210 } break;
211 case ENC_INFO_RC_MODE : {
212 MppEncRcMode rc_mode = *((MppEncRcMode *)val);
213
214 str = strof_rc_mode(rc_mode);
215 } break;
216 case ENC_INFO_PROFILE : {
217 RK_U32 profile = *((RK_U32 *)val);
218
219 str = strof_profle(info->coding, profile);
220 } break;
221 default : {
222 } break;
223 }
224 } break;
225 default : {
226 mpp_err_f("found invalid ctx type %d\n", info->type);
227 return MPP_ERR_VALUE;
228 } break;
229 }
230
231 if (str)
232 snprintf((void *)&ret, sizeof(ret) - 1, "%s", str);
233
234 return ret;
235 }
236
hal_info_to_float(RK_S32 num,RK_S32 denom)237 RK_U64 hal_info_to_float(RK_S32 num, RK_S32 denom)
238 {
239 RK_U64 ret = 0;
240
241 if (!denom)
242 snprintf((void *)&ret, sizeof(ret) - 1, "%d", num);
243 else
244 snprintf((void *)&ret, sizeof(ret) - 1, "%.2f", (float)num / denom);
245
246 return ret;
247 }
248
hal_info_from_enc_cfg(HalInfo ctx,MppEncCfgSet * cfg)249 MPP_RET hal_info_from_enc_cfg(HalInfo ctx, MppEncCfgSet *cfg)
250 {
251 MppEncRcCfg *rc = &cfg->rc;
252 MppEncPrepCfg *prep = &cfg->prep;
253 HalInfoImpl *info = (HalInfoImpl *)ctx;
254 RK_U32 profile = 0;
255 RK_U64 val = 0;
256
257 hal_info_set(ctx, ENC_INFO_WIDTH, CODEC_INFO_FLAG_NUMBER, prep->width);
258 hal_info_set(ctx, ENC_INFO_HEIGHT, CODEC_INFO_FLAG_NUMBER, prep->height);
259
260 val = hal_info_to_string(ctx, ENC_INFO_FORMAT, &info->coding);
261
262 hal_info_set(ctx, ENC_INFO_FORMAT, CODEC_INFO_FLAG_STRING, val);
263 hal_info_set(ctx, ENC_INFO_FPS_IN, CODEC_INFO_FLAG_NUMBER,
264 rc->fps_in_num / rc->fps_in_denom);
265 hal_info_set(ctx, ENC_INFO_FPS_OUT, CODEC_INFO_FLAG_NUMBER,
266 rc->fps_out_num / rc->fps_out_denom);
267
268 val = hal_info_to_string(ctx, ENC_INFO_RC_MODE, &rc->rc_mode);
269 hal_info_set(ctx, ENC_INFO_RC_MODE, CODEC_INFO_FLAG_STRING, val);
270
271 hal_info_set(ctx, ENC_INFO_BITRATE, CODEC_INFO_FLAG_NUMBER, rc->bps_target);
272 hal_info_set(ctx, ENC_INFO_GOP_SIZE, CODEC_INFO_FLAG_NUMBER, rc->gop);
273
274 switch (info->coding) {
275 case MPP_VIDEO_CodingAVC : {
276 profile = cfg->h264.profile;
277 } break;
278 case MPP_VIDEO_CodingHEVC : {
279 profile = cfg->h265.profile;
280 } break;
281 case MPP_VIDEO_CodingMJPEG :
282 case MPP_VIDEO_CodingVP8 :
283 default : {
284 } break;
285 }
286 val = hal_info_to_string(ctx, ENC_INFO_PROFILE, &profile);
287 hal_info_set(ctx, ENC_INFO_PROFILE, CODEC_INFO_FLAG_STRING, val);
288
289 return MPP_OK;
290 }
291