xref: /OK3568_Linux_fs/external/mpp/mpp/hal/common/hal_info.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 denorm)237 RK_U64 hal_info_to_float(RK_S32 num, RK_S32 denorm)
238 {
239     RK_U64 ret = 0;
240 
241     if (!denorm)
242         snprintf((void *)&ret, sizeof(ret) - 1, "%d", num);
243     else
244         snprintf((void *)&ret, sizeof(ret) - 1, "%.2f", (float)num / denorm);
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     MppEncCodecCfg *codec = &cfg->codec;
254     HalInfoImpl *info = (HalInfoImpl *)ctx;
255     RK_U32 profile = 0;
256     RK_U64 val = 0;
257 
258     hal_info_set(ctx, ENC_INFO_WIDTH, CODEC_INFO_FLAG_NUMBER, prep->width);
259     hal_info_set(ctx, ENC_INFO_HEIGHT, CODEC_INFO_FLAG_NUMBER, prep->height);
260 
261     val = hal_info_to_string(ctx, ENC_INFO_FORMAT, &info->coding);
262 
263     hal_info_set(ctx, ENC_INFO_FORMAT, CODEC_INFO_FLAG_STRING, val);
264     hal_info_set(ctx, ENC_INFO_FPS_IN, CODEC_INFO_FLAG_NUMBER,
265                  rc->fps_in_num / rc->fps_in_denorm);
266     hal_info_set(ctx, ENC_INFO_FPS_OUT, CODEC_INFO_FLAG_NUMBER,
267                  rc->fps_out_num / rc->fps_out_denorm);
268 
269     val = hal_info_to_string(ctx, ENC_INFO_RC_MODE, &rc->rc_mode);
270     hal_info_set(ctx, ENC_INFO_RC_MODE, CODEC_INFO_FLAG_STRING, val);
271 
272     hal_info_set(ctx, ENC_INFO_BITRATE, CODEC_INFO_FLAG_NUMBER, rc->bps_target);
273     hal_info_set(ctx, ENC_INFO_GOP_SIZE, CODEC_INFO_FLAG_NUMBER, rc->gop);
274 
275     switch (info->coding) {
276     case MPP_VIDEO_CodingAVC : {
277         profile = codec->h264.profile;
278     } break;
279     case MPP_VIDEO_CodingHEVC : {
280         profile = codec->h265.profile;
281     } break;
282     case MPP_VIDEO_CodingMJPEG :
283     case MPP_VIDEO_CodingVP8 :
284     default : {
285     } break;
286     }
287     val = hal_info_to_string(ctx, ENC_INFO_PROFILE, &profile);
288     hal_info_set(ctx, ENC_INFO_PROFILE, CODEC_INFO_FLAG_STRING, val);
289 
290     return MPP_OK;
291 }
292