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