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