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