1 /*
2 * Copyright 2015 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 #define MODULE_TAG "vpu_api_legacy"
18
19 #include "string.h"
20
21 #include "mpp_mem.h"
22 #include "mpp_env.h"
23 #include "mpp_time.h"
24 #include "mpp_debug.h"
25 #include "mpp_common.h"
26
27 #include "vpu_api_legacy.h"
28 #include "mpp_packet_impl.h"
29 #include "mpp_buffer_impl.h"
30 #include "mpp_frame.h"
31 #include "mpp_compat.h"
32
33 #define VPU_API_ENC_INPUT_TIMEOUT 100
34
35 RK_U32 vpu_api_debug = 0;
36
vpu_pic_type_remap_to_mpp(EncInputPictureType type)37 static MppFrameFormat vpu_pic_type_remap_to_mpp(EncInputPictureType type)
38 {
39 MppFrameFormat ret = MPP_FMT_BUTT;
40 switch (type) {
41 case ENC_INPUT_YUV420_PLANAR : {
42 ret = MPP_FMT_YUV420P;
43 } break;
44 case ENC_INPUT_YUV420_SEMIPLANAR : {
45 ret = MPP_FMT_YUV420SP;
46 } break;
47 case ENC_INPUT_YUV420_SEMIPLANAR_VU : {
48 ret = MPP_FMT_YUV420SP_VU;
49 } break;
50 case ENC_INPUT_YUV422_INTERLEAVED_YUYV : {
51 ret = MPP_FMT_YUV422_YUYV;
52 } break;
53 case ENC_INPUT_YUV422_INTERLEAVED_UYVY : {
54 ret = MPP_FMT_YUV422_UYVY;
55 } break;
56 case ENC_INPUT_RGB565 : {
57 ret = MPP_FMT_RGB565;
58 } break;
59 case ENC_INPUT_BGR565 : {
60 ret = MPP_FMT_BGR565;
61 } break;
62 case ENC_INPUT_RGB555 : {
63 ret = MPP_FMT_RGB555;
64 } break;
65 case ENC_INPUT_BGR555 : {
66 ret = MPP_FMT_BGR555;
67 } break;
68 case ENC_INPUT_RGB444 : {
69 ret = MPP_FMT_RGB444;
70 } break;
71 case ENC_INPUT_BGR444 : {
72 ret = MPP_FMT_BGR444;
73 } break;
74 case ENC_INPUT_RGB888 : {
75 ret = MPP_FMT_RGB888;
76 } break;
77 case ENC_INPUT_BGR888 : {
78 ret = MPP_FMT_BGR888;
79 } break;
80 case ENC_INPUT_RGB101010 : {
81 ret = MPP_FMT_RGB101010;
82 } break;
83 case ENC_INPUT_BGR101010 : {
84 ret = MPP_FMT_BGR101010;
85 } break;
86 default : {
87 mpp_err("There is no match format, err!!!!!!");
88 } break;
89 }
90 return ret;
91 }
92
vpu_api_set_enc_cfg(MppCtx mpp_ctx,MppApi * mpi,MppEncCfg enc_cfg,MppCodingType coding,MppFrameFormat fmt,EncParameter_t * cfg)93 static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, MppEncCfg enc_cfg,
94 MppCodingType coding, MppFrameFormat fmt,
95 EncParameter_t *cfg)
96 {
97 MPP_RET ret = MPP_OK;
98 RK_S32 width = cfg->width;
99 RK_S32 height = cfg->height;
100 RK_S32 bps = cfg->bitRate;
101 RK_S32 fps_in = cfg->framerate;
102 RK_S32 fps_out = (cfg->framerateout) ? (cfg->framerateout) : (fps_in);
103 RK_S32 gop = (cfg->intraPicRate) ? (cfg->intraPicRate) : (fps_out);
104 RK_S32 qp_init = (coding == MPP_VIDEO_CodingAVC) ? (26) :
105 (coding == MPP_VIDEO_CodingMJPEG) ? (10) :
106 (coding == MPP_VIDEO_CodingVP8) ? (56) :
107 (coding == MPP_VIDEO_CodingHEVC) ? (26) : (0);
108 RK_S32 qp = (cfg->qp) ? (cfg->qp) : (qp_init);
109 RK_S32 profile = cfg->profileIdc;
110 RK_S32 level = cfg->levelIdc;
111 RK_S32 cabac_en = cfg->enableCabac;
112 RK_S32 rc_mode = cfg->rc_mode;
113 RK_U32 is_fix_qp = (rc_mode == MPP_ENC_RC_MODE_FIXQP) ? 1 : 0;
114
115 RK_S32 qp_max = (cfg->reserved[0] & 0xFF00) >> 8;
116 RK_S32 qp_min = cfg->reserved[0] & 0x00FF;
117
118 if (qp_max == 0 || qp_max < qp) {
119 qp_max = 51;
120 }
121 if (qp_min == 0 || qp_min > qp) {
122 qp_min = 10;
123 }
124
125 mpp_log("setup encoder rate control config:\n");
126 mpp_log("width %4d height %4d format %d:%x\n", width, height, cfg->format, fmt);
127 mpp_log("rc_mode %s qp %d bps %d\n", (rc_mode) ? ("CBR") : ("CQP"), qp, bps);
128 mpp_log("fps in %d fps out %d gop %d\n", fps_in, fps_out, gop);
129 mpp_log("setup encoder stream feature config:\n");
130 mpp_log("profile %d level %d cabac %d\n", profile, level, cabac_en);
131 mpp_log("setup encoder qp_init %d qp_min %d qp_max %d\n", qp, qp_min, qp_max);
132
133 mpp_assert(width);
134 mpp_assert(height);
135 mpp_assert(qp);
136
137 mpp_enc_cfg_set_s32(enc_cfg, "prep:width", width);
138 mpp_enc_cfg_set_s32(enc_cfg, "prep:height", height);
139 switch (fmt & MPP_FRAME_FMT_MASK) {
140 case MPP_FMT_YUV420P:
141 case MPP_FMT_YUV420SP :
142 case MPP_FMT_YUV420SP_VU : {
143 mpp_enc_cfg_set_s32(enc_cfg, "prep:hor_stride", MPP_ALIGN(width, 16));
144 } break;
145 case MPP_FMT_RGB565:
146 case MPP_FMT_BGR565:
147 case MPP_FMT_RGB555:
148 case MPP_FMT_BGR555: {
149 mpp_enc_cfg_set_s32(enc_cfg, "prep:hor_stride", 2 * MPP_ALIGN(width, 16));
150 } break;
151 case MPP_FMT_RGB888 :
152 case MPP_FMT_BGR888 : {
153 mpp_enc_cfg_set_s32(enc_cfg, "prep:hor_stride", 3 * MPP_ALIGN(width, 16));
154 } break;
155 case MPP_FMT_ARGB8888 :
156 case MPP_FMT_ABGR8888 :
157 case MPP_FMT_BGRA8888 :
158 case MPP_FMT_RGBA8888 : {
159 mpp_enc_cfg_set_s32(enc_cfg, "prep:hor_stride", 4 * MPP_ALIGN(width, 16));
160 } break;
161 default: {
162 mpp_err("unsupport format 0x%x\n", fmt & MPP_FRAME_FMT_MASK);
163 } break;
164 }
165 mpp_enc_cfg_set_s32(enc_cfg, "prep:ver_stride", MPP_ALIGN(height, 8));
166 mpp_enc_cfg_set_s32(enc_cfg, "prep:format", fmt);
167
168 mpp_enc_cfg_set_s32(enc_cfg, "rc:mode", is_fix_qp ? MPP_ENC_RC_MODE_FIXQP :
169 (rc_mode ? MPP_ENC_RC_MODE_CBR : MPP_ENC_RC_MODE_VBR));
170 mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_target", bps);
171 mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_max", bps * 17 / 16);
172 mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_min", rc_mode ? bps * 15 / 16 : bps * 1 / 16);
173 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_flex", 0);
174 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_num", fps_in);
175 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_denom", 1);
176 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_flex", 0);
177 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_num", fps_out);
178 mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_denom", 1);
179 mpp_enc_cfg_set_s32(enc_cfg, "rc:gop", gop);
180
181 mpp_enc_cfg_set_s32(enc_cfg, "codec:type", coding);
182 switch (coding) {
183 case MPP_VIDEO_CodingAVC : {
184 mpp_enc_cfg_set_s32(enc_cfg, "h264:profile", profile);
185 mpp_enc_cfg_set_s32(enc_cfg, "h264:level", level);
186 mpp_enc_cfg_set_s32(enc_cfg, "h264:cabac_en", cabac_en);
187 mpp_enc_cfg_set_s32(enc_cfg, "h264:cabac_idc", 0);
188 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_init", is_fix_qp ? qp : -1);
189 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_min", is_fix_qp ? qp : qp_min);
190 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_max", is_fix_qp ? qp : qp_max);
191 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_min_i", is_fix_qp ? 10 : qp_min);
192 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_max_i", is_fix_qp ? 51 : qp_max);
193 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_step", 4);
194 mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_delta_ip", 3);
195 } break;
196 case MPP_VIDEO_CodingVP8 : {
197 mpp_enc_cfg_set_s32(enc_cfg, "vp8:qp_init", -1);
198 mpp_enc_cfg_set_s32(enc_cfg, "vp8:qp_min", 0);
199 mpp_enc_cfg_set_s32(enc_cfg, "vp8:qp_max", 127);
200 mpp_enc_cfg_set_s32(enc_cfg, "vp8:qp_min_i", 0);
201 mpp_enc_cfg_set_s32(enc_cfg, "vp8:qp_max_i", 127);
202 } break;
203 case MPP_VIDEO_CodingMJPEG : {
204 mpp_enc_cfg_set_s32(enc_cfg, "jpeg:quant", qp);
205 } break;
206 default : {
207 mpp_err_f("support encoder coding type %d\n", coding);
208 } break;
209 }
210
211 ret = mpi->control(mpp_ctx, MPP_ENC_SET_CFG, enc_cfg);
212 if (ret) {
213 mpp_err("setup enc config failed ret %d\n", ret);
214 goto RET;
215 }
216 RET:
217 return ret;
218 }
219
is_valid_dma_fd(int fd)220 static int is_valid_dma_fd(int fd)
221 {
222 int ret = 1;
223 /* detect input file handle */
224 int fs_flag = fcntl(fd, F_GETFL, NULL);
225 int fd_flag = fcntl(fd, F_GETFD, NULL);
226
227 if (fs_flag == -1 || fd_flag == -1) {
228 ret = 0;
229 }
230
231 return ret;
232 }
233
copy_align_raw_buffer_to_dest(RK_U8 * dst,RK_U8 * src,RK_U32 width,RK_U32 height,MppFrameFormat fmt)234 static int copy_align_raw_buffer_to_dest(RK_U8 *dst, RK_U8 *src, RK_U32 width,
235 RK_U32 height, MppFrameFormat fmt)
236 {
237 int ret = 1;
238 RK_U32 index = 0;
239 RK_U8 *dst_buf = dst;
240 RK_U8 *src_buf = src;
241 RK_U32 row = 0;
242 RK_U32 hor_stride = MPP_ALIGN(width, 16);
243 RK_U32 ver_stride = MPP_ALIGN(height, 8);
244 RK_U8 *dst_u = dst_buf + hor_stride * ver_stride;
245 RK_U8 *dst_v = dst_u + hor_stride * ver_stride / 4;
246
247 switch (fmt) {
248 case MPP_FMT_YUV420SP :
249 case MPP_FMT_YUV420SP_VU : {
250 for (row = 0; row < height; row++) {
251 memcpy(dst_buf + row * hor_stride, src_buf + index, width);
252 index += width;
253 }
254 for (row = 0; row < height / 2; row++) {
255 memcpy(dst_u + row * hor_stride, src_buf + index, width);
256 index += width;
257 }
258 } break;
259 case MPP_FMT_YUV420P : {
260 for (row = 0; row < height; row++) {
261 memcpy(dst_buf + row * hor_stride, src_buf + index, width);
262 index += width;
263 }
264 for (row = 0; row < height / 2; row++) {
265 memcpy(dst_u + row * hor_stride / 2, src_buf + index, width / 2);
266 index += width / 2;
267 }
268 for (row = 0; row < height / 2; row++) {
269 memcpy(dst_v + row * hor_stride / 2, src_buf + index, width / 2);
270 index += width / 2;
271 }
272 } break;
273 case MPP_FMT_RGB888 :
274 case MPP_FMT_BGR888 : {
275 for (row = 0; row < height; row++) {
276 memcpy(dst_buf + row * hor_stride * 3, src_buf + row * width * 3, width * 3);
277 }
278 } break;
279 case MPP_FMT_ABGR8888 :
280 case MPP_FMT_ARGB8888 :
281 case MPP_FMT_BGRA8888 :
282 case MPP_FMT_RGBA8888 : {
283 for (row = 0; row < height; row++) {
284 memcpy(dst_buf + row * hor_stride * 4, src_buf + row * width * 4, width * 4);
285 }
286 } break;
287 default : {
288 mpp_err("unsupport align fmt:%d now\n", fmt);
289 } break;
290 }
291
292 return ret;
293 }
294
VpuApiLegacy()295 VpuApiLegacy::VpuApiLegacy() :
296 mpp_ctx(NULL),
297 mpi(NULL),
298 init_ok(0),
299 frame_count(0),
300 set_eos(0),
301 frm_info(NULL),
302 memGroup(NULL),
303 format(MPP_FMT_YUV420P),
304 mInputTimeOutMs(0),
305 fd_input(-1),
306 fd_output(-1),
307 mEosSet(0),
308 enc_cfg(NULL),
309 enc_hdr_pkt(NULL),
310 enc_hdr_buf(NULL),
311 enc_hdr_buf_size(0),
312 dec_out_frm_struct_type(0)
313 {
314 vpu_api_dbg_func("enter\n");
315
316 mpp_create(&mpp_ctx, &mpi);
317 mpp_frame_init(&frm_info);
318
319 memset(&frm_rdy_cb, 0, sizeof(FrameRdyCB));
320 memset(&enc_param, 0, sizeof(enc_param));
321
322 mlvec = NULL;
323 memset(&mlvec_dy_cfg, 0, sizeof(mlvec_dy_cfg));
324
325 vpu_api_dbg_func("leave\n");
326 }
327
~VpuApiLegacy()328 VpuApiLegacy::~VpuApiLegacy()
329 {
330 vpu_api_dbg_func("enter\n");
331
332 mpp_frame_deinit(&frm_info);
333 mpp_destroy(mpp_ctx);
334
335 if (memGroup) {
336 mpp_buffer_group_put(memGroup);
337 memGroup = NULL;
338 }
339
340 if (enc_cfg) {
341 mpp_enc_cfg_deinit(enc_cfg);
342 enc_cfg = NULL;
343 }
344
345 if (mlvec) {
346 vpu_api_mlvec_deinit(mlvec);
347 mlvec = NULL;
348 }
349
350 if (enc_hdr_pkt) {
351 mpp_packet_deinit(&enc_hdr_pkt);
352 enc_hdr_pkt = NULL;
353 }
354 MPP_FREE(enc_hdr_buf);
355 enc_hdr_buf_size = 0;
356
357 vpu_api_dbg_func("leave\n");
358 }
359
init_frame_info(VpuCodecContext * ctx,MppCtx mpp_ctx,MppApi * mpi,MppFrame frame_info,VPU_GENERIC * p)360 static RK_S32 init_frame_info(VpuCodecContext *ctx, MppCtx mpp_ctx, MppApi *mpi,
361 MppFrame frame_info, VPU_GENERIC *p)
362 {
363 RK_S32 ret = -1;
364 RK_U32 fbcOutFmt = 0;
365
366 if (ctx->private_data)
367 fbcOutFmt = *(RK_U32 *)ctx->private_data;
368
369 if (ctx->extra_cfg.bit_depth
370 || ctx->extra_cfg.yuv_format) {
371 if (ctx->extra_cfg.bit_depth == 10)
372 p->CodecType = (ctx->extra_cfg.yuv_format == 1)
373 ? MPP_FMT_YUV422SP_10BIT : MPP_FMT_YUV420SP_10BIT;
374 else
375 p->CodecType = (ctx->extra_cfg.yuv_format == 1)
376 ? MPP_FMT_YUV422SP : MPP_FMT_YUV420SP;
377 } else {
378 /**hightest of p->ImgWidth bit show current dec bitdepth
379 * 0 - 8bit
380 * 1 - 10bit
381 **/
382 if (p->ImgWidth & 0x80000000)
383 p->CodecType = (p->ImgWidth & 0x40000000)
384 ? MPP_FMT_YUV422SP_10BIT : MPP_FMT_YUV420SP_10BIT;
385 else
386 p->CodecType = (p->ImgWidth & 0x40000000)
387 ? MPP_FMT_YUV422SP : MPP_FMT_YUV420SP;
388 }
389 p->ImgWidth = (p->ImgWidth & 0xFFFF);
390
391 mpp_frame_set_width(frame_info, p->ImgWidth);
392 mpp_frame_set_height(frame_info, p->ImgHeight);
393 mpp_frame_set_fmt(frame_info, (MppFrameFormat)(p->CodecType | fbcOutFmt));
394
395 ret = mpi->control(mpp_ctx, MPP_DEC_SET_FRAME_INFO, (MppParam)frame_info);
396 /* output the parameters used */
397 p->ImgHorStride = mpp_frame_get_hor_stride(frame_info);
398 p->ImgVerStride = mpp_frame_get_ver_stride(frame_info);
399 p->BufSize = mpp_frame_get_buf_size(frame_info);
400
401 return ret;
402 }
403
404
init(VpuCodecContext * ctx,RK_U8 * extraData,RK_U32 extra_size)405 RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size)
406 {
407 vpu_api_dbg_func("enter\n");
408
409 MPP_RET ret = MPP_OK;
410 MppCtxType type;
411
412 if (mpp_ctx == NULL || mpi == NULL) {
413 mpp_err("found invalid context input");
414 return MPP_ERR_NULL_PTR;
415 }
416
417 if (CODEC_DECODER == ctx->codecType) {
418 type = MPP_CTX_DEC;
419 } else if (CODEC_ENCODER == ctx->codecType) {
420 type = MPP_CTX_ENC;
421 } else {
422 mpp_err("found invalid codec type %d\n", ctx->codecType);
423 return MPP_ERR_VPU_CODEC_INIT;
424 }
425
426 ret = mpp_init(mpp_ctx, type, (MppCodingType)ctx->videoCoding);
427 if (ret) {
428 mpp_err_f(" init error. \n");
429 return ret;
430 }
431
432 if (MPP_CTX_ENC == type) {
433 EncParameter_t *param = (EncParameter_t*)ctx->private_data;
434 MppCodingType coding = (MppCodingType)ctx->videoCoding;
435 MppPollType block = (MppPollType)VPU_API_ENC_INPUT_TIMEOUT;
436 MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_DISABLE;
437
438 /* setup input / output block mode */
439 ret = mpi->control(mpp_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block);
440 if (MPP_OK != ret)
441 mpp_err("mpi control MPP_SET_INPUT_TIMEOUT failed\n");
442
443 /* disable sei by default */
444 ret = mpi->control(mpp_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode);
445 if (ret)
446 mpp_err("mpi control MPP_ENC_SET_SEI_CFG failed ret %d\n", ret);
447
448 if (memGroup == NULL) {
449 ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_ION);
450 if (ret) {
451 mpp_err("memGroup mpp_buffer_group_get failed %d\n", ret);
452 return ret;
453 }
454 }
455
456 ret = mpp_enc_cfg_init(&enc_cfg);
457 if (ret) {
458 mpp_err("mpp_enc_cfg_init failed %d\n", ret);
459 mpp_buffer_group_put(memGroup);
460 memGroup = NULL;
461 return ret;
462 }
463
464 format = vpu_pic_type_remap_to_mpp((EncInputPictureType)param->format);
465
466 memcpy(&enc_param, param, sizeof(enc_param));
467
468 if (MPP_OK == vpu_api_mlvec_check_cfg(param)) {
469 if (NULL == mlvec) {
470 vpu_api_mlvec_init(&mlvec);
471 vpu_api_mlvec_setup(mlvec, mpp_ctx, mpi, enc_cfg);
472 }
473 }
474
475 if (mlvec)
476 vpu_api_mlvec_set_st_cfg(mlvec, (VpuApiMlvecStaticCfg *)param);
477
478 vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, param);
479
480 if (!mlvec) {
481 if (NULL == enc_hdr_pkt) {
482 if (NULL == enc_hdr_buf) {
483 enc_hdr_buf_size = SZ_1K;
484 enc_hdr_buf = mpp_calloc_size(RK_U8, enc_hdr_buf_size);
485 }
486
487 if (enc_hdr_buf)
488 mpp_packet_init(&enc_hdr_pkt, enc_hdr_buf, enc_hdr_buf_size);
489 }
490
491 mpp_assert(enc_hdr_pkt);
492 if (enc_hdr_pkt) {
493 ret = mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, enc_hdr_pkt);
494 ctx->extradata_size = mpp_packet_get_length(enc_hdr_pkt);
495 ctx->extradata = mpp_packet_get_data(enc_hdr_pkt);
496 }
497 }
498 } else { /* MPP_CTX_DEC */
499 vpug.CodecType = ctx->codecType;
500 vpug.ImgWidth = ctx->width;
501 vpug.ImgHeight = ctx->height;
502
503 init_frame_info(ctx, mpp_ctx, mpi, frm_info, &vpug);
504
505 if (extraData != NULL) {
506 MppPacket pkt = NULL;
507
508 mpp_packet_init(&pkt, extraData, extra_size);
509 mpp_packet_set_extra_data(pkt);
510 mpi->decode_put_packet(mpp_ctx, pkt);
511 mpp_packet_deinit(&pkt);
512 }
513
514 RK_U32 flag = 0;
515 ret = mpi->control(mpp_ctx, MPP_DEC_SET_ENABLE_DEINTERLACE, &flag);
516 if (ret)
517 mpp_err_f("disable mpp deinterlace failed ret %d\n", ret);
518 }
519
520 init_ok = 1;
521
522 vpu_api_dbg_func("leave\n");
523 return ret;
524 }
525
flush(VpuCodecContext * ctx)526 RK_S32 VpuApiLegacy::flush(VpuCodecContext *ctx)
527 {
528 (void)ctx;
529 vpu_api_dbg_func("enter\n");
530 if (mpi && mpi->reset && init_ok) {
531 mpi->reset(mpp_ctx);
532 set_eos = 0;
533 mEosSet = 0;
534 }
535 vpu_api_dbg_func("leave\n");
536 return 0;
537 }
538
setup_VPU_FRAME_from_mpp_frame(VpuCodecContext * ctx,VPU_FRAME * vframe,MppFrame mframe)539 static void setup_VPU_FRAME_from_mpp_frame(VpuCodecContext *ctx, VPU_FRAME *vframe, MppFrame mframe)
540 {
541 MppBuffer buf = mpp_frame_get_buffer(mframe);
542 RK_U64 pts = mpp_frame_get_pts(mframe);
543 RK_U32 mode = mpp_frame_get_mode(mframe);
544
545 MppFrameColorRange colorRan = mpp_frame_get_color_range(mframe);
546 MppFrameColorTransferCharacteristic colorTrc = mpp_frame_get_color_trc(mframe);
547 MppFrameColorPrimaries colorPri = mpp_frame_get_color_primaries(mframe);
548 MppFrameColorSpace colorSpa = mpp_frame_get_colorspace(mframe);
549
550 if (buf)
551 mpp_buffer_inc_ref(buf);
552
553 vframe->CodingType = ctx->videoCoding;
554 vframe->DisplayWidth = mpp_frame_get_width(mframe);
555 vframe->DisplayHeight = mpp_frame_get_height(mframe);
556 vframe->FrameWidth = mpp_frame_get_hor_stride(mframe);
557 vframe->FrameHeight = mpp_frame_get_ver_stride(mframe);
558
559 vframe->ColorRange = (colorRan == MPP_FRAME_RANGE_JPEG);
560 vframe->ColorPrimaries = colorPri;
561 vframe->ColorTransfer = colorTrc;
562 vframe->ColorCoeffs = colorSpa;
563
564 if (mode == MPP_FRAME_FLAG_FRAME)
565 vframe->FrameType = 0;
566 else {
567 RK_U32 field_order = mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK;
568 if (field_order == MPP_FRAME_FLAG_TOP_FIRST)
569 vframe->FrameType = 1;
570 else if (field_order == MPP_FRAME_FLAG_BOT_FIRST)
571 vframe->FrameType = 2;
572 else if (field_order == MPP_FRAME_FLAG_DEINTERLACED)
573 vframe->FrameType = 4;
574 }
575 vframe->ErrorInfo = mpp_frame_get_errinfo(mframe) | mpp_frame_get_discard(mframe);
576 vframe->ShowTime.TimeHigh = (RK_U32)(pts >> 32);
577 vframe->ShowTime.TimeLow = (RK_U32)pts;
578 switch (mpp_frame_get_fmt(mframe) & MPP_FRAME_FMT_MASK) {
579 case MPP_FMT_YUV420SP: {
580 vframe->ColorType = VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR;
581 vframe->OutputWidth = 0x20;
582 } break;
583 case MPP_FMT_YUV420SP_10BIT: {
584 vframe->ColorType = VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR;
585 vframe->ColorType |= VPU_OUTPUT_FORMAT_BIT_10;
586 vframe->OutputWidth = 0x22;
587 } break;
588 case MPP_FMT_YUV422SP: {
589 vframe->ColorType = VPU_OUTPUT_FORMAT_YUV422;
590 vframe->OutputWidth = 0x10;
591 } break;
592 case MPP_FMT_YUV422SP_10BIT: {
593 vframe->ColorType = VPU_OUTPUT_FORMAT_YUV422;
594 vframe->ColorType |= VPU_OUTPUT_FORMAT_BIT_10;
595 vframe->OutputWidth = 0x23;
596 } break;
597 case MPP_FMT_YUV444SP: {
598 vframe->ColorType = VPU_OUTPUT_FORMAT_YUV444;
599 vframe->OutputWidth = 0x11;
600 } break;
601 default: {
602 } break;
603 }
604
605 switch (mpp_frame_get_fmt(mframe) & MPP_FRAME_FBC_MASK) {
606 case MPP_FRAME_FBC_AFBC_V1: {
607 vframe->ColorType |= VPU_OUTPUT_FORMAT_FBC_AFBC_V1;
608 } break;
609 case MPP_FRAME_FBC_AFBC_V2: {
610 vframe->ColorType |= VPU_OUTPUT_FORMAT_FBC_AFBC_V2;
611 } break;
612 default: {
613 } break;
614 }
615
616 switch (colorTrc) {
617 case MPP_FRAME_TRC_SMPTEST2084: {
618 vframe->ColorType |= VPU_OUTPUT_FORMAT_DYNCRANGE_HDR10; //HDR10
619 } break;
620 case MPP_FRAME_TRC_ARIB_STD_B67: {
621 vframe->ColorType |= VPU_OUTPUT_FORMAT_DYNCRANGE_HDR_HLG; //HDR_HLG
622 } break;
623 default: {
624 } break;
625 }
626
627 if (buf) {
628 MppBufferImpl *p = (MppBufferImpl*)buf;
629 void *ptr = (p->mode == MPP_BUFFER_INTERNAL) ?
630 mpp_buffer_get_ptr(buf) : NULL;
631 RK_S32 fd = mpp_buffer_get_fd(buf);
632
633 vframe->FrameBusAddr[0] = fd;
634 vframe->FrameBusAddr[1] = fd;
635 vframe->vpumem.vir_addr = (RK_U32*)ptr;
636 vframe->vpumem.phy_addr = fd;
637
638 vframe->vpumem.size = vframe->FrameWidth * vframe->FrameHeight * 3 / 2;
639 vframe->vpumem.offset = (RK_U32*)buf;
640 }
641 }
642
setup_video_frame_meta(VideoFrame_t * videoFrame,MppFrame mframe)643 static void setup_video_frame_meta(VideoFrame_t *videoFrame, MppFrame mframe)
644 {
645 if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_MIXED) {
646 MppMeta meta = NULL;
647 RK_S32 yOffset = 0;
648 RK_S32 uvOffset = 0;
649
650 meta = mpp_frame_get_meta(mframe);
651 mpp_meta_get_s32(meta, KEY_DEC_TBN_Y_OFFSET, &yOffset);
652 mpp_meta_get_s32(meta, KEY_DEC_TBN_UV_OFFSET, &uvOffset);
653 if (yOffset && uvOffset) {
654 videoFrame->thumbInfo.enable = 1;
655 videoFrame->thumbInfo.yOffset = yOffset;
656 videoFrame->thumbInfo.uvOffset = uvOffset;
657 } else {
658 videoFrame->thumbInfo.enable = 0;
659 }
660 }
661
662 if (MPP_FRAME_FMT_IS_HDR(mpp_frame_get_fmt(mframe))) {
663 MppMeta meta = NULL;
664 RK_S32 offset = 0;
665 RK_S32 size = 0;
666
667 meta = mpp_frame_get_meta(mframe);
668 mpp_meta_get_s32(meta, KEY_HDR_META_OFFSET, &offset);
669 mpp_meta_get_s32(meta, KEY_HDR_META_SIZE, &size);
670 videoFrame->hdrInfo.isHdr = 1;
671 videoFrame->hdrInfo.offset = offset;
672 videoFrame->hdrInfo.size = size;
673 }
674
675 videoFrame->viewId = mpp_frame_get_viewid(mframe);
676 }
677
decode(VpuCodecContext * ctx,VideoPacket_t * pkt,DecoderOut_t * aDecOut)678 RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
679 {
680 MPP_RET ret = MPP_OK;
681 MppFrame mframe = NULL;
682 MppPacket packet = NULL;
683
684 vpu_api_dbg_func("enter\n");
685
686 if (ctx->videoCoding == OMX_RK_VIDEO_CodingMJPEG) {
687 MppTask task = NULL;
688
689 if (!init_ok) {
690 mpp_err("init failed!\n");
691 return VPU_API_ERR_VPU_CODEC_INIT;
692 }
693
694 /* check input param */
695 if (!pkt || !aDecOut) {
696 mpp_err("invalid input %p and output %p\n", pkt, aDecOut);
697 return VPU_API_ERR_UNKNOW;
698 }
699
700 if (pkt->size <= 0) {
701 mpp_err("invalid input size %d\n", pkt->size);
702 return VPU_API_ERR_UNKNOW;
703 }
704
705 /* try import input buffer and output buffer */
706 RK_S32 fd = -1;
707 RK_U32 width = ctx->width;
708 RK_U32 height = ctx->height;
709 RK_U32 hor_stride = MPP_ALIGN(width, 16);
710 RK_U32 ver_stride = MPP_ALIGN(height, 16);
711 MppBuffer str_buf = NULL; /* input */
712 MppBuffer pic_buf = NULL; /* output */
713
714 ret = mpp_frame_init(&mframe);
715 if (MPP_OK != ret) {
716 mpp_err_f("mpp_frame_init failed\n");
717 goto DECODE_OUT;
718 }
719
720 fd = (RK_S32)(pkt->pts & 0xffffffff);
721 if (fd_input < 0) {
722 fd_input = is_valid_dma_fd(fd);
723 }
724
725 if (fd_input) {
726 MppBufferInfo inputCommit;
727
728 memset(&inputCommit, 0, sizeof(inputCommit));
729 inputCommit.type = MPP_BUFFER_TYPE_ION;
730 inputCommit.size = pkt->size;
731 inputCommit.fd = fd;
732
733 ret = mpp_buffer_import(&str_buf, &inputCommit);
734 if (ret) {
735 mpp_err_f("import input picture buffer failed\n");
736 goto DECODE_OUT;
737 }
738 } else {
739 if (NULL == pkt->data) {
740 ret = MPP_ERR_NULL_PTR;
741 goto DECODE_OUT;
742 }
743
744 ret = mpp_buffer_get(memGroup, &str_buf, pkt->size);
745 if (ret) {
746 mpp_err_f("allocate input picture buffer failed\n");
747 goto DECODE_OUT;
748 }
749 memcpy((RK_U8*) mpp_buffer_get_ptr(str_buf), pkt->data, pkt->size);
750 }
751
752 fd = (RK_S32)(aDecOut->timeUs & 0xffffffff);
753 if (fd_output < 0) {
754 fd_output = is_valid_dma_fd(fd);
755 }
756
757 if (fd_output) {
758 MppBufferInfo outputCommit;
759
760 memset(&outputCommit, 0, sizeof(outputCommit));
761 /* in order to avoid interface change use space in output to transmit information */
762 outputCommit.type = MPP_BUFFER_TYPE_ION;
763 outputCommit.fd = fd;
764 outputCommit.size = width * height * 3 / 2;
765 outputCommit.ptr = (void*)aDecOut->data;
766
767 ret = mpp_buffer_import(&pic_buf, &outputCommit);
768 if (ret) {
769 mpp_err_f("import output stream buffer failed\n");
770 goto DECODE_OUT;
771 }
772 } else {
773 ret = mpp_buffer_get(memGroup, &pic_buf, hor_stride * ver_stride * 3 / 2);
774 if (ret) {
775 mpp_err_f("allocate output stream buffer failed\n");
776 goto DECODE_OUT;
777 }
778 }
779
780 mpp_packet_init_with_buffer(&packet, str_buf); /* input */
781 mpp_frame_set_buffer(mframe, pic_buf); /* output */
782
783 vpu_api_dbg_func("mpp import input fd %d output fd %d",
784 mpp_buffer_get_fd(str_buf), mpp_buffer_get_fd(pic_buf));
785
786 ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
787 if (ret) {
788 mpp_err("mpp input poll failed\n");
789 goto DECODE_OUT;
790 }
791
792 ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
793 if (ret) {
794 mpp_err("mpp task input dequeue failed\n");
795 goto DECODE_OUT;
796 }
797
798 mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
799 mpp_task_meta_set_frame (task, KEY_OUTPUT_FRAME, mframe);
800
801 ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
802 if (ret) {
803 mpp_err("mpp task input enqueue failed\n");
804 goto DECODE_OUT;
805 }
806
807 pkt->size = 0;
808 task = NULL;
809
810 ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
811 if (ret) {
812 mpp_err("mpp output poll failed\n");
813 goto DECODE_OUT;
814 }
815
816 ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
817 if (ret) {
818 mpp_err("ret %d mpp task output dequeue failed\n", ret);
819 goto DECODE_OUT;
820 }
821
822 if (task) {
823 MppFrame frame_out = NULL;
824
825 mpp_task_meta_get_frame(task, KEY_OUTPUT_FRAME, &frame_out);
826 mpp_assert(frame_out == mframe);
827 vpu_api_dbg_func("decoded frame %d\n", frame_count);
828 frame_count++;
829
830 ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
831 if (ret) {
832 mpp_err("mpp task output enqueue failed\n");
833 goto DECODE_OUT;
834 }
835 task = NULL;
836 }
837
838 // copy decoded frame into output buffer, and set outpub frame size
839 if (mframe != NULL) {
840 MppBuffer buf_out = mpp_frame_get_buffer(mframe);
841 size_t len = mpp_buffer_get_size(buf_out);
842 aDecOut->size = len;
843
844 if (fd_output) {
845 mpp_log_f("fd for output is invalid!\n");
846 // TODO: check frame format and allocate correct buffer
847 aDecOut->data = mpp_malloc(RK_U8, width * height * 3 / 2);
848 memcpy(aDecOut->data, (RK_U8*) mpp_buffer_get_ptr(pic_buf), aDecOut->size);
849 }
850
851 vpu_api_dbg_func("get frame %p size %d\n", mframe, len);
852
853 mpp_frame_deinit(&mframe);
854 } else {
855 mpp_log("outputPacket is NULL!");
856 }
857
858 DECODE_OUT:
859 if (str_buf) {
860 mpp_buffer_put(str_buf);
861 str_buf = NULL;
862 }
863
864 if (pic_buf) {
865 mpp_buffer_put(pic_buf);
866 pic_buf = NULL;
867 }
868 } else {
869 mpp_packet_init(&packet, pkt->data, pkt->size);
870 mpp_packet_set_pts(packet, pkt->pts);
871 if (pkt->nFlags & OMX_BUFFERFLAG_EOS) {
872 mpp_packet_set_eos(packet);
873 }
874
875 vpu_api_dbg_input("input size %-6d flag %x pts %lld\n",
876 pkt->size, pkt->nFlags, pkt->pts);
877
878 ret = mpi->decode(mpp_ctx, packet, &mframe);
879 if (MPP_OK == ret) {
880 pkt->size = 0;
881 }
882 if (ret || NULL == mframe) {
883 aDecOut->size = 0;
884 } else {
885 VPU_FRAME *vframe = NULL;
886 MppBuffer buf = mpp_frame_get_buffer(mframe);
887
888 if (dec_out_frm_struct_type) {
889 VideoFrame_t *videoFrame = (VideoFrame_t *)aDecOut->data;
890 vframe = &videoFrame->vpuFrame;
891 memset(videoFrame, 0, sizeof(VideoFrame_t));
892 aDecOut->size = sizeof(VideoFrame_t);
893 setup_video_frame_meta(videoFrame, mframe);
894 } else {
895 vframe = (VPU_FRAME *)aDecOut->data;
896 memset(vframe, 0, sizeof(VPU_FRAME));
897 aDecOut->size = sizeof(VPU_FRAME);
898 }
899
900 setup_VPU_FRAME_from_mpp_frame(ctx, vframe, mframe);
901
902 aDecOut->timeUs = mpp_frame_get_pts(mframe);
903 frame_count++;
904
905 if (mpp_frame_get_eos(mframe)) {
906 set_eos = 1;
907 if (buf == NULL) {
908 aDecOut->size = 0;
909 }
910 }
911 if (vpu_api_debug & VPU_API_DBG_OUTPUT) {
912 mpp_log("get one frame pts %lld, fd 0x%x, poc %d, errinfo %x, discard %d, eos %d, verr %d",
913 aDecOut->timeUs,
914 ((buf) ? (mpp_buffer_get_fd(buf)) : (-1)),
915 mpp_frame_get_poc(mframe),
916 mpp_frame_get_errinfo(mframe),
917 mpp_frame_get_discard(mframe),
918 mpp_frame_get_eos(mframe), vframe->ErrorInfo);
919 }
920
921 /*
922 * IMPORTANT: mframe is malloced from mpi->decode_get_frame
923 * So we need to deinit mframe here. But the buffer in the frame should not be free with mframe.
924 * Because buffer need to be set to vframe->vpumem.offset and send to display.
925 * The we have to clear the buffer pointer in mframe then release mframe.
926 */
927 mpp_frame_deinit(&mframe);
928 }
929 }
930
931 if (packet)
932 mpp_packet_deinit(&packet);
933
934 if (mframe)
935 mpp_frame_deinit(&mframe);
936
937 vpu_api_dbg_func("leave ret %d\n", ret);
938 return ret;
939 }
940
decode_sendstream(VideoPacket_t * pkt)941 RK_S32 VpuApiLegacy::decode_sendstream(VideoPacket_t *pkt)
942 {
943 vpu_api_dbg_func("enter\n");
944
945 RK_S32 ret = MPP_OK;
946 MppPacket mpkt = NULL;
947
948 if (!init_ok) {
949 return VPU_API_ERR_VPU_CODEC_INIT;
950 }
951
952 mpp_packet_init(&mpkt, pkt->data, pkt->size);
953 mpp_packet_set_pts(mpkt, pkt->pts);
954 if (pkt->nFlags & OMX_BUFFERFLAG_EOS) {
955 mpp_packet_set_eos(mpkt);
956 }
957
958 vpu_api_dbg_input("input size %-6d flag %x pts %lld\n",
959 pkt->size, pkt->nFlags, pkt->pts);
960
961 ret = mpi->decode_put_packet(mpp_ctx, mpkt);
962 if (ret == MPP_OK) {
963 pkt->size = 0;
964 } else if (mInputTimeOutMs == 0) {
965 /* reduce cpu overhead here */
966 msleep(1);
967 }
968
969 mpp_packet_deinit(&mpkt);
970
971 vpu_api_dbg_func("leave ret %d\n", ret);
972 /* NOTE: always return success for old player compatibility */
973 return MPP_OK;
974 }
975
decode_getoutframe(VpuCodecContext * ctx,DecoderOut_t * aDecOut)976 RK_S32 VpuApiLegacy::decode_getoutframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut)
977 {
978 RK_S32 ret = 0;
979 VPU_FRAME *vframe = NULL;
980 MppFrame mframe = NULL;
981
982 vpu_api_dbg_func("enter\n");
983
984 if (!init_ok) {
985 return VPU_API_ERR_VPU_CODEC_INIT;
986 }
987
988 if (NULL == mpi) {
989 aDecOut->size = 0;
990 return 0;
991 }
992
993 if (set_eos) {
994 aDecOut->size = 0;
995 mEosSet = 1;
996 return VPU_API_EOS_STREAM_REACHED;
997 }
998
999 ret = mpi->decode_get_frame(mpp_ctx, &mframe);
1000 if (ret || NULL == mframe) {
1001 aDecOut->size = 0;
1002 } else {
1003 MppBuffer buf = mpp_frame_get_buffer(mframe);
1004
1005 if (dec_out_frm_struct_type) {
1006 VideoFrame_t *videoFrame = (VideoFrame_t *)aDecOut->data;
1007 vframe = &videoFrame->vpuFrame;
1008 memset(videoFrame, 0, sizeof(VideoFrame_t));
1009 aDecOut->size = sizeof(VideoFrame_t);
1010 setup_video_frame_meta(videoFrame, mframe);
1011 } else {
1012 vframe = (VPU_FRAME *)aDecOut->data;
1013 memset(vframe, 0, sizeof(VPU_FRAME));
1014 aDecOut->size = sizeof(VPU_FRAME);
1015 }
1016
1017 setup_VPU_FRAME_from_mpp_frame(ctx, vframe, mframe);
1018
1019 aDecOut->timeUs = mpp_frame_get_pts(mframe);
1020 frame_count++;
1021
1022 if (mpp_frame_get_eos(mframe) && !mpp_frame_get_info_change(mframe)) {
1023 set_eos = 1;
1024 if (buf == NULL) {
1025 aDecOut->size = 0;
1026 mEosSet = 1;
1027 ret = VPU_API_EOS_STREAM_REACHED;
1028 } else {
1029 aDecOut->nFlags |= VPU_API_EOS_STREAM_REACHED;
1030 }
1031 }
1032 if (vpu_api_debug & VPU_API_DBG_OUTPUT) {
1033 mpp_log("get one frame pts %lld, fd 0x%x, poc %d, errinfo %x, discard %d, eos %d, verr %d",
1034 aDecOut->timeUs,
1035 ((buf) ? (mpp_buffer_get_fd(buf)) : (-1)),
1036 mpp_frame_get_poc(mframe),
1037 mpp_frame_get_errinfo(mframe),
1038 mpp_frame_get_discard(mframe),
1039 mpp_frame_get_eos(mframe), vframe->ErrorInfo);
1040 }
1041
1042 /*
1043 * IMPORTANT: mframe is malloced from mpi->decode_get_frame
1044 * So we need to deinit mframe here. But the buffer in the frame should not be free with mframe.
1045 * Because buffer need to be set to vframe->vpumem.offset and send to display.
1046 * The we have to clear the buffer pointer in mframe then release mframe.
1047 */
1048 mpp_frame_deinit(&mframe);
1049 }
1050
1051 vpu_api_dbg_func("leave ret %d\n", ret);
1052
1053 return ret;
1054 }
1055
encode(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm,EncoderOut_t * aEncOut)1056 RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut)
1057 {
1058 MPP_RET ret = MPP_OK;
1059 MppTask task = NULL;
1060 vpu_api_dbg_func("enter\n");
1061
1062 if (!init_ok)
1063 return VPU_API_ERR_VPU_CODEC_INIT;
1064
1065 /* check input param */
1066 if (!aEncInStrm || !aEncOut) {
1067 mpp_err("invalid input %p and output %p\n", aEncInStrm, aEncOut);
1068 return VPU_API_ERR_UNKNOW;
1069 }
1070
1071 if (NULL == aEncInStrm->buf || 0 == aEncInStrm->size) {
1072 mpp_err("invalid input buffer %p size %d\n", aEncInStrm->buf, aEncInStrm->size);
1073 return VPU_API_ERR_UNKNOW;
1074 }
1075
1076 /* try import input buffer and output buffer */
1077 RK_S32 fd = -1;
1078 RK_U32 width = ctx->width;
1079 RK_U32 height = ctx->height;
1080 RK_U32 hor_stride = MPP_ALIGN(width, 16);
1081 RK_U32 ver_stride = MPP_ALIGN(height, 16);
1082 MppFrame frame = NULL;
1083 MppPacket packet = NULL;
1084 MppBuffer pic_buf = NULL;
1085 MppBuffer str_buf = NULL;
1086
1087 ret = mpp_frame_init(&frame);
1088 if (MPP_OK != ret) {
1089 mpp_err_f("mpp_frame_init failed\n");
1090 goto ENCODE_OUT;
1091 }
1092
1093 mpp_frame_set_width(frame, width);
1094 mpp_frame_set_height(frame, height);
1095 mpp_frame_set_ver_stride(frame, ver_stride);
1096 switch (format & MPP_FRAME_FMT_MASK) {
1097 case MPP_FMT_YUV420P :
1098 case MPP_FMT_YUV420SP :
1099 case MPP_FMT_YUV420SP_VU : {
1100 mpp_frame_set_hor_stride(frame, hor_stride);
1101 } break;
1102 case MPP_FMT_RGB565:
1103 case MPP_FMT_BGR565:
1104 case MPP_FMT_RGB555:
1105 case MPP_FMT_BGR555: {
1106 mpp_frame_set_hor_stride(frame, hor_stride * 2);
1107 } break;
1108 case MPP_FMT_RGB888 :
1109 case MPP_FMT_BGR888 : {
1110 mpp_frame_set_hor_stride(frame, hor_stride * 3);
1111 } break;
1112 case MPP_FMT_ARGB8888 :
1113 case MPP_FMT_ABGR8888 :
1114 case MPP_FMT_BGRA8888 :
1115 case MPP_FMT_RGBA8888 : {
1116 mpp_frame_set_hor_stride(frame, hor_stride * 4);
1117 } break;
1118 default: {
1119 mpp_err("unsupport format 0x%x\n", format & MPP_FRAME_FMT_MASK);
1120 } break;
1121 }
1122 mpp_frame_set_fmt(frame, (MppFrameFormat)(format & MPP_FRAME_FMT_MASK));
1123 if (aEncInStrm->nFlags) {
1124 mpp_log_f("found eos\n");
1125 mpp_frame_set_eos(frame, 1);
1126 }
1127
1128 fd = aEncInStrm->bufPhyAddr;
1129 if (fd_input < 0) {
1130 fd_input = is_valid_dma_fd(fd);
1131 }
1132 if (fd_input) {
1133 MppBufferInfo inputCommit;
1134
1135 memset(&inputCommit, 0, sizeof(inputCommit));
1136 inputCommit.type = MPP_BUFFER_TYPE_ION;
1137 inputCommit.size = aEncInStrm->size;
1138 inputCommit.fd = fd;
1139
1140 ret = mpp_buffer_import(&pic_buf, &inputCommit);
1141 if (ret) {
1142 mpp_err_f("import input picture buffer failed\n");
1143 goto ENCODE_OUT;
1144 }
1145 } else {
1146 if (NULL == aEncInStrm->buf) {
1147 ret = MPP_ERR_NULL_PTR;
1148 goto ENCODE_OUT;
1149 }
1150
1151 ret = mpp_buffer_get(memGroup, &pic_buf, aEncInStrm->size);
1152 if (ret) {
1153 mpp_err_f("allocate input picture buffer failed\n");
1154 goto ENCODE_OUT;
1155 }
1156 memcpy((RK_U8*) mpp_buffer_get_ptr(pic_buf), aEncInStrm->buf, aEncInStrm->size);
1157 }
1158
1159 fd = (RK_S32)(aEncOut->timeUs & 0xffffffff);
1160
1161 if (fd_output < 0) {
1162 fd_output = is_valid_dma_fd(fd);
1163 }
1164 if (fd_output) {
1165 RK_S32 *tmp = (RK_S32*)(&aEncOut->timeUs);
1166 MppBufferInfo outputCommit;
1167
1168 memset(&outputCommit, 0, sizeof(outputCommit));
1169 /* in order to avoid interface change use space in output to transmit information */
1170 outputCommit.type = MPP_BUFFER_TYPE_ION;
1171 outputCommit.fd = fd;
1172 outputCommit.size = tmp[1];
1173 outputCommit.ptr = (void*)aEncOut->data;
1174
1175 ret = mpp_buffer_import(&str_buf, &outputCommit);
1176 if (ret) {
1177 mpp_err_f("import output stream buffer failed\n");
1178 goto ENCODE_OUT;
1179 }
1180 } else {
1181 ret = mpp_buffer_get(memGroup, &str_buf, hor_stride * ver_stride);
1182 if (ret) {
1183 mpp_err_f("allocate output stream buffer failed\n");
1184 goto ENCODE_OUT;
1185 }
1186 }
1187
1188 mpp_frame_set_buffer(frame, pic_buf);
1189 mpp_packet_init_with_buffer(&packet, str_buf);
1190 mpp_packet_set_length(packet, 0);
1191
1192 vpu_api_dbg_func("mpp import input fd %d output fd %d",
1193 mpp_buffer_get_fd(pic_buf), mpp_buffer_get_fd(str_buf));
1194
1195 ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
1196 if (ret) {
1197 mpp_err("mpp input poll failed\n");
1198 goto ENCODE_OUT;
1199 }
1200
1201 ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
1202 if (ret) {
1203 mpp_err("mpp task input dequeue failed\n");
1204 goto ENCODE_OUT;
1205 }
1206 if (task == NULL) {
1207 mpp_err("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
1208 goto ENCODE_OUT;
1209 }
1210
1211 mpp_task_meta_set_frame (task, KEY_INPUT_FRAME, frame);
1212 mpp_task_meta_set_packet(task, KEY_OUTPUT_PACKET, packet);
1213
1214 ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
1215 if (ret) {
1216 mpp_err("mpp task input enqueue failed\n");
1217 goto ENCODE_OUT;
1218 }
1219 task = NULL;
1220
1221 ret = mpi->poll(mpp_ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
1222 if (ret) {
1223 mpp_err("mpp output poll failed\n");
1224 goto ENCODE_OUT;
1225 }
1226
1227 ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
1228 if (ret) {
1229 mpp_err("ret %d mpp task output dequeue failed\n", ret);
1230 goto ENCODE_OUT;
1231 }
1232
1233 mpp_assert(task);
1234
1235 if (task) {
1236 MppFrame frame_out = NULL;
1237 MppFrame packet_out = NULL;
1238
1239 mpp_task_meta_get_packet(task, KEY_OUTPUT_PACKET, &packet_out);
1240
1241 mpp_assert(packet_out == packet);
1242 vpu_api_dbg_func("encoded frame %d\n", frame_count);
1243 frame_count++;
1244
1245 ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
1246 if (ret) {
1247 mpp_err("mpp task output enqueue failed\n");
1248 goto ENCODE_OUT;
1249 }
1250 task = NULL;
1251
1252 ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
1253 if (ret) {
1254 mpp_err("mpp input poll failed\n");
1255 goto ENCODE_OUT;
1256 }
1257
1258 // dequeue task from MPP_PORT_INPUT
1259 ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
1260 if (ret) {
1261 mpp_log_f("failed to dequeue from input port ret %d\n", ret);
1262 goto ENCODE_OUT;
1263 }
1264 mpp_assert(task);
1265 ret = mpp_task_meta_get_frame(task, KEY_INPUT_FRAME, &frame_out);
1266 mpp_assert(frame_out == frame);
1267 ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
1268 if (ret) {
1269 mpp_err("mpp task output enqueue failed\n");
1270 goto ENCODE_OUT;
1271 }
1272 task = NULL;
1273 }
1274
1275 // copy encoded stream into output buffer, and set output stream size
1276 if (packet) {
1277 RK_U32 eos = mpp_packet_get_eos(packet);
1278 RK_S64 pts = mpp_packet_get_pts(packet);
1279 size_t length = mpp_packet_get_length(packet);
1280 MppMeta meta = mpp_packet_get_meta(packet);
1281 RK_S32 is_intra = 0;
1282
1283 if (!fd_output) {
1284 RK_U8 *src = (RK_U8 *)mpp_packet_get_data(packet);
1285 size_t buffer = MPP_ALIGN(length, SZ_4K);
1286
1287 aEncOut->data = mpp_malloc(RK_U8, buffer);
1288
1289 if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC) {
1290 // remove first 00 00 00 01
1291 length -= 4;
1292 memcpy(aEncOut->data, src + 4, length);
1293 } else {
1294 memcpy(aEncOut->data, src, length);
1295 }
1296 }
1297
1298 mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &is_intra);
1299
1300 aEncOut->size = (RK_S32)length;
1301 aEncOut->timeUs = pts;
1302 aEncOut->keyFrame = is_intra;
1303
1304 vpu_api_dbg_output("get packet %p size %d pts %lld keyframe %d eos %d\n",
1305 packet, length, pts, aEncOut->keyFrame, eos);
1306
1307 mpp_packet_deinit(&packet);
1308 } else {
1309 mpp_log("outputPacket is NULL!");
1310 }
1311
1312 ENCODE_OUT:
1313 if (pic_buf) {
1314 mpp_buffer_put(pic_buf);
1315 pic_buf = NULL;
1316 }
1317
1318 if (str_buf) {
1319 mpp_buffer_put(str_buf);
1320 str_buf = NULL;
1321 }
1322
1323 if (frame)
1324 mpp_frame_deinit(&frame);
1325
1326 if (packet)
1327 mpp_packet_deinit(&packet);
1328
1329 vpu_api_dbg_func("leave ret %d\n", ret);
1330
1331 return ret;
1332 }
1333
encoder_sendframe(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm)1334 RK_S32 VpuApiLegacy::encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm)
1335 {
1336 RK_S32 ret = 0;
1337 vpu_api_dbg_func("enter\n");
1338
1339 RK_U32 width = ctx->width;
1340 RK_U32 height = ctx->height;
1341 RK_U32 hor_stride = MPP_ALIGN(width, 16);
1342 RK_U32 ver_stride = MPP_ALIGN(height, 8);
1343 RK_S64 pts = aEncInStrm->timeUs;
1344 RK_S32 fd = aEncInStrm->bufPhyAddr;
1345 RK_U32 size = aEncInStrm->size;
1346
1347 /* try import input buffer and output buffer */
1348 MppFrame frame = NULL;
1349
1350 ret = mpp_frame_init(&frame);
1351 if (MPP_OK != ret) {
1352 mpp_err_f("mpp_frame_init failed\n");
1353 goto FUNC_RET;
1354 }
1355
1356 mpp_frame_set_width(frame, width);
1357 mpp_frame_set_height(frame, height);
1358 mpp_frame_set_ver_stride(frame, ver_stride);
1359 mpp_frame_set_pts(frame, pts);
1360 switch (format & MPP_FRAME_FMT_MASK) {
1361 case MPP_FMT_YUV420P :
1362 case MPP_FMT_YUV420SP :
1363 case MPP_FMT_YUV420SP_VU : {
1364 mpp_frame_set_hor_stride(frame, hor_stride);
1365 } break;
1366 case MPP_FMT_RGB565:
1367 case MPP_FMT_BGR565:
1368 case MPP_FMT_RGB555:
1369 case MPP_FMT_BGR555: {
1370 mpp_frame_set_hor_stride(frame, hor_stride * 2);
1371 } break;
1372 case MPP_FMT_RGB888 :
1373 case MPP_FMT_BGR888 : {
1374 mpp_frame_set_hor_stride(frame, hor_stride * 3);
1375 } break;
1376 case MPP_FMT_ARGB8888 :
1377 case MPP_FMT_ABGR8888 :
1378 case MPP_FMT_BGRA8888 :
1379 case MPP_FMT_RGBA8888 : {
1380 mpp_frame_set_hor_stride(frame, hor_stride * 4);
1381 } break;
1382 default: {
1383 mpp_err("unsupport format 0x%x\n", format & MPP_FRAME_FMT_MASK);
1384 } break;
1385 }
1386 mpp_frame_set_fmt(frame, (MppFrameFormat)(format & MPP_FRAME_FMT_MASK));
1387 if (aEncInStrm->nFlags) {
1388 mpp_log_f("found eos true\n");
1389 mpp_frame_set_eos(frame, 1);
1390 }
1391
1392 if (size <= 0) {
1393 mpp_frame_set_buffer(frame, NULL);
1394 if (!aEncInStrm->nFlags)
1395 mpp_err_f("found empty frame without eos flag set!\n");
1396 goto PUT_FRAME;
1397 }
1398
1399 if (fd_input < 0) {
1400 fd_input = is_valid_dma_fd(fd);
1401 }
1402 if (fd_input) {
1403 MppBufferInfo inputCommit;
1404
1405 memset(&inputCommit, 0, sizeof(inputCommit));
1406 inputCommit.type = MPP_BUFFER_TYPE_ION;
1407 inputCommit.size = size;
1408 inputCommit.fd = fd;
1409 if (size > 0) {
1410 MppBuffer buffer = NULL;
1411 ret = mpp_buffer_import(&buffer, &inputCommit);
1412 if (ret) {
1413 mpp_err_f("import input picture buffer failed\n");
1414 goto FUNC_RET;
1415 }
1416 mpp_frame_set_buffer(frame, buffer);
1417 mpp_buffer_put(buffer);
1418 buffer = NULL;
1419 }
1420 } else {
1421 RK_U32 align_size = 0;
1422
1423 if (NULL == aEncInStrm->buf) {
1424 ret = MPP_ERR_NULL_PTR;
1425 goto FUNC_RET;
1426 }
1427 if (format >= MPP_FMT_YUV420SP && format < MPP_FMT_YUV_BUTT) {
1428 align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 3 / 2;
1429 } else if (format >= MPP_FMT_YUV420SP_VU && format < MPP_FMT_YUV_BUTT) {
1430 align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 3 / 2;
1431 } else if (format >= MPP_FMT_RGB565 && format < MPP_FMT_BGR888) {
1432 align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 3;
1433 } else if (format >= MPP_FMT_RGB101010 && format < MPP_FMT_RGB_BUTT) {
1434 align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 4;
1435 } else {
1436 mpp_err_f("unsupport input format:%d\n", format);
1437 ret = MPP_NOK;
1438 goto FUNC_RET;
1439 }
1440 if (align_size > 0) {
1441 MppBuffer buffer = NULL;
1442 ret = mpp_buffer_get(memGroup, &buffer, align_size);
1443 if (ret) {
1444 mpp_err_f("allocate input picture buffer failed\n");
1445 goto FUNC_RET;
1446 }
1447 copy_align_raw_buffer_to_dest((RK_U8 *)mpp_buffer_get_ptr(buffer),
1448 aEncInStrm->buf, width, height, format);
1449 mpp_frame_set_buffer(frame, buffer);
1450 mpp_buffer_put(buffer);
1451 buffer = NULL;
1452 }
1453 }
1454
1455 PUT_FRAME:
1456
1457 vpu_api_dbg_input("w %d h %d input fd %d size %d pts %lld, flag %d \n",
1458 width, height, fd, size, aEncInStrm->timeUs, aEncInStrm->nFlags);
1459 if (mlvec) {
1460 MppMeta meta = mpp_frame_get_meta(frame);
1461
1462 vpu_api_mlvec_set_dy_cfg(mlvec, &mlvec_dy_cfg, meta);
1463 }
1464
1465 ret = mpi->encode_put_frame(mpp_ctx, frame);
1466 if (ret)
1467 mpp_err_f("encode_put_frame ret %d\n", ret);
1468 else
1469 aEncInStrm->size = 0;
1470
1471 FUNC_RET:
1472 if (frame)
1473 mpp_frame_deinit(&frame);
1474
1475 vpu_api_dbg_func("leave ret %d\n", ret);
1476 return ret;
1477 }
1478
encoder_getstream(VpuCodecContext * ctx,EncoderOut_t * aEncOut)1479 RK_S32 VpuApiLegacy::encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut)
1480 {
1481 RK_S32 ret = 0;
1482 MppPacket packet = NULL;
1483 vpu_api_dbg_func("enter\n");
1484
1485 ret = mpi->encode_get_packet(mpp_ctx, &packet);
1486 if (ret) {
1487 mpp_err_f("encode_get_packet failed ret %d\n", ret);
1488 goto FUNC_RET;
1489 }
1490 if (packet) {
1491 RK_U8 *src = (RK_U8 *)mpp_packet_get_data(packet);
1492 RK_U32 eos = mpp_packet_get_eos(packet);
1493 RK_S64 pts = mpp_packet_get_pts(packet);
1494 size_t length = mpp_packet_get_length(packet);
1495 MppMeta meta = mpp_packet_get_meta(packet);
1496 RK_S32 is_intra = 0;
1497
1498 RK_U32 offset = 0;
1499 if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC) {
1500 offset = 4;
1501 length = (length > offset) ? (length - offset) : 0;
1502 }
1503 aEncOut->data = NULL;
1504 if (length > 0) {
1505 aEncOut->data = mpp_calloc(RK_U8, MPP_ALIGN(length + 16, SZ_4K));
1506 if (aEncOut->data)
1507 memcpy(aEncOut->data, src + offset, length);
1508 }
1509
1510 mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &is_intra);
1511
1512 aEncOut->size = (RK_S32)length;
1513 aEncOut->timeUs = pts;
1514 aEncOut->keyFrame = is_intra;
1515
1516 vpu_api_dbg_output("get packet %p size %d pts %lld keyframe %d eos %d\n",
1517 packet, length, pts, aEncOut->keyFrame, eos);
1518
1519 mEosSet = eos;
1520 mpp_packet_deinit(&packet);
1521 } else {
1522 aEncOut->size = 0;
1523 vpu_api_dbg_output("get NULL packet, eos %d\n", mEosSet);
1524 if (mEosSet)
1525 ret = -1;
1526 }
1527
1528 FUNC_RET:
1529 vpu_api_dbg_func("leave ret %d\n", ret);
1530 return ret;
1531 }
1532
perform(PerformCmd cmd,RK_S32 * data)1533 RK_S32 VpuApiLegacy::perform(PerformCmd cmd, RK_S32 *data)
1534 {
1535 vpu_api_dbg_func("enter\n");
1536 switch (cmd) {
1537 case INPUT_FORMAT_MAP : {
1538 EncInputPictureType vpu_frame_fmt = *(EncInputPictureType *)data;
1539 MppFrameFormat mpp_frame_fmt = vpu_pic_type_remap_to_mpp(vpu_frame_fmt);
1540 *(MppFrameFormat *)data = mpp_frame_fmt;
1541 } break;
1542 default:
1543 mpp_err("cmd can not match with any option!");
1544 break;
1545 }
1546 vpu_api_dbg_func("leave\n");
1547 return 0;
1548 }
1549
frameReadyCallback(void * ctx,void * mppCtx,RK_S32 cmd,void * mppFrame)1550 static RK_S32 frameReadyCallback(void *ctx, void *mppCtx, RK_S32 cmd, void *mppFrame)
1551 {
1552 (void)mppCtx;
1553 (void)cmd;
1554 (void)mppFrame;
1555 VpuApiLegacy *vpuApi = (VpuApiLegacy *)ctx;
1556 RK_S32 ret = 0;
1557
1558 vpu_api_dbg_func("enter\n");
1559
1560 if (!vpuApi) {
1561 return ret;
1562 }
1563
1564 if (vpuApi->frm_rdy_cb.cb) {
1565 ret = vpuApi->frm_rdy_cb.cb(vpuApi->frm_rdy_cb.cbCtx);
1566 }
1567
1568 vpu_api_dbg_func("leave ret %d\n", ret);
1569
1570 return ret;
1571 }
1572
control(VpuCodecContext * ctx,VPU_API_CMD cmd,void * param)1573 RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
1574 {
1575 vpu_api_dbg_func("enter cmd 0x%x param %p\n", cmd, param);
1576
1577 if (mpi == NULL && !init_ok) {
1578 return 0;
1579 }
1580
1581 MpiCmd mpicmd = MPI_CMD_BUTT;
1582 switch (cmd) {
1583 case VPU_API_ENABLE_DEINTERLACE : {
1584 mpicmd = MPP_DEC_SET_ENABLE_DEINTERLACE;
1585 } break;
1586 case VPU_API_ENC_SETCFG : {
1587 MppCodingType coding = (MppCodingType)ctx->videoCoding;
1588
1589 memcpy(&enc_param, param, sizeof(enc_param));
1590 return vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, &enc_param);
1591 } break;
1592 case VPU_API_ENC_GETCFG : {
1593 memcpy(param, &enc_param, sizeof(enc_param));
1594 return mpi->control(mpp_ctx, MPP_ENC_GET_CFG, enc_cfg);;
1595 } break;
1596 case VPU_API_ENC_SETFORMAT : {
1597 EncInputPictureType type = *((EncInputPictureType *)param);
1598 MppCodingType coding = (MppCodingType)ctx->videoCoding;
1599 MppFrameFormat old_fmt = format;
1600
1601 format = vpu_pic_type_remap_to_mpp(type);
1602 if (old_fmt != format)
1603 return vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, &enc_param);
1604 else
1605 return 0;
1606 } break;
1607 case VPU_API_ENC_SETIDRFRAME : {
1608 mpicmd = MPP_ENC_SET_IDR_FRAME;
1609 } break;
1610 case VPU_API_SET_VPUMEM_CONTEXT: {
1611 mpicmd = MPP_DEC_SET_EXT_BUF_GROUP;
1612 } break;
1613 case VPU_API_USE_PRESENT_TIME_ORDER: {
1614 mpicmd = MPP_DEC_SET_PRESENT_TIME_ORDER;
1615 } break;
1616 case VPU_API_SET_INFO_CHANGE: {
1617 mpicmd = MPP_DEC_SET_INFO_CHANGE_READY;
1618 } break;
1619 case VPU_API_USE_FAST_MODE: {
1620 mpicmd = MPP_DEC_SET_PARSER_FAST_MODE;
1621 } break;
1622 case VPU_API_DEC_GET_STREAM_COUNT: {
1623 mpicmd = MPP_DEC_GET_STREAM_COUNT;
1624 } break;
1625 case VPU_API_GET_VPUMEM_USED_COUNT: {
1626 mpicmd = MPP_DEC_GET_VPUMEM_USED_COUNT;
1627 } break;
1628 case VPU_API_SET_OUTPUT_BLOCK: {
1629 mpicmd = MPP_SET_OUTPUT_TIMEOUT;
1630 if (param) {
1631 RK_S32 timeout = *((RK_S32*)param);
1632
1633 if (timeout) {
1634 if (timeout < 0)
1635 mpp_log("set output mode to block\n");
1636 else
1637 mpp_log("set output timeout %d ms\n", timeout);
1638 } else {
1639 mpp_log("set output mode to non-block\n");
1640 }
1641 }
1642 } break;
1643 case VPU_API_SET_INPUT_BLOCK: {
1644 mpicmd = MPP_SET_INPUT_TIMEOUT;
1645 if (param) {
1646 RK_S32 timeout = *((RK_S32*)param);
1647 mInputTimeOutMs = timeout;
1648
1649 if (timeout) {
1650 if (timeout < 0)
1651 mpp_log("set input mode to block\n");
1652 else
1653 mpp_log("set input timeout %d ms\n", timeout);
1654 } else {
1655 mpp_log("set input mode to non-block\n");
1656 }
1657 }
1658 } break;
1659 case VPU_API_GET_EOS_STATUS: {
1660 *((RK_S32 *)param) = mEosSet;
1661 mpicmd = MPI_CMD_BUTT;
1662 } break;
1663 case VPU_API_SET_FRAME_INFO: {
1664 mpicmd = MPI_CMD_BUTT;
1665 mpi->control(mpp_ctx, MPP_DEC_SET_FRAME_INFO, (MppParam)frm_info);
1666 } break;
1667 case VPU_API_GET_FRAME_INFO: {
1668 *((VPU_GENERIC *)param) = vpug;
1669 mpicmd = MPI_CMD_BUTT;
1670 } break;
1671 case VPU_API_SET_OUTPUT_MODE: {
1672 mpicmd = MPP_DEC_SET_OUTPUT_FORMAT;
1673 mpp_frame_set_fmt(frm_info, (param) ? (*((MppFrameFormat *)param)) :
1674 (MPP_FMT_YUV420SP));
1675 } break;
1676 case VPU_API_DEC_EN_FBC_HDR_256_ODD : {
1677 MppCompat *compatItem = NULL;
1678 compatItem = mpp_compat_query_by_id(MPP_COMPAT_DEC_FBC_HDR_256_ODD);
1679 if (compatItem) {
1680 mpp_compat_update(compatItem, 1);
1681 }
1682 } break;
1683 case VPU_API_DEC_OUT_FRM_STRUCT_TYPE: {
1684 dec_out_frm_struct_type = *((RK_S32 *)param);
1685 return 0;
1686 } break;
1687 case VPU_API_DEC_EN_THUMBNAIL: {
1688 RK_S32 ret = 0;
1689 MppDecCfg cfg;
1690 RK_U32 val = *((RK_U32 *)param);
1691 ret = mpp_dec_cfg_init(&cfg);
1692 if (ret) {
1693 return ret;
1694 }
1695 ret = mpi->control(mpp_ctx, MPP_DEC_GET_CFG, cfg);
1696 mpp_dec_cfg_set_u32(cfg, "base:enable_thumbnail", val);
1697 ret = mpi->control(mpp_ctx, MPP_DEC_SET_CFG, cfg);
1698 mpp_dec_cfg_deinit(cfg);
1699 return ret;
1700 } break;
1701 case VPU_API_DEC_EN_HDR_META: {
1702 RK_S32 ret = 0;
1703 MppDecCfg cfg;
1704 RK_U32 val = *((RK_U32 *)param);
1705 ret = mpp_dec_cfg_init(&cfg);
1706 if (ret) {
1707 return ret;
1708 }
1709 ret = mpi->control(mpp_ctx, MPP_DEC_GET_CFG, cfg);
1710 mpp_dec_cfg_set_u32(cfg, "base:enable_hdr_meta", val);
1711 ret = mpi->control(mpp_ctx, MPP_DEC_SET_CFG, cfg);
1712 mpp_dec_cfg_deinit(cfg);
1713 return ret;
1714 } break;
1715 case VPU_API_SET_FRM_RDY_CB: {
1716 RK_S32 ret = 0;
1717 MppDecCfg cfg;
1718 FrameRdyCB *cb = (FrameRdyCB *)param;
1719
1720 ret = mpp_dec_cfg_init(&cfg);
1721 if (ret) {
1722 return ret;
1723 }
1724
1725 frm_rdy_cb.cb = cb->cb;
1726 frm_rdy_cb.cbCtx = cb->cbCtx;
1727 mpp_dec_cfg_set_ptr(cfg, "cb:frm_rdy_cb",
1728 frm_rdy_cb.cb ? (void *)frm_rdy_cb.cb : (void *)frameReadyCallback);
1729 mpp_dec_cfg_set_ptr(cfg, "cb:frm_rdy_ctx", frm_rdy_cb.cbCtx);
1730 ret = mpi->control(mpp_ctx, MPP_DEC_SET_CFG, cfg);
1731 mpp_dec_cfg_deinit(cfg);
1732 return ret;
1733 } break;
1734 case VPU_API_SET_DISABLE_ERROR: {
1735 mpicmd = MPP_DEC_SET_DISABLE_ERROR;
1736 } break;
1737 case VPU_API_SET_DIS_ERR_CLR_MARK: {
1738 mpicmd = MPP_DEC_SET_DIS_ERR_CLR_MARK;
1739 } break;
1740 case VPU_API_SET_IMMEDIATE_OUT: {
1741 mpicmd = MPP_DEC_SET_IMMEDIATE_OUT;
1742 } break;
1743 case VPU_API_ENC_SET_VEPU22_CFG: {
1744 mpicmd = MPP_ENC_SET_CODEC_CFG;
1745 } break;
1746 case VPU_API_ENC_GET_VEPU22_CFG: {
1747 mpicmd = MPP_ENC_GET_CODEC_CFG;
1748 } break;
1749 case VPU_API_ENC_SET_VEPU22_CTU_QP: {
1750 mpicmd = MPP_ENC_SET_CTU_QP;
1751 } break;
1752 case VPU_API_ENC_SET_VEPU22_ROI: {
1753 mpicmd = MPP_ENC_SET_ROI_CFG;
1754 } break;
1755 case VPU_API_ENC_MPP_SETCFG: {
1756 mpicmd = MPP_ENC_SET_CFG;
1757 } break;
1758 case VPU_API_ENC_MPP_GETCFG: {
1759 *((MppEncCfg *)param) = enc_cfg;
1760 return 0;
1761 } break;
1762 case VPU_API_ENC_SET_MAX_TID: {
1763 RK_S32 max_tid = *(RK_S32 *)param;
1764
1765 vpu_api_dbg_ctrl("VPU_API_ENC_SET_MAX_TID %d\n", max_tid);
1766 mlvec_dy_cfg.max_tid = max_tid;
1767 mlvec_dy_cfg.updated |= VPU_API_ENC_MAX_TID_UPDATED;
1768
1769 if (mlvec)
1770 vpu_api_mlvec_set_dy_max_tid(mlvec, max_tid);
1771
1772 return 0;
1773 } break;
1774 case VPU_API_ENC_SET_MARK_LTR: {
1775 RK_S32 mark_ltr = *(RK_S32 *)param;
1776
1777 vpu_api_dbg_ctrl("VPU_API_ENC_SET_MARK_LTR %d\n", mark_ltr);
1778
1779 mlvec_dy_cfg.mark_ltr = mark_ltr;
1780 if (mark_ltr >= 0)
1781 mlvec_dy_cfg.updated |= VPU_API_ENC_MARK_LTR_UPDATED;
1782
1783 return 0;
1784 } break;
1785 case VPU_API_ENC_SET_USE_LTR: {
1786 RK_S32 use_ltr = *(RK_S32 *)param;
1787
1788 vpu_api_dbg_ctrl("VPU_API_ENC_SET_USE_LTR %d\n", use_ltr);
1789
1790 mlvec_dy_cfg.use_ltr = use_ltr;
1791 mlvec_dy_cfg.updated |= VPU_API_ENC_USE_LTR_UPDATED;
1792
1793 return 0;
1794 } break;
1795 case VPU_API_ENC_SET_FRAME_QP: {
1796 RK_S32 frame_qp = *(RK_S32 *)param;
1797
1798 vpu_api_dbg_ctrl("VPU_API_ENC_SET_FRAME_QP %d\n", frame_qp);
1799
1800 mlvec_dy_cfg.frame_qp = frame_qp;
1801 mlvec_dy_cfg.updated |= VPU_API_ENC_FRAME_QP_UPDATED;
1802
1803 return 0;
1804 } break;
1805 case VPU_API_ENC_SET_BASE_LAYER_PID: {
1806 RK_S32 base_layer_pid = *(RK_S32 *)param;
1807
1808 vpu_api_dbg_ctrl("VPU_API_ENC_SET_BASE_LAYER_PID %d\n", base_layer_pid);
1809
1810 mlvec_dy_cfg.base_layer_pid = base_layer_pid;
1811 mlvec_dy_cfg.updated |= VPU_API_ENC_BASE_PID_UPDATED;
1812
1813 return 0;
1814 } break;
1815 case VPU_API_GET_EXTRA_INFO: {
1816 EncoderOut_t *out = (EncoderOut_t *)param;
1817
1818 vpu_api_dbg_ctrl("VPU_API_GET_EXTRA_INFO\n");
1819
1820 if (NULL == enc_hdr_pkt) {
1821 if (NULL == enc_hdr_buf) {
1822 enc_hdr_buf_size = SZ_1K;
1823 enc_hdr_buf = mpp_calloc_size(RK_U8, enc_hdr_buf_size);
1824 }
1825
1826 if (enc_hdr_buf)
1827 mpp_packet_init(&enc_hdr_pkt, enc_hdr_buf, enc_hdr_buf_size);
1828 }
1829
1830 mpp_assert(enc_hdr_pkt);
1831 if (enc_hdr_pkt) {
1832 mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, enc_hdr_pkt);
1833
1834 RK_S32 length = mpp_packet_get_length(enc_hdr_pkt);
1835 void *src = mpp_packet_get_data(enc_hdr_pkt);
1836
1837 memcpy(out->data, src, length);
1838 out->size = length;
1839 }
1840 return 0;
1841 } break;
1842 case VPU_API_SET_PARSER_SPLIT_MODE: {
1843 mpicmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
1844 } break;
1845 case VPU_API_DEC_EN_MVC: {
1846 mpicmd = MPP_DEC_SET_ENABLE_MVC;
1847 } break;
1848 default: {
1849 } break;
1850 }
1851
1852 RK_S32 ret = -1;
1853 if (mpicmd < MPI_CMD_BUTT)
1854 ret = mpi->control(mpp_ctx, mpicmd, (MppParam)param);
1855
1856 vpu_api_dbg_func("leave\n");
1857 return ret;
1858 }
1859
1860