• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 Rockchip Electronics Co., LTD.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #define MODULE_TAG "vpu_api_legacy"
19 
20 #include "vpu_api_legacy.h"
21 #include <fcntl.h>
22 #include "cstring"
23 #include "hdf_log.h"
24 #include "mpp_mem.h"
25 #include "mpp_env.h"
26 #include "mpp_time.h"
27 #include "mpp_common.h"
28 #include "mpp_packet_impl.h"
29 #include "mpp_buffer_impl.h"
30 #include "mpp_frame.h"
31 #include "vpu_mem_legacy.h"
32 #include "securec.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             HDF_LOGE("%s There is no match format, err!!!!!!", __func__);
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) : // qp_init 26
103                       (coding == MPP_VIDEO_CodingMJPEG) ? (10) : // qp_init 10
104                       (coding == MPP_VIDEO_CodingVP8) ? (56) : // qp_init 56
105                       (coding == MPP_VIDEO_CodingHEVC) ? (26) : (0); // qp_init 26
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     HDF_LOGI("setup encoder rate control config:");
114     HDF_LOGI("width %4d height %4d format %d:%x", width, height, cfg->format, fmt);
115     HDF_LOGI("rc_mode %s qp %d bps %d", (rc_mode) ? ("CBR") : ("CQP"), qp, bps);
116     HDF_LOGI("fps in %d fps out %d gop %d", fps_in, fps_out, gop);
117     HDF_LOGI("setup encoder stream feature config:");
118     HDF_LOGI("profile %d level %d cabac %d", profile, level, cabac_en);
119 
120     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:width", width);
121     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:height", height);
122     switch (fmt & MPP_FRAME_FMT_MASK) {
123         case MPP_FMT_YUV420SP :
124         case MPP_FMT_YUV420SP_VU : {
125             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, \
126                 "prep:hor_stride", MPP_ALIGN(width, 16)); // hor_stride 16
127             } break;
128         case MPP_FMT_RGB565:
129         case MPP_FMT_BGR565:
130         case MPP_FMT_RGB555:
131         case MPP_FMT_BGR555: {
132             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:hor_stride", \
133                 2 * MPP_ALIGN(width, 16)); // hor_stride 2 * 16
134             } break;
135         case MPP_FMT_ARGB8888 :
136         case MPP_FMT_ABGR8888 :
137         case MPP_FMT_BGRA8888 :
138         case MPP_FMT_RGBA8888 : {
139             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:hor_stride", 4 * MPP_ALIGN(width, 16)); // hor_stride 4 * 16
140             } break;
141         default: {
142             HDF_LOGE("%s unsupport format 0x%x", __func__, fmt & MPP_FRAME_FMT_MASK);
143             } break;
144     }
145     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:ver_stride", MPP_ALIGN(height, 8)); // height 8 bit
146     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "prep:format", fmt);
147 
148     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:mode", is_fix_qp ? MPP_ENC_RC_MODE_FIXQP :
149                         (rc_mode ? MPP_ENC_RC_MODE_CBR : MPP_ENC_RC_MODE_VBR));
150     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:bps_target", bps);
151     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:bps_max", bps * 17 / 16); // bps_max  17 / 16
152     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:bps_min", rc_mode ? bps * 15 / 16 : bps * 1 / 16); // bps_min 15 / 16
153     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_in_flex", 0);
154     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_in_num", fps_in);
155     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_in_denorm", 1);
156     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_out_flex", 0);
157     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_out_num", fps_out);
158     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:fps_out_denorm", 1);
159     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "rc:gop", gop);
160 
161     (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "codec:type", coding);
162     switch (coding) {
163         case MPP_VIDEO_CodingAVC : {
164             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:profile", profile);
165             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:level", level);
166             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:cabac_en", cabac_en);
167             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:cabac_idc", 0);
168             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_init", is_fix_qp ? qp : -1);
169             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_min", is_fix_qp  ? qp : 10); // qp_min 10
170             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_max", is_fix_qp ? qp : 51); // h264:qp_max 51
171             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_min_i", 10); // qp_min_i 10
172             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_max_i", 51); // qp_max_i 51
173             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_step", 4); // qp_step 4
174             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "h264:qp_delta_ip", 3); // qp_delta_ip 3
175             } break;
176         case MPP_VIDEO_CodingVP8 : {
177             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "vp8:qp_init", -1);
178             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "vp8:qp_min", 0); // qp_min 0
179             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "vp8:qp_max", 127); // qp_max 127
180             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "vp8:qp_min_i", 0); // qp_min_i 0
181             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "vp8:qp_max_i", 127); // qp_max_i 127
182             } break;
183         case MPP_VIDEO_CodingMJPEG : {
184             (*(mRKMppApi.HdiMppEncCfgSetS32))(enc_cfg, "jpeg:quant", qp);
185             } break;
186         default : {
187             HDF_LOGE("%s support encoder coding type %d", __func__, coding);
188             } break;
189     }
190 
191     ret = mpi->control(mpp_ctx, MPP_ENC_SET_CFG, enc_cfg);
192     if (ret) {
193         HDF_LOGE("%s setup enc config failed ret %d", __func__, ret);
194         goto RET;
195     }
196 RET:
197     return ret;
198 }
199 
is_valid_dma_fd(int fd)200 static int is_valid_dma_fd(int fd)
201 {
202     int ret = 1;
203     /* detect input file handle */
204     int fs_flag = fcntl(fd, F_GETFL, nullptr);
205     int fd_flag = fcntl(fd, F_GETFD, nullptr);
206     if (fs_flag == -1 || fd_flag == -1) {
207         ret = 0;
208     }
209 
210     return ret;
211 }
212 
copy_align_raw_buffer_to_dest(RK_U8 * dst,RK_U8 * src,RK_U32 width,RK_U32 height,MppFrameFormat fmt)213 static int copy_align_raw_buffer_to_dest(RK_U8 *dst, RK_U8 *src, RK_U32 width,
214                                          RK_U32 height, MppFrameFormat fmt)
215 {
216     int ret = 1;
217     RK_U32 index = 0;
218     RK_U8 *dst_buf = dst;
219     RK_U8 *src_buf = src;
220     RK_U32 row = 0;
221     RK_U32 hor_stride = MPP_ALIGN(width, 16); // width 16
222     RK_U32 ver_stride = MPP_ALIGN(height, 8); // height 8
223     RK_U8 *dst_u = dst_buf + hor_stride * ver_stride;
224     RK_U8 *dst_v = dst_u + hor_stride * ver_stride / 4;
225 
226     switch (fmt) {
227         case MPP_FMT_YUV420SP : {
228             for (row = 0; row < height; row++) {
229                 if (memcpy_s(dst_buf + row * hor_stride, width, src_buf + index, width) != EOK) {
230                     HDF_LOGE("%s memcpy_s no", __func__);
231                 }
232                 index += width;
233             }
234             for (row = 0; row < height / 2; row++) { // height : / 2
235                 if (memcpy_s(dst_u + row * hor_stride, width, src_buf + index, width) != EOK) {
236                     HDF_LOGE("%s memcpy_s no", __func__);
237                 }
238                 index += width;
239             }
240             } break;
241         case MPP_FMT_YUV420P : {
242             for (row = 0; row < height; row++) {
243                 if (memcpy_s(dst_buf + row * hor_stride, width, src_buf + index, width) != EOK) {
244                     HDF_LOGE("%s memcpy_s no", __func__);
245                 }
246                 index += width;
247             }
248             for (row = 0; row < height / 2; row++) { // height : / 2
249                 if (memcpy_s(dst_u + row * hor_stride / 2, // height : / 2
250                     width / 2, src_buf + index, width / 2) != EOK) { // height : / 2
251                     HDF_LOGE("%s memcpy_s no", __func__);
252                 }
253                 index += width / 2; // width / 2
254             }
255             for (row = 0; row < height / 2; row++) { // height : / 2
256                 if (memcpy_s(dst_v + row * hor_stride / 2, // height : / 2
257                     width / 2, src_buf + index, width / 2) != EOK) { // height : / 2
258                     HDF_LOGE("%s memcpy_s no", __func__);
259                 }
260                 index += width / 2; // width / 2
261             }
262             } break;
263         case MPP_FMT_RGBA8888 :
264         case MPP_FMT_BGRA8888 :
265         case MPP_FMT_ABGR8888 :
266         case MPP_FMT_ARGB8888 : {
267             for (row = 0; row < height; row++) {
268                 if (memcpy_s(dst_buf + row * hor_stride * 4, // width 4
269                     width * 4, src_buf + row * width * 4, width * 4) != EOK) { // width 4
270                     HDF_LOGE("%s memcpy_s no", __func__);
271                 }
272                 }
273             } break;
274         default : {
275             HDF_LOGE("%s unsupport align fmt:%d now", __func__, fmt);
276             } break;
277         }
278 
279     return ret;
280 }
281 
VpuApiLegacy()282 VpuApiLegacy::VpuApiLegacy() : mpp_ctx(nullptr),
283     mpi(nullptr),
284     init_ok(0),
285     frame_count(0),
286     set_eos(0),
287     memGroup(nullptr),
288     format(MPP_FMT_YUV420P),
289     fd_input(-1),
290     fd_output(-1),
291     mEosSet(0),
292     enc_cfg(nullptr),
293     enc_hdr_pkt(nullptr),
294     enc_hdr_buf(nullptr),
295     enc_hdr_buf_size(0)
296 {
297     HDF_LOGD("enter");
298 
299     (*(mRKMppApi.HdiMppCreate))(&mpp_ctx, &mpi);
300 
301     memset_s(&enc_param, sizeof(enc_param), 0, sizeof(enc_param));
302 
303     mlvec = nullptr;
304     memset_s(&mlvec_dy_cfg, sizeof(mlvec_dy_cfg), 0, sizeof(mlvec_dy_cfg));
305 
306     HDF_LOGD("leave");
307 }
308 
~VpuApiLegacy()309 VpuApiLegacy::~VpuApiLegacy()
310 {
311     HDF_LOGD("enter");
312 
313     (*(mRKMppApi.HdiMppDestroy))(mpp_ctx);
314 
315     if (memGroup) {
316         (*(mRKMppApi.HdiMppBufferGroupPut))(memGroup);
317         memGroup = nullptr;
318     }
319 
320     if (enc_cfg) {
321         (*(mRKMppApi.HdiMppEncCfgDeinit))(enc_cfg);
322         enc_cfg = nullptr;
323     }
324 
325     if (mlvec) {
326         vpu_api_mlvec_deinit(mlvec);
327         mlvec = nullptr;
328     }
329 
330     if (enc_hdr_pkt) {
331         (*(mRKMppApi.HdiMppPacketDeinit))(&enc_hdr_pkt);
332         enc_hdr_pkt = nullptr;
333     }
334     if (enc_hdr_buf) {
335         (*(mRKMppApi.Hdimpp_osal_free))(__FUNCTION__, enc_hdr_buf);
336     }
337     enc_hdr_buf = nullptr;
338 
339     enc_hdr_buf_size = 0;
340 
341     HDF_LOGD("leave");
342 }
343 
init_frame_info(VpuCodecContext * ctx,MppCtx mpp_ctx,MppApi * mpi,VPU_GENERIC * p)344 static RK_S32 init_frame_info(VpuCodecContext *ctx,
345                               MppCtx mpp_ctx, MppApi *mpi, VPU_GENERIC *p)
346 {
347     RK_S32 ret = -1;
348     MppFrame frame = nullptr;
349     RK_U32 fbcOutFmt = 0;
350 
351     if (ctx->private_data)
352         fbcOutFmt = *(RK_U32 *)ctx->private_data;
353 
354     if (ctx->extra_cfg.bit_depth
355         || ctx->extra_cfg.yuv_format) {
356         if (ctx->extra_cfg.bit_depth == 10) // extra_cfg.bit_depth == 10
357             p->CodecType = (ctx->extra_cfg.yuv_format == 1)
358                            ? MPP_FMT_YUV422SP_10BIT : MPP_FMT_YUV420SP_10BIT;
359         else
360             p->CodecType = (ctx->extra_cfg.yuv_format == 1)
361                            ? MPP_FMT_YUV422SP : MPP_FMT_YUV420SP;
362     } else {
363         /**hightest of p->ImgWidth bit show current dec bitdepth
364           * 0 - 8bit
365           * 1 - 10bit
366           **/
367         if (p->ImgWidth & 0x80000000)
368             p->CodecType = (p->ImgWidth & 0x40000000)
369                            ? MPP_FMT_YUV422SP_10BIT : MPP_FMT_YUV420SP_10BIT;
370         else
371             p->CodecType = (p->ImgWidth & 0x40000000)
372                            ? MPP_FMT_YUV422SP : MPP_FMT_YUV420SP;
373     }
374     p->ImgWidth = (p->ImgWidth & 0xFFFF);
375 
376     (*(mRKMppApi.HdiMppFrameInit))(&frame);
377 
378     (*(mRKMppApi.HdiMppFrameSetWidth))(frame, p->ImgWidth);
379     (*(mRKMppApi.HdiMppFrameSetHeight))(frame, p->ImgHeight);
380     (*(mRKMppApi.HdiMppFrameSetFormat))(frame, (MppFrameFormat)(p->CodecType | fbcOutFmt));
381 
382     ret = mpi->control(mpp_ctx, MPP_DEC_SET_FRAME_INFO, (MppParam)frame);
383     /* output the parameters used */
384     p->ImgHorStride = (*(mRKMppApi.HdiMppFrameGetHorStride))(frame);
385     p->ImgVerStride = (*(mRKMppApi.HdiMppFrameGetVerStride))(frame);
386     p->BufSize = (*(mRKMppApi.HdiMppFrameGetBufferSize))(frame);
387 
388     (*(mRKMppApi.HdiMppFrameDeinit))(&frame);
389 
390     return ret;
391 }
392 
393 
init(VpuCodecContext * ctx,RK_U8 * extraData,RK_U32 extra_size)394 RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size)
395 {
396     HDF_LOGD("enter");
397 
398     MPP_RET ret = MPP_OK;
399     MppCtxType type;
400 
401     if (mpp_ctx == nullptr || mpi == nullptr) {
402         HDF_LOGE("%s found invalid context input", __func__);
403         return MPP_ERR_NULL_PTR;
404     }
405 
406     if (CODEC_DECODER == ctx->codecType) {
407         type = MPP_CTX_DEC;
408     } else if (CODEC_ENCODER == ctx->codecType) {
409         type = MPP_CTX_ENC;
410     } else {
411         HDF_LOGE("%s found invalid codec type %d", __func__, ctx->codecType);
412         return MPP_ERR_VPU_CODEC_INIT;
413     }
414 
415     ret = (*(mRKMppApi.HdiMppInit))(mpp_ctx, type, (MppCodingType)ctx->videoCoding);
416     if (ret) {
417         HDF_LOGE("%s  init error.", __func__);
418         return ret;
419     }
420 
421     if (MPP_CTX_ENC == type) {
422         EncParameter_t *param = (EncParameter_t*)ctx->private_data;
423         MppCodingType coding = (MppCodingType)ctx->videoCoding;
424         MppPollType block = (MppPollType)VPU_API_ENC_INPUT_TIMEOUT;
425         MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_DISABLE;
426 
427         /* setup input / output block mode */
428         ret = mpi->control(mpp_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block);
429         if (MPP_OK != ret)
430             HDF_LOGE("%s mpi control MPP_SET_INPUT_TIMEOUT failed", __func__);
431 
432         /* disable sei by default */
433         ret = mpi->control(mpp_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode);
434         if (ret)
435             HDF_LOGE("%s mpi control MPP_ENC_SET_SEI_CFG failed ret %d", __func__, ret);
436 
437         if (memGroup == nullptr) {
438             ret = (*(mRKMppApi.HdiMppBufferGroupGet)) \
439                 (&memGroup, MPP_BUFFER_TYPE_ION, MPP_BUFFER_INTERNAL, MODULE_TAG, __FUNCTION__);
440             if (ret) {
441                 HDF_LOGE("%s memGroup (*(mRKMppApi.HdiMppBufferGroupGet)) failed %d", __func__, ret);
442                 return ret;
443             }
444         }
445 
446         ret = (*(mRKMppApi.HdiMppEncCfgInit))(&enc_cfg);
447         if (ret) {
448             HDF_LOGE("%s (*(mRKMppApi.HdiMppEncCfgInit)) failed %d", __func__, ret);
449             (*(mRKMppApi.HdiMppBufferGroupPut))(memGroup);
450             memGroup = nullptr;
451             return ret;
452         }
453 
454         format = vpu_pic_type_remap_to_mpp((EncInputPictureType)param->format);
455         if (memcpy_s(&enc_param, sizeof(enc_param), param, sizeof(enc_param)) != EOK) {
456             HDF_LOGE("%s memcpy_s no", __func__);
457         }
458 
459         if (MPP_OK == vpu_api_mlvec_check_cfg(param)) {
460             if (mlvec == nullptr) {
461                 vpu_api_mlvec_init(&mlvec);
462                 vpu_api_mlvec_setup(mlvec, mpp_ctx, mpi, enc_cfg);
463             }
464         }
465 
466         if (mlvec)
467             vpu_api_mlvec_set_st_cfg(mlvec, (VpuApiMlvecStaticCfg *)param);
468 
469         vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, param);
470 
471         if (!mlvec) {
472             if (enc_hdr_pkt == nullptr) {
473                 if (enc_hdr_buf == nullptr) {
474                     enc_hdr_buf_size = SZ_1K;
475                     enc_hdr_buf = (*(mRKMppApi.Hdimpp_osal_calloc))(__FUNCTION__, enc_hdr_buf_size);
476                 }
477 
478                 if (enc_hdr_buf)
479                     (*(mRKMppApi.HdiMppPacketInit))(&enc_hdr_pkt, enc_hdr_buf, enc_hdr_buf_size);
480             }
481             if (enc_hdr_pkt) {
482                 ret = mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, enc_hdr_pkt);
483                 ctx->extradata_size = (*(mRKMppApi.HdiMppPacketGetLength))(enc_hdr_pkt);
484                 ctx->extradata      = (*(mRKMppApi.Hdimpp_packet_get_data))(enc_hdr_pkt);
485             }
486         }
487     } else { /* MPP_CTX_DEC */
488         vpug.CodecType  = ctx->codecType;
489         vpug.ImgWidth   = ctx->width;
490         vpug.ImgHeight  = ctx->height;
491 
492         init_frame_info(ctx, mpp_ctx, mpi, &vpug);
493 
494         if (extraData != nullptr) {
495             MppPacket pkt = nullptr;
496 
497             (*(mRKMppApi.HdiMppPacketInit))(&pkt, extraData, extra_size);
498             (*(mRKMppApi.Hdimpp_packet_set_extra_data))(pkt);
499             mpi->decode_put_packet(mpp_ctx, pkt);
500             (*(mRKMppApi.HdiMppPacketDeinit))(&pkt);
501         }
502 
503         RK_U32 flag = 0;
504         ret = mpi->control(mpp_ctx, MPP_DEC_SET_ENABLE_DEINTERLACE, &flag);
505         if (ret)
506             HDF_LOGE("%s disable mpp deinterlace failed ret %d", __func__, ret);
507     }
508 
509     init_ok = 1;
510 
511     HDF_LOGD("leave");
512     return ret;
513 }
514 
flush(VpuCodecContext * ctx)515 RK_S32 VpuApiLegacy::flush(VpuCodecContext *ctx)
516 {
517     (void)ctx;
518     HDF_LOGD("enter");
519     if (mpi && mpi->reset && init_ok) {
520         mpi->reset(mpp_ctx);
521         set_eos = 0;
522         mEosSet = 0;
523     }
524     HDF_LOGD("leave");
525     return 0;
526 }
527 
setup_VPU_FRAME_from_mpp_frame(VPU_FRAME * vframe,MppFrame mframe)528 static void setup_VPU_FRAME_from_mpp_frame(VPU_FRAME *vframe, MppFrame mframe)
529 {
530     MppBuffer buf = (*(mRKMppApi.HdiMppFrameGetBuffer))(mframe);
531     RK_U64 pts  = (*(mRKMppApi.Hdimpp_frame_get_pts))(mframe);
532     RK_U32 mode = (*(mRKMppApi.Hdimpp_frame_get_mode))(mframe);
533 
534     MppFrameColorRange colorRan = (*(mRKMppApi.Hdimpp_frame_get_color_range))(mframe);
535     MppFrameColorTransferCharacteristic colorTrc = (*(mRKMppApi.Hdimpp_frame_get_color_trc))(mframe);
536     MppFrameColorPrimaries colorPri = (*(mRKMppApi.Hdimpp_frame_get_color_primaries))(mframe);
537     MppFrameColorSpace colorSpa = (*(mRKMppApi.Hdimpp_frame_get_colorspace))(mframe);
538 
539     if (buf)
540         (*(mRKMppApi.Hdimpp_buffer_inc_ref_with_caller))(buf, __FUNCTION__);
541 
542     vframe->DisplayWidth = (*(mRKMppApi.HdiMppFrameGetWidth))(mframe);
543     vframe->DisplayHeight = (*(mRKMppApi.HdiMppFrameGetHeight))(mframe);
544     vframe->FrameWidth = (*(mRKMppApi.HdiMppFrameGetHorStride))(mframe);
545     vframe->FrameHeight = (*(mRKMppApi.HdiMppFrameGetVerStride))(mframe);
546 
547     vframe->ColorRange = (colorRan == MPP_FRAME_RANGE_JPEG);
548     vframe->ColorPrimaries = colorPri;
549     vframe->ColorTransfer = colorTrc;
550     vframe->ColorCoeffs = colorSpa;
551 
552     if (mode == MPP_FRAME_FLAG_FRAME)
553         vframe->FrameType = 0;
554     else {
555         RK_U32 field_order = mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK;
556         if (field_order == MPP_FRAME_FLAG_TOP_FIRST)
557             vframe->FrameType = 1; // vframe->FrameType = 1
558         else if (field_order == MPP_FRAME_FLAG_BOT_FIRST)
559             vframe->FrameType = 2; // vframe->FrameType = 2
560         else if (field_order == MPP_FRAME_FLAG_DEINTERLACED)
561             vframe->FrameType = 4; // vframe->FrameType = 4
562     }
563     vframe->ErrorInfo = (*(mRKMppApi.HdiMppFrameGetErrinfo))(mframe) | (*(mRKMppApi.HdiMppFrameGetDiscard))(mframe);
564     vframe->ShowTime.TimeHigh = (RK_U32)(pts >> 32); // (pts >> 32)
565     vframe->ShowTime.TimeLow = (RK_U32)pts;
566     switch ((*(mRKMppApi.HdiMppFrameGetFormat))(mframe) & MPP_FRAME_FMT_MASK) {
567         case MPP_FMT_YUV420SP: {
568             vframe->ColorType = VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR;
569             vframe->OutputWidth = 0x20;
570             } break;
571         case MPP_FMT_YUV420SP_10BIT: {
572             vframe->ColorType = VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR;
573             vframe->ColorType |= VPU_OUTPUT_FORMAT_BIT_10;
574             vframe->OutputWidth = 0x22;
575             } break;
576         case MPP_FMT_YUV422SP: {
577             vframe->ColorType = VPU_OUTPUT_FORMAT_YUV422;
578             vframe->OutputWidth = 0x10;
579             } break;
580         case MPP_FMT_YUV422SP_10BIT: {
581             vframe->ColorType = VPU_OUTPUT_FORMAT_YUV422;
582             vframe->ColorType |= VPU_OUTPUT_FORMAT_BIT_10;
583             vframe->OutputWidth = 0x23;
584             } break;
585         default: {
586             } break;
587         }
588 
589     switch (colorPri) {
590         case MPP_FRAME_PRI_BT2020: {
591             vframe->ColorType |= VPU_OUTPUT_FORMAT_COLORSPACE_BT2020;
592             } break;
593         case MPP_FRAME_PRI_BT709: {
594             vframe->ColorType |= VPU_OUTPUT_FORMAT_COLORSPACE_BT709;
595             } break;
596         default: {
597             } break;
598         }
599 
600     switch (colorTrc) {
601         case MPP_FRAME_TRC_SMPTEST2084: {
602             vframe->ColorType |= VPU_OUTPUT_FORMAT_DYNCRANGE_HDR10; // HDR10
603             } break;
604         case MPP_FRAME_TRC_ARIB_STD_B67: {
605             vframe->ColorType |= VPU_OUTPUT_FORMAT_DYNCRANGE_HDR_HLG; // HDR_HLG
606             } break;
607         case MPP_FRAME_TRC_BT2020_10: {
608             vframe->ColorType |= VPU_OUTPUT_FORMAT_COLORSPACE_BT2020; // BT2020
609             } break;
610         default: {
611             } break;
612         }
613 
614     if (buf) {
615         MppBufferImpl *p = (MppBufferImpl*)buf;
616         void *ptr = (p->mode == MPP_BUFFER_INTERNAL) ?
617                     (*(mRKMppApi.HdiMppBufferGetPtrWithCaller))(buf, __FUNCTION__) : nullptr;
618         RK_S32 fd = (*(mRKMppApi.HdiMppBufferGetFdWithCaller))(buf, __FUNCTION__);
619 
620         vframe->FrameBusAddr[0] = fd;
621         vframe->FrameBusAddr[1] = fd;
622         vframe->vpumem.vir_addr = (RK_U32*)ptr;
623         vframe->vpumem.phy_addr = fd;
624 
625         vframe->vpumem.size = vframe->FrameWidth * vframe->FrameHeight * 3 / 2; // FrameHeight * 3 / 2
626         vframe->vpumem.offset = (RK_U32*)buf;
627     }
628 }
629 
decode(VpuCodecContext * ctx,VideoPacket_t * pkt,DecoderOut_t * aDecOut)630 RK_S32 VpuApiLegacy::decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
631 {
632     MPP_RET ret = MPP_OK;
633     MppFrame mframe = nullptr;
634     MppPacket packet = nullptr;
635 
636     HDF_LOGD("enter");
637 
638     if (ctx->videoCoding == OMX_RK_VIDEO_CodingMJPEG) {
639         MppTask task = nullptr;
640 
641         if (!init_ok) {
642             HDF_LOGE("%s init failed!", __func__);
643             return VPU_API_ERR_VPU_CODEC_INIT;
644         }
645 
646         /* check input param */
647         if (!pkt || !aDecOut) {
648             HDF_LOGE("%s invalid input %p and output %p", __func__, pkt, aDecOut);
649             return VPU_API_ERR_UNKNOW;
650         }
651 
652         if (pkt->size <= 0) {
653             HDF_LOGE("%s invalid input size %d", __func__, pkt->size);
654             return VPU_API_ERR_UNKNOW;
655         }
656 
657         /* try import input buffer and output buffer */
658         RK_S32 fd           = -1;
659         RK_U32 width        = ctx->width;
660         RK_U32 height       = ctx->height;
661         RK_U32 hor_stride   = MPP_ALIGN(width,  16); // (width,  16)
662         RK_U32 ver_stride   = MPP_ALIGN(height, 16); // (height, 16)
663         MppBuffer   str_buf = nullptr; /* input */
664         MppBuffer   pic_buf = nullptr; /* output */
665 
666         ret = (*(mRKMppApi.HdiMppFrameInit))(&mframe);
667         if (MPP_OK != ret) {
668             HDF_LOGE("%s (*(mRKMppApi.HdiMppFrameInit)) failed", __func__);
669             goto DECODE_OUT;
670         }
671 
672         fd = (RK_S32)(pkt->pts & 0xffffffff);
673         if (fd_input < 0) {
674             fd_input = is_valid_dma_fd(fd);
675         }
676 
677         if (fd_input) {
678             MppBufferInfo   inputCommit;
679 
680             memset_s(&inputCommit, sizeof(inputCommit), 0, sizeof(inputCommit));
681             inputCommit.type = MPP_BUFFER_TYPE_ION;
682             inputCommit.size = pkt->size;
683             inputCommit.fd = fd;
684 
685             ret = (*(mRKMppApi.Hdimpp_buffer_import_with_tag))(nullptr, \
686                 &inputCommit, &str_buf, MODULE_TAG, __FUNCTION__);
687             if (ret) {
688                 HDF_LOGE("%s import input picture buffer failed", __func__);
689                 goto DECODE_OUT;
690             }
691         } else {
692             if (pkt->data == nullptr) {
693                 ret = MPP_ERR_NULL_PTR;
694                 goto DECODE_OUT;
695             }
696 
697             ret = (*(mRKMppApi.HdiMppBufferGetWithTag))(memGroup, &str_buf, pkt->size, MODULE_TAG, __FUNCTION__);
698             if (ret) {
699                 HDF_LOGE("%s allocate input picture buffer failed", __func__);
700                 goto DECODE_OUT;
701             }
702             if (memcpy_s((RK_U8*) (*(mRKMppApi.HdiMppBufferGetPtrWithCaller))(str_buf, __FUNCTION__), \
703                 pkt->size, pkt->data, pkt->size) != EOK) {
704                 HDF_LOGE("%s memcpy_s no", __func__);
705             }
706         }
707 
708         fd = (RK_S32)(aDecOut->timeUs & 0xffffffff);
709         if (fd_output < 0) {
710             fd_output = is_valid_dma_fd(fd);
711         }
712 
713         if (fd_output) {
714             MppBufferInfo outputCommit;
715 
716             memset_s(&outputCommit, sizeof(outputCommit), 0, sizeof(outputCommit));
717             /* in order to avoid interface change use space in output to transmit information */
718             outputCommit.type = MPP_BUFFER_TYPE_ION;
719             outputCommit.fd = fd;
720             outputCommit.size = width * height * 3 / 2; // size 3 / 2 bit
721             outputCommit.ptr = (void*)aDecOut->data;
722 
723             ret = (*(mRKMppApi.Hdimpp_buffer_import_with_tag)) \
724                 (nullptr, &outputCommit, &pic_buf, MODULE_TAG, __FUNCTION__);
725             if (ret) {
726                 HDF_LOGE("%s import output stream buffer failed", __func__);
727                 goto DECODE_OUT;
728             }
729         } else {
730             ret = (*(mRKMppApi.HdiMppBufferGetWithTag))
731                 (memGroup, &pic_buf, hor_stride * ver_stride * 3 / 2, MODULE_TAG, __FUNCTION__); // size 3 / 2 bit
732             if (ret) {
733                 HDF_LOGE("%s allocate output stream buffer failed", __func__);
734                 goto DECODE_OUT;
735             }
736         }
737 
738         (*(mRKMppApi.HdiMppPacketInitWithBuffer))(&packet, str_buf); /* input */
739         (*(mRKMppApi.HdiMppFrameSetBuffer))(mframe, pic_buf); /* output */
740 
741         HDF_LOGI("mpp import input fd %d output fd %d", \
742             (*(mRKMppApi.HdiMppBufferGetFdWithCaller))(str_buf, __FUNCTION__), \
743             (*(mRKMppApi.HdiMppBufferGetFdWithCaller))(pic_buf, __FUNCTION__));
744 
745         ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
746         if (ret) {
747             HDF_LOGE("%s mpp input poll failed", __func__);
748             goto DECODE_OUT;
749         }
750 
751         ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
752         if (ret) {
753             HDF_LOGE("%s mpp task input dequeue failed", __func__);
754             goto DECODE_OUT;
755         }
756 
757         (*(mRKMppApi.Hdimpp_task_meta_set_packet))(task, KEY_INPUT_PACKET, packet);
758         (*(mRKMppApi.Hdimpp_task_meta_set_frame))(task, KEY_OUTPUT_FRAME, mframe);
759 
760         ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
761         if (ret) {
762             HDF_LOGE("%s mpp task input enqueue failed", __func__);
763             goto DECODE_OUT;
764         }
765 
766         pkt->size = 0;
767         task = nullptr;
768 
769         ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
770         if (ret) {
771             HDF_LOGE("%s mpp output poll failed", __func__);
772             goto DECODE_OUT;
773         }
774 
775         ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
776         if (ret) {
777             HDF_LOGE("%s ret %d mpp task output dequeue failed", __func__, ret);
778             goto DECODE_OUT;
779         }
780 
781         if (task) {
782             MppFrame frame_out = nullptr;
783 
784             (*(mRKMppApi.Hdimpp_task_meta_get_frame))(task, KEY_OUTPUT_FRAME, &frame_out);
785             HDF_LOGD("decoded frame %d", frame_count);
786             frame_count++;
787 
788             ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
789             if (ret) {
790                 HDF_LOGE("%s mpp task output enqueue failed", __func__);
791                 goto DECODE_OUT;
792             }
793             task = nullptr;
794         }
795 
796         // copy decoded frame into output buffer, and set outpub frame size
797         if (mframe != nullptr) {
798             MppBuffer buf_out = (*(mRKMppApi.HdiMppFrameGetBuffer))(mframe);
799             size_t len  = (*(mRKMppApi.Hdimpp_buffer_get_size_with_caller))(buf_out, __FUNCTION__);
800             aDecOut->size = len;
801 
802             if (fd_output) {
803                 HDF_LOGE("%s fd for output is invalid!", __func__);
804                 aDecOut->data = (RK_U8*)(*(mRKMppApi.Hdimpp_osal_malloc))
805                     (__FUNCTION__, sizeof(RK_U8) * (width * height * 3 / 2)); // size 3 / 2 bit
806                 if ( memcpy_s(aDecOut->data,  aDecOut->size, \
807                     (RK_U8*) (*(mRKMppApi.HdiMppBufferGetPtrWithCaller))(pic_buf, __FUNCTION__), \
808                     aDecOut->size) != EOK) {
809                     HDF_LOGE("%s memcpy_s no", __func__);
810                 }
811             }
812 
813             HDF_LOGI("get frame %p size %d", mframe, len);
814 
815             (*(mRKMppApi.HdiMppFrameDeinit))(&mframe);
816         } else {
817             HDF_LOGE("%s outputPacket is nullptr!", __func__);
818         }
819 
820     DECODE_OUT:
821         if (str_buf) {
822             (*(mRKMppApi.HdiMppBufferPutWithCaller))(str_buf, __FUNCTION__);
823             str_buf = nullptr;
824         }
825 
826         if (pic_buf) {
827             (*(mRKMppApi.HdiMppBufferPutWithCaller))(pic_buf, __FUNCTION__);
828             pic_buf = nullptr;
829         }
830     } else {
831         (*(mRKMppApi.HdiMppPacketInit))(&packet, pkt->data, pkt->size);
832         (*(mRKMppApi.HdiMppPacketSetPts))(packet, pkt->pts);
833         if (pkt->nFlags & OMX_BUFFERFLAG_EOS) {
834             (*(mRKMppApi.HdiMppPacketSetEos))(packet);
835         }
836 
837         HDF_LOGD("input size %-6d flag %x pts %lld", \
838             pkt->size, pkt->nFlags, pkt->pts);
839 
840         ret = mpi->decode(mpp_ctx, packet, &mframe);
841         if (MPP_OK == ret) {
842             pkt->size = 0;
843         }
844         if (ret || mframe == nullptr) {
845             aDecOut->size = 0;
846         } else {
847             VPU_FRAME *vframe = (VPU_FRAME *)aDecOut->data;
848             MppBuffer buf = (*(mRKMppApi.HdiMppFrameGetBuffer))(mframe);
849 
850             setup_VPU_FRAME_from_mpp_frame(vframe, mframe);
851 
852             aDecOut->size = sizeof(VPU_FRAME);
853             aDecOut->timeUs = (*(mRKMppApi.Hdimpp_frame_get_pts))(mframe);
854             frame_count++;
855 
856             if ((*(mRKMppApi.HdiMppFrameGetEos))(mframe)) {
857                 set_eos = 1;
858                 if (buf == nullptr) {
859                     aDecOut->size = 0;
860                 }
861             }
862             if (vpu_api_debug & VPU_API_DBG_OUTPUT) {
863                 HDF_LOGD("get one frame pts %lld, fd 0x%x, poc %d, errinfo %x, discard %d, eos %d, verr %d", \
864                     aDecOut->timeUs, \
865                     ((buf) ? ((*(mRKMppApi.HdiMppBufferGetFdWithCaller))(buf, __FUNCTION__)) : (-1)), \
866                     (*(mRKMppApi.Hdimpp_frame_get_poc))(mframe), \
867                     (*(mRKMppApi.HdiMppFrameGetErrinfo))(mframe), \
868                     (*(mRKMppApi.HdiMppFrameGetDiscard))(mframe), \
869                     (*(mRKMppApi.HdiMppFrameGetEos))(mframe), vframe->ErrorInfo);
870             }
871 
872             /*
873              * IMPORTANT: mframe is malloced from mpi->decode_get_frame
874              * So we need to deinit mframe here. But the buffer in the frame should not be free with mframe.
875              * Because buffer need to be set to vframe->vpumem.offset and send to display.
876              * The we have to clear the buffer pointer in mframe then release mframe.
877              */
878             (*(mRKMppApi.HdiMppFrameDeinit))(&mframe);
879         }
880     }
881 
882     if (packet)
883         (*(mRKMppApi.HdiMppPacketDeinit))(&packet);
884 
885     if (mframe)
886         (*(mRKMppApi.HdiMppFrameDeinit))(&mframe);
887 
888     HDF_LOGD("leave ret %d", ret);
889     return ret;
890 }
891 
decode_sendstream(VideoPacket_t * pkt)892 RK_S32 VpuApiLegacy::decode_sendstream(VideoPacket_t *pkt)
893 {
894     HDF_LOGD("enter");
895 
896     RK_S32 ret = MPP_OK;
897     MppPacket mpkt = nullptr;
898 
899     if (!init_ok) {
900         return VPU_API_ERR_VPU_CODEC_INIT;
901     }
902 
903     (*(mRKMppApi.HdiMppPacketInit))(&mpkt, pkt->data, pkt->size);
904     (*(mRKMppApi.HdiMppPacketSetPts))(mpkt, pkt->pts);
905     if (pkt->nFlags & OMX_BUFFERFLAG_EOS) {
906         (*(mRKMppApi.HdiMppPacketSetEos))(mpkt);
907     }
908 
909     HDF_LOGD("input size %-6d flag %x pts %lld", \
910         pkt->size, pkt->nFlags, pkt->pts);
911 
912     ret = mpi->decode_put_packet(mpp_ctx, mpkt);
913     if (ret == MPP_OK) {
914         pkt->size = 0;
915     } else {
916         /* reduce cpu overhead here */
917         msleep(1);
918     }
919 
920     (*(mRKMppApi.HdiMppPacketDeinit))(&mpkt);
921 
922     HDF_LOGD("leave ret %d", ret);
923     /* NOTE: always return success for old player compatibility */
924     return MPP_OK;
925 }
926 
decode_getoutframe(DecoderOut_t * aDecOut)927 RK_S32 VpuApiLegacy::decode_getoutframe(DecoderOut_t *aDecOut)
928 {
929     RK_S32 ret = 0;
930     VPU_FRAME *vframe = (VPU_FRAME *)aDecOut->data;
931     MppFrame  mframe = nullptr;
932 
933     HDF_LOGD("enter");
934 
935     if (!init_ok) {
936         return VPU_API_ERR_VPU_CODEC_INIT;
937     }
938 
939     memset_s(vframe, sizeof(VPU_FRAME), 0, sizeof(VPU_FRAME));
940 
941     if (mpi == nullptr) {
942         aDecOut->size = 0;
943         return 0;
944     }
945 
946     if (set_eos) {
947         aDecOut->size = 0;
948         mEosSet = 1;
949         return VPU_API_EOS_STREAM_REACHED;
950     }
951 
952     ret = mpi->decode_get_frame(mpp_ctx, &mframe);
953     if (ret || mframe == nullptr) {
954         aDecOut->size = 0;
955     } else {
956         MppBuffer buf = (*(mRKMppApi.HdiMppFrameGetBuffer))(mframe);
957 
958         setup_VPU_FRAME_from_mpp_frame(vframe, mframe);
959 
960         aDecOut->size = sizeof(VPU_FRAME);
961         aDecOut->timeUs = (*(mRKMppApi.Hdimpp_frame_get_pts))(mframe);
962         frame_count++;
963 
964         if ((*(mRKMppApi.HdiMppFrameGetEos))(mframe) && !(*(mRKMppApi.HdiMppFrameGetInfoChange))(mframe)) {
965             set_eos = 1;
966             if (buf == nullptr) {
967                 aDecOut->size = 0;
968                 mEosSet = 1;
969                 ret = VPU_API_EOS_STREAM_REACHED;
970             } else {
971                 aDecOut->nFlags |= VPU_API_EOS_STREAM_REACHED;
972             }
973         }
974         if (vpu_api_debug & VPU_API_DBG_OUTPUT) {
975             HDF_LOGD("get one frame pts %lld, fd 0x%x, poc %d, errinfo %x, discard %d, eos %d, verr %d", \
976                 aDecOut->timeUs, \
977                 ((buf) ? ((*(mRKMppApi.HdiMppBufferGetFdWithCaller))(buf, __FUNCTION__)) : (-1)), \
978                 (*(mRKMppApi.Hdimpp_frame_get_poc))(mframe), \
979                 (*(mRKMppApi.HdiMppFrameGetErrinfo))(mframe), \
980                 (*(mRKMppApi.HdiMppFrameGetDiscard))(mframe), \
981                 (*(mRKMppApi.HdiMppFrameGetEos))(mframe), vframe->ErrorInfo);
982         }
983 
984         /*
985          * IMPORTANT: mframe is malloced from mpi->decode_get_frame
986          * So we need to deinit mframe here. But the buffer in the frame should not be free with mframe.
987          * Because buffer need to be set to vframe->vpumem.offset and send to display.
988          * The we have to clear the buffer pointer in mframe then release mframe.
989          */
990         (*(mRKMppApi.HdiMppFrameDeinit))(&mframe);
991     }
992 
993     HDF_LOGD("leave ret %d", ret);
994 
995     return ret;
996 }
997 
encode(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm,EncoderOut_t * aEncOut)998 RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut)
999 {
1000     MPP_RET ret = MPP_OK;
1001     MppTask task = nullptr;
1002     HDF_LOGD("enter");
1003 
1004     if (!init_ok)
1005         return VPU_API_ERR_VPU_CODEC_INIT;
1006 
1007     /* check input param */
1008     if (!aEncInStrm || !aEncOut) {
1009         HDF_LOGE("%s invalid input %p and output %p", __func__, aEncInStrm, aEncOut);
1010         return VPU_API_ERR_UNKNOW;
1011     }
1012 
1013     if (aEncInStrm->buf == nullptr || aEncInStrm->size == 0) {
1014         HDF_LOGE("%s invalid input buffer %p size %d", __func__, aEncInStrm->buf, aEncInStrm->size);
1015         return VPU_API_ERR_UNKNOW;
1016     }
1017 
1018     /* try import input buffer and output buffer */
1019     RK_S32 fd           = -1;
1020     RK_U32 width        = ctx->width;
1021     RK_U32 height       = ctx->height;
1022     RK_U32 hor_stride   = MPP_ALIGN(width,  16);
1023     RK_U32 ver_stride   = MPP_ALIGN(height, 16);
1024     MppFrame    frame   = nullptr;
1025     MppPacket   packet  = nullptr;
1026     MppBuffer   pic_buf = nullptr;
1027     MppBuffer   str_buf = nullptr;
1028 
1029     ret = (*(mRKMppApi.HdiMppFrameInit))(&frame);
1030     if (MPP_OK != ret) {
1031         HDF_LOGE("%s (*(mRKMppApi.HdiMppFrameInit)) failed", __func__);
1032         goto ENCODE_OUT;
1033     }
1034 
1035     (*(mRKMppApi.HdiMppFrameSetWidth))(frame, width);
1036     (*(mRKMppApi.HdiMppFrameSetHeight))(frame, height);
1037     (*(mRKMppApi.HdiMppFrameSetHorStride))(frame, hor_stride);
1038     (*(mRKMppApi.HdiMppFrameSetVerStride))(frame, ver_stride);
1039 
1040     fd = aEncInStrm->bufPhyAddr;
1041     if (fd_input < 0) {
1042         fd_input = is_valid_dma_fd(fd);
1043     }
1044     if (fd_input) {
1045         MppBufferInfo   inputCommit;
1046 
1047         memset_s(&inputCommit, sizeof(inputCommit), 0, sizeof(inputCommit));
1048         inputCommit.type = MPP_BUFFER_TYPE_ION;
1049         inputCommit.size = aEncInStrm->size;
1050         inputCommit.fd = fd;
1051 
1052         ret = (*(mRKMppApi.Hdimpp_buffer_import_with_tag))(nullptr, &inputCommit, \
1053             &pic_buf, MODULE_TAG, __FUNCTION__);
1054         if (ret) {
1055             HDF_LOGE("%s import input picture buffer failed", __func__);
1056             goto ENCODE_OUT;
1057         }
1058     } else {
1059         if (aEncInStrm->buf == nullptr) {
1060             ret = MPP_ERR_NULL_PTR;
1061             goto ENCODE_OUT;
1062         }
1063 
1064         ret = (*(mRKMppApi.HdiMppBufferGetWithTag))(memGroup, &pic_buf, aEncInStrm->size, MODULE_TAG, __FUNCTION__);
1065         if (ret) {
1066             HDF_LOGE("%s allocate input picture buffer failed", __func__);
1067             goto ENCODE_OUT;
1068         }
1069         if (memcpy_s((RK_U8*) (*(mRKMppApi.HdiMppBufferGetPtrWithCaller))(pic_buf, __FUNCTION__), \
1070             aEncInStrm->size, aEncInStrm->buf, aEncInStrm->size) != EOK) {
1071             HDF_LOGE("%s memcpy_s no", __func__);
1072         }
1073     }
1074 
1075     fd = (RK_S32)(aEncOut->timeUs & 0xffffffff);
1076 
1077     if (fd_output < 0) {
1078         fd_output = is_valid_dma_fd(fd);
1079     }
1080     if (fd_output) {
1081         RK_S32 *tmp = (RK_S32*)(&aEncOut->timeUs);
1082         MppBufferInfo outputCommit;
1083 
1084         memset_s(&outputCommit, sizeof(outputCommit), 0, sizeof(outputCommit));
1085         /* in order to avoid interface change use space in output to transmit information */
1086         outputCommit.type = MPP_BUFFER_TYPE_ION;
1087         outputCommit.fd = fd;
1088         outputCommit.size = tmp[1];
1089         outputCommit.ptr = (void*)aEncOut->data;
1090 
1091         ret = (*(mRKMppApi.Hdimpp_buffer_import_with_tag))(nullptr, &outputCommit, &str_buf, MODULE_TAG, __FUNCTION__);
1092         if (ret) {
1093             HDF_LOGE("%s import output stream buffer failed", __func__);
1094             goto ENCODE_OUT;
1095         }
1096     } else {
1097         ret = (*(mRKMppApi.HdiMppBufferGetWithTag))(memGroup, \
1098             &str_buf, hor_stride * ver_stride, MODULE_TAG, __FUNCTION__);
1099         if (ret) {
1100             HDF_LOGE("%s allocate output stream buffer failed", __func__);
1101             goto ENCODE_OUT;
1102         }
1103     }
1104 
1105     (*(mRKMppApi.HdiMppFrameSetBuffer))(frame, pic_buf);
1106     (*(mRKMppApi.HdiMppPacketInitWithBuffer))(&packet, str_buf);
1107     (*(mRKMppApi.HdiMppPacketSetLength))(packet, 0);
1108 
1109     HDF_LOGD("mpp import input fd %d output fd %d", \
1110         (*(mRKMppApi.HdiMppBufferGetFdWithCaller))(pic_buf, __FUNCTION__), \
1111         (*(mRKMppApi.HdiMppBufferGetFdWithCaller))(str_buf, __FUNCTION__));
1112 
1113     ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
1114     if (ret) {
1115         HDF_LOGE("%s mpp input poll failed", __func__);
1116         goto ENCODE_OUT;
1117     }
1118 
1119     ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
1120     if (ret) {
1121         HDF_LOGE("%s mpp task input dequeue failed", __func__);
1122         goto ENCODE_OUT;
1123     }
1124     if (task == nullptr) {
1125         HDF_LOGE("%s mpi dequeue from MPP_PORT_INPUT fail, task equal with nullptr!", __func__);
1126         goto ENCODE_OUT;
1127     }
1128 
1129     (*(mRKMppApi.Hdimpp_task_meta_set_frame)) (task, KEY_INPUT_FRAME,  frame);
1130     (*(mRKMppApi.Hdimpp_task_meta_set_packet))(task, KEY_OUTPUT_PACKET, packet);
1131 
1132     ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
1133     if (ret) {
1134         HDF_LOGE("%s mpp task input enqueue failed", __func__);
1135         goto ENCODE_OUT;
1136     }
1137     task = nullptr;
1138 
1139     ret = mpi->poll(mpp_ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
1140     if (ret) {
1141         HDF_LOGE("%s mpp output poll failed", __func__);
1142         goto ENCODE_OUT;
1143     }
1144 
1145     ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
1146     if (ret) {
1147         HDF_LOGE("%s ret %d mpp task output dequeue failed", __func__, ret);
1148         goto ENCODE_OUT;
1149     }
1150 
1151     if (task) {
1152         MppFrame frame_out = nullptr;
1153         MppFrame packet_out = nullptr;
1154 
1155         (*(mRKMppApi.HdiMppTaskMetaGetPacket))(task, KEY_OUTPUT_PACKET, &packet_out);
1156 
1157         HDF_LOGD("encoded frame %d", frame_count);
1158         frame_count++;
1159 
1160         ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
1161         if (ret) {
1162             HDF_LOGE("%s mpp task output enqueue failed", __func__);
1163             goto ENCODE_OUT;
1164         }
1165         task = nullptr;
1166 
1167         ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
1168         if (ret) {
1169             HDF_LOGE("%s mpp input poll failed", __func__);
1170             goto ENCODE_OUT;
1171         }
1172 
1173         // dequeue task from MPP_PORT_INPUT
1174         ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
1175         if (ret) {
1176             HDF_LOGE("%s failed to dequeue from input port ret %d", __func__, ret);
1177             goto ENCODE_OUT;
1178         }
1179         ret = (*(mRKMppApi.Hdimpp_task_meta_get_frame))(task, KEY_INPUT_FRAME, &frame_out);
1180         ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
1181         if (ret) {
1182             HDF_LOGE("%s mpp task output enqueue failed", __func__);
1183             goto ENCODE_OUT;
1184         }
1185         task = nullptr;
1186     }
1187 
1188     // copy encoded stream into output buffer, and set output stream size
1189     if (packet) {
1190         RK_U32 eos = (*(mRKMppApi.HdiMppPacketGetEos))(packet);
1191         RK_S64 pts = (*(mRKMppApi.HdiMppPacketGetPts))(packet);
1192         size_t length = (*(mRKMppApi.HdiMppPacketGetLength))(packet);
1193         MppMeta meta = (*(mRKMppApi.Hdimpp_packet_get_meta))(packet);
1194         RK_S32 is_intra = 0;
1195 
1196         if (!fd_output) {
1197             RK_U8 *src = (RK_U8 *)(*(mRKMppApi.Hdimpp_packet_get_data))(packet);
1198             size_t buffer = MPP_ALIGN(length, SZ_4K);
1199 
1200             aEncOut->data = (RK_U8*)(*(mRKMppApi.Hdimpp_osal_malloc))(__FUNCTION__, sizeof(RK_U8)*buffer);
1201 
1202             if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC) {
1203                 // remove first 00 00 00 01
1204                 length -= 4; // length -= 4
1205                 if (memcpy_s(aEncOut->data, length, src + 4, length) != EOK) { // length -= 4
1206                     HDF_LOGE("%s memcpy_s no", __func__);
1207                 }
1208             } else {
1209                 if (memcpy_s(aEncOut->data, length, src, length) != EOK) {
1210                     HDF_LOGE("%s memcpy_s no", __func__);
1211                 }
1212             }
1213         }
1214 
1215         (*(mRKMppApi.Hdimpp_meta_get_s32))(meta, KEY_OUTPUT_INTRA, &is_intra);
1216 
1217         aEncOut->size = (RK_S32)length;
1218         aEncOut->timeUs = pts;
1219         aEncOut->keyFrame = is_intra;
1220 
1221         HDF_LOGD("get packet %p size %d pts %lld keyframe %d eos %d", \
1222             packet, length, pts, aEncOut->keyFrame, eos);
1223 
1224         (*(mRKMppApi.HdiMppPacketDeinit))(&packet);
1225     } else {
1226         HDF_LOGE("%s outputPacket is nullptr!", __func__);
1227     }
1228 
1229 ENCODE_OUT:
1230     if (pic_buf) {
1231         (*(mRKMppApi.HdiMppBufferPutWithCaller))(pic_buf, __FUNCTION__);
1232         pic_buf = nullptr;
1233     }
1234 
1235     if (str_buf) {
1236         (*(mRKMppApi.HdiMppBufferPutWithCaller))(str_buf, __FUNCTION__);
1237         str_buf = nullptr;
1238     }
1239 
1240     if (frame)
1241         (*(mRKMppApi.HdiMppFrameDeinit))(&frame);
1242 
1243     if (packet)
1244         (*(mRKMppApi.HdiMppPacketDeinit))(&packet);
1245 
1246     HDF_LOGD("leave ret %d", ret);
1247 
1248     return ret;
1249 }
1250 
encoder_sendframe(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm)1251 RK_S32 VpuApiLegacy::encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm)
1252 {
1253     RK_S32 ret = 0;
1254     HDF_LOGD("enter");
1255 
1256     RK_U32 width        = ctx->width;
1257     RK_U32 height       = ctx->height;
1258     RK_U32 hor_stride   = MPP_ALIGN(width,  16);
1259     RK_U32 ver_stride   = MPP_ALIGN(height, 8);
1260     RK_S64 pts          = aEncInStrm->timeUs;
1261     RK_S32 fd           = aEncInStrm->bufPhyAddr;
1262     RK_U32 size         = aEncInStrm->size;
1263 
1264     /* try import input buffer and output buffer */
1265     MppFrame frame = nullptr;
1266 
1267     ret = (*(mRKMppApi.HdiMppFrameInit))(&frame);
1268     if (MPP_OK != ret) {
1269         HDF_LOGE("%s (*(mRKMppApi.HdiMppFrameInit)) failed", __func__);
1270         goto FUNC_RET;
1271     }
1272 
1273     (*(mRKMppApi.HdiMppFrameSetWidth))(frame, width);
1274     (*(mRKMppApi.HdiMppFrameSetHeight))(frame, height);
1275     (*(mRKMppApi.HdiMppFrameSetHorStride))(frame, hor_stride);
1276     (*(mRKMppApi.HdiMppFrameSetVerStride))(frame, ver_stride);
1277     (*(mRKMppApi.Hdimpp_frame_set_pts))(frame, pts);
1278 
1279     if (aEncInStrm->nFlags) {
1280         HDF_LOGE("%s found eos true", __func__);
1281         (*(mRKMppApi.HdiMppFrameSetEos))(frame, 1);
1282     }
1283 
1284     if (size <= 0) {
1285         (*(mRKMppApi.HdiMppFrameSetBuffer))(frame, nullptr);
1286         if (!aEncInStrm->nFlags)
1287             HDF_LOGE("%s found empty frame without eos flag set!", __func__);
1288         goto PUT_FRAME;
1289     }
1290 
1291     if (fd_input < 0) {
1292         fd_input = is_valid_dma_fd(fd);
1293     }
1294     if (fd_input) {
1295         MppBufferInfo   inputCommit;
1296 
1297         memset_s(&inputCommit, sizeof(inputCommit), 0, sizeof(inputCommit));
1298         inputCommit.type = MPP_BUFFER_TYPE_ION;
1299         inputCommit.size = size;
1300         inputCommit.fd = fd;
1301         if (size > 0) {
1302             MppBuffer buffer = nullptr;
1303             ret = (*(mRKMppApi.Hdimpp_buffer_import_with_tag))(nullptr, \
1304                 &inputCommit, &buffer, MODULE_TAG, __FUNCTION__);
1305             if (ret) {
1306                 HDF_LOGE("%s import input picture buffer failed", __func__);
1307                 goto FUNC_RET;
1308             }
1309             (*(mRKMppApi.HdiMppFrameSetBuffer))(frame, buffer);
1310             (*(mRKMppApi.HdiMppBufferPutWithCaller))(buffer, __FUNCTION__);
1311             buffer = nullptr;
1312         }
1313     } else {
1314         RK_U32 align_size   = 0;
1315 
1316         if (aEncInStrm->buf == nullptr) {
1317             ret = MPP_ERR_NULL_PTR;
1318             goto FUNC_RET;
1319         }
1320         if (format >= MPP_FMT_YUV420SP && format < MPP_FMT_YUV_BUTT) {
1321             align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 3 / 2; // (ver_stride, 16) * 3 / 2 bit
1322         } else if (format >= MPP_FMT_RGB565 && format < MPP_FMT_BGR888) {
1323             align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 3; // (ver_stride, 16) * 3 bit
1324         } else if (format >= MPP_FMT_RGB101010 && format < MPP_FMT_RGB_BUTT) {
1325             align_size = hor_stride * MPP_ALIGN(ver_stride, 16) * 4; // (ver_stride, 16) * 4 bit
1326         } else {
1327             HDF_LOGE("%s unsupport input format:%d", __func__, format);
1328             ret = MPP_NOK;
1329             goto FUNC_RET;
1330         }
1331         if (align_size > 0) {
1332             MppBuffer buffer = nullptr;
1333             ret = (*(mRKMppApi.HdiMppBufferGetWithTag))(memGroup, &buffer, align_size, MODULE_TAG, __FUNCTION__);
1334             if (ret) {
1335                 HDF_LOGE("%s allocate input picture buffer failed", __func__);
1336                 goto FUNC_RET;
1337             }
1338             copy_align_raw_buffer_to_dest((RK_U8 *)(*(mRKMppApi.HdiMppBufferGetPtrWithCaller))(buffer, __FUNCTION__),
1339                 aEncInStrm->buf, width, height, format);
1340             (*(mRKMppApi.HdiMppFrameSetBuffer))(frame, buffer);
1341             (*(mRKMppApi.HdiMppBufferPutWithCaller))(buffer, __FUNCTION__);
1342             buffer = nullptr;
1343         }
1344     }
1345 
1346 PUT_FRAME:
1347 
1348     HDF_LOGD("w %d h %d input fd %d size %d pts %lld, flag %d ", \
1349         width, height, fd, size, aEncInStrm->timeUs, aEncInStrm->nFlags);
1350     if (mlvec) {
1351         MppMeta meta = (*(mRKMppApi.HdiMppFrameGetMeta))(frame);
1352 
1353         vpu_api_mlvec_set_dy_cfg(mlvec, &mlvec_dy_cfg, meta);
1354     }
1355 
1356     ret = mpi->encode_put_frame(mpp_ctx, frame);
1357     if (ret)
1358         HDF_LOGE("%s encode_put_frame ret %d", __func__, ret);
1359     else
1360         aEncInStrm->size = 0;
1361 
1362 FUNC_RET:
1363     if (frame)
1364         (*(mRKMppApi.HdiMppFrameDeinit))(&frame);
1365 
1366     HDF_LOGD("leave ret %d", ret);
1367     return ret;
1368 }
1369 
encoder_getstream(VpuCodecContext * ctx,EncoderOut_t * aEncOut)1370 RK_S32 VpuApiLegacy::encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut)
1371 {
1372     RK_S32 ret = 0;
1373     MppPacket packet = nullptr;
1374     HDF_LOGD("enter");
1375 
1376     ret = mpi->encode_get_packet(mpp_ctx, &packet);
1377     if (ret) {
1378         HDF_LOGE("%s encode_get_packet failed ret %d", __func__, ret);
1379         goto FUNC_RET;
1380     }
1381     if (packet) {
1382         RK_U8 *src = (RK_U8 *)(*(mRKMppApi.Hdimpp_packet_get_data))(packet);
1383         RK_U32 eos = (*(mRKMppApi.HdiMppPacketGetEos))(packet);
1384         RK_S64 pts = (*(mRKMppApi.HdiMppPacketGetPts))(packet);
1385         size_t length = (*(mRKMppApi.HdiMppPacketGetLength))(packet);
1386         MppMeta meta = (*(mRKMppApi.Hdimpp_packet_get_meta))(packet);
1387         RK_S32 is_intra = 0;
1388 
1389         RK_U32 offset = 0;
1390         if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC) {
1391             offset = 4; //  offset = 4
1392             length = (length > offset) ? (length - offset) : 0;
1393         }
1394         aEncOut->data = nullptr;
1395         if (length > 0) {
1396             aEncOut->data = (RK_U8*)(*(mRKMppApi.Hdimpp_osal_calloc)) \
1397                 (__FUNCTION__, sizeof(RK_U8)*MPP_ALIGN(length + 16, SZ_4K)); // length + 16
1398             if (aEncOut->data) {
1399                 if (memcpy_s(aEncOut->data, length, src + offset, length) != EOK) {
1400                     HDF_LOGE("%s memcpy_s no", __func__);
1401                 }
1402             }
1403         }
1404 
1405         (*(mRKMppApi.Hdimpp_meta_get_s32))(meta, KEY_OUTPUT_INTRA, &is_intra);
1406 
1407         aEncOut->size = (RK_S32)length;
1408         aEncOut->timeUs = pts;
1409         aEncOut->keyFrame = is_intra;
1410 
1411         HDF_LOGD("get packet %p size %d pts %lld keyframe %d eos %d", \
1412             packet, length, pts, aEncOut->keyFrame, eos);
1413 
1414         mEosSet = eos;
1415         (*(mRKMppApi.HdiMppPacketDeinit))(&packet);
1416     } else {
1417         aEncOut->size = 0;
1418         HDF_LOGE("%s get nullptr packet, eos %d", __func__, mEosSet);
1419         if (mEosSet)
1420             ret = -1;
1421     }
1422 
1423 FUNC_RET:
1424     HDF_LOGD("leave ret %d", ret);
1425     return ret;
1426 }
1427 
perform(PerformCmd cmd,RK_S32 * data)1428 RK_S32 VpuApiLegacy::perform(PerformCmd cmd, RK_S32 *data)
1429 {
1430     HDF_LOGD("enter");
1431     switch (cmd) {
1432         case INPUT_FORMAT_MAP : {
1433             EncInputPictureType vpu_frame_fmt = *(EncInputPictureType *)data;
1434             MppFrameFormat mpp_frame_fmt = vpu_pic_type_remap_to_mpp(vpu_frame_fmt);
1435             *(MppFrameFormat *)data = mpp_frame_fmt;
1436             } break;
1437         default:
1438             HDF_LOGE("%s cmd can not match with any option!", __func__);
1439             break;
1440     }
1441     HDF_LOGD("leave");
1442     return 0;
1443 }
1444 
control(VpuCodecContext * ctx,VPU_API_CMD cmd,void * param)1445 RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
1446 {
1447     HDF_LOGD("enter cmd 0x%x param %p", cmd, param);
1448 
1449     if (mpi == nullptr && !init_ok) {
1450         return 0;
1451     }
1452 
1453     MpiCmd mpicmd = MPI_CMD_BUTT;
1454     switch (cmd) {
1455         case VPU_API_ENABLE_DEINTERLACE : {
1456             mpicmd = MPP_DEC_SET_ENABLE_DEINTERLACE;
1457             } break;
1458         case VPU_API_ENC_SETCFG : {
1459             MppCodingType coding = (MppCodingType)ctx->videoCoding;
1460 
1461             if (memcpy_s(&enc_param, sizeof(enc_param), param, sizeof(enc_param)) != EOK) {
1462                 HDF_LOGE("%s memcpy_s no", __func__);
1463             }
1464             return vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, &enc_param);
1465             } break;
1466         case VPU_API_ENC_GETCFG : {
1467             if (memcpy_s(param, sizeof(enc_param), &enc_param, sizeof(enc_param)) != EOK) {
1468                 HDF_LOGE("%s memcpy_s no", __func__);
1469             }
1470             return 0;
1471             } break;
1472         case VPU_API_ENC_SETFORMAT : {
1473             EncInputPictureType type = *((EncInputPictureType *)param);
1474             format = vpu_pic_type_remap_to_mpp(type);
1475             return 0;
1476             } break;
1477         case VPU_API_ENC_SETIDRFRAME : {
1478             mpicmd = MPP_ENC_SET_IDR_FRAME;
1479             } break;
1480         case VPU_API_SET_VPUMEM_CONTEXT: {
1481             mpicmd = MPP_DEC_SET_EXT_BUF_GROUP;
1482             } break;
1483         case VPU_API_USE_PRESENT_TIME_ORDER: {
1484             mpicmd = MPP_DEC_SET_PRESENT_TIME_ORDER;
1485             } break;
1486         case VPU_API_SET_INFO_CHANGE: {
1487             mpicmd = MPP_DEC_SET_INFO_CHANGE_READY;
1488             } break;
1489         case VPU_API_USE_FAST_MODE: {
1490             mpicmd = MPP_DEC_SET_PARSER_FAST_MODE;
1491             } break;
1492         case VPU_API_DEC_GET_STREAM_COUNT: {
1493             mpicmd = MPP_DEC_GET_STREAM_COUNT;
1494             } break;
1495         case VPU_API_GET_VPUMEM_USED_COUNT: {
1496             mpicmd = MPP_DEC_GET_VPUMEM_USED_COUNT;
1497             } break;
1498         case VPU_API_SET_OUTPUT_BLOCK: {
1499             mpicmd = MPP_SET_OUTPUT_TIMEOUT;
1500             if (param) {
1501                 RK_S32 timeout = *((RK_S32*)param);
1502 
1503                 if (timeout) {
1504                     if (timeout < 0)
1505                         HDF_LOGI("set output mode to block");
1506                     else
1507                         HDF_LOGI("set output timeout %d ms", timeout);
1508                 } else {
1509                     HDF_LOGI("set output mode to non-block");
1510                 }
1511             }
1512             } break;
1513         case VPU_API_GET_EOS_STATUS: {
1514             *((RK_S32 *)param) = mEosSet;
1515             mpicmd = MPI_CMD_BUTT;
1516             } break;
1517         case VPU_API_GET_FRAME_INFO: {
1518             *((VPU_GENERIC *)param) = vpug;
1519             mpicmd = MPI_CMD_BUTT;
1520             } break;
1521         case VPU_API_SET_OUTPUT_MODE: {
1522             mpicmd = MPP_DEC_SET_OUTPUT_FORMAT;
1523             } break;
1524         case VPU_API_SET_IMMEDIATE_OUT: {
1525             mpicmd = MPP_DEC_SET_IMMEDIATE_OUT;
1526             } break;
1527         case VPU_API_ENC_SET_VEPU22_CFG: {
1528             mpicmd = MPP_ENC_SET_CODEC_CFG;
1529             } break;
1530         case VPU_API_ENC_GET_VEPU22_CFG: {
1531             mpicmd = MPP_ENC_GET_CODEC_CFG;
1532             } break;
1533         case VPU_API_ENC_SET_VEPU22_CTU_QP: {
1534             mpicmd = MPP_ENC_SET_CTU_QP;
1535             } break;
1536         case VPU_API_ENC_SET_VEPU22_ROI: {
1537             mpicmd = MPP_ENC_SET_ROI_CFG;
1538             } break;
1539         case VPU_API_ENC_SET_MAX_TID: {
1540             RK_S32 max_tid = *(RK_S32 *)param;
1541 
1542             HDF_LOGI("VPU_API_ENC_SET_MAX_TID %d", max_tid);
1543             mlvec_dy_cfg.max_tid = max_tid;
1544             mlvec_dy_cfg.updated |= VPU_API_ENC_MAX_TID_UPDATED;
1545 
1546             if (mlvec)
1547                 vpu_api_mlvec_set_dy_max_tid(mlvec, max_tid);
1548 
1549             return 0;
1550             } break;
1551         case VPU_API_ENC_SET_MARK_LTR: {
1552             RK_S32 mark_ltr = *(RK_S32 *)param;
1553 
1554             HDF_LOGI("VPU_API_ENC_SET_MARK_LTR %d", mark_ltr);
1555 
1556             mlvec_dy_cfg.mark_ltr = mark_ltr;
1557             if (mark_ltr >= 0)
1558                 mlvec_dy_cfg.updated |= VPU_API_ENC_MARK_LTR_UPDATED;
1559 
1560             return 0;
1561             } break;
1562         case VPU_API_ENC_SET_USE_LTR: {
1563             RK_S32 use_ltr = *(RK_S32 *)param;
1564 
1565             HDF_LOGI("VPU_API_ENC_SET_USE_LTR %d", use_ltr);
1566 
1567             mlvec_dy_cfg.use_ltr = use_ltr;
1568             mlvec_dy_cfg.updated |= VPU_API_ENC_USE_LTR_UPDATED;
1569 
1570             return 0;
1571             } break;
1572         case VPU_API_ENC_SET_FRAME_QP: {
1573             RK_S32 frame_qp = *(RK_S32 *)param;
1574 
1575             HDF_LOGI("VPU_API_ENC_SET_FRAME_QP %d", frame_qp);
1576 
1577             mlvec_dy_cfg.frame_qp = frame_qp;
1578             mlvec_dy_cfg.updated |= VPU_API_ENC_FRAME_QP_UPDATED;
1579 
1580             return 0;
1581             } break;
1582         case VPU_API_ENC_SET_BASE_LAYER_PID: {
1583             RK_S32 base_layer_pid = *(RK_S32 *)param;
1584 
1585             HDF_LOGI("VPU_API_ENC_SET_BASE_LAYER_PID %d", base_layer_pid);
1586 
1587             mlvec_dy_cfg.base_layer_pid = base_layer_pid;
1588             mlvec_dy_cfg.updated |= VPU_API_ENC_BASE_PID_UPDATED;
1589 
1590             return 0;
1591             } break;
1592         case VPU_API_GET_EXTRA_INFO: {
1593             EncoderOut_t *out = (EncoderOut_t *)param;
1594 
1595             HDF_LOGI("VPU_API_GET_EXTRA_INFO");
1596 
1597             if (enc_hdr_pkt == nullptr) {
1598                 if (enc_hdr_buf == nullptr) {
1599                     enc_hdr_buf_size = SZ_1K;
1600                     enc_hdr_buf = (*(mRKMppApi.Hdimpp_osal_calloc))(__FUNCTION__, enc_hdr_buf_size);
1601                 }
1602 
1603                 if (enc_hdr_buf)
1604                     (*(mRKMppApi.HdiMppPacketInit))(&enc_hdr_pkt, enc_hdr_buf, enc_hdr_buf_size);
1605             }
1606 
1607             if (enc_hdr_pkt) {
1608                 mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, enc_hdr_pkt);
1609 
1610                 RK_S32 length = (*(mRKMppApi.HdiMppPacketGetLength))(enc_hdr_pkt);
1611                 void *src = (*(mRKMppApi.Hdimpp_packet_get_data))(enc_hdr_pkt);
1612 
1613                 if (memcpy_s(out->data, length, src, length) != EOK) {
1614                     HDF_LOGE("%s memcpy_s no", __func__);
1615                 }
1616                 out->size = length;
1617             }
1618             return 0;
1619             } break;
1620         case VPU_API_SET_PARSER_SPLIT_MODE: {
1621             mpicmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
1622             } break;
1623         default: {
1624             } break;
1625     }
1626 
1627     RK_S32 ret = -1;
1628     if (mpicmd < MPI_CMD_BUTT)
1629         ret = mpi->control(mpp_ctx, mpicmd, (MppParam)param);
1630 
1631     HDF_LOGD("leave");
1632     return ret;
1633 }
1634 
1635