xref: /OK3568_Linux_fs/external/mpp/mpp/legacy/vpu_api_legacy.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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