1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "h265e_api"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23
24 #include "rc.h"
25 #include "mpp_enc_cfg_impl.h"
26 #include "mpp_packet_impl.h"
27
28 #include "h265e_api.h"
29 #include "h265e_slice.h"
30 #include "h265e_codec.h"
31 #include "h265e_syntax_new.h"
32 #include "h265e_ps.h"
33 #include "h265e_header_gen.h"
34
35 RK_U32 h265e_debug = 0;
36
h265e_init(void * ctx,EncImplCfg * ctrlCfg)37 static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
38 {
39 H265eCtx *p = (H265eCtx *)ctx;
40 MPP_RET ret = MPP_OK;
41 MppEncCodecCfg *codec = NULL;
42 MppEncRcCfg *rc_cfg = &ctrlCfg->cfg->rc;
43 MppEncPrepCfg *prep = &ctrlCfg->cfg->prep;
44 MppEncH265Cfg *h265 = NULL;
45
46 if (ctx == NULL) {
47 mpp_err_f("invalid NULL ctx\n");
48 return MPP_ERR_NULL_PTR;
49 }
50
51 mpp_env_get_u32("h265e_debug", &h265e_debug, 0);
52 h265e_dbg_func("enter ctx %p\n", ctx);
53
54 mpp_assert(ctrlCfg->coding == MPP_VIDEO_CodingHEVC);
55 p->cfg = ctrlCfg->cfg;
56
57 memset(&p->syntax, 0, sizeof(p->syntax));
58
59 p->extra_info = mpp_calloc(H265eExtraInfo, 1);
60
61 p->param_buf = mpp_calloc_size(void, H265E_EXTRA_INFO_BUF_SIZE);
62 mpp_packet_init(&p->packeted_param, p->param_buf, H265E_EXTRA_INFO_BUF_SIZE);
63
64 h265e_init_extra_info(p->extra_info);
65 /* set defualt value of codec */
66 codec = &p->cfg->codec;
67 h265 = &codec->h265;
68 h265->intra_qp = 26;
69 h265->max_qp = 51;
70 h265->min_qp = 10;
71 h265->max_i_qp = 51;
72 h265->min_i_qp = 10;
73 h265->qpmap_mode = 1;
74 h265->ip_qp_delta = 5;
75 h265->raw_dealt_qp = 4;
76 h265->max_delta_qp = 10;
77 h265->gop_delta_qp = 0;
78 h265->intra_refresh_mode = 0;
79 h265->intra_refresh_arg = 0;
80 h265->independ_slice_mode = 0;
81 h265->independ_slice_arg = 0;
82 h265->depend_slice_mode = 0;
83 h265->depend_slice_arg = 0;
84
85 h265->profile = MPP_PROFILE_HEVC_MAIN;
86 h265->level = 120;
87 h265->const_intra_pred = 0; /* constraint intra prediction flag */
88
89 if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3528) {
90 h265->ctu_size = 32;
91 h265->max_cu_size = 32;
92 h265->tmvp_enable = 0;
93 } else {
94 h265->ctu_size = 64;
95 h265->max_cu_size = 64;
96 h265->tmvp_enable = 1;
97 }
98
99 h265->amp_enable = 0;
100 h265->sao_enable = 1;
101
102 h265->num_ref = 1;
103
104 h265->slice_cfg.split_enable = 0;
105 h265->entropy_cfg.cabac_init_flag = 1;
106 h265->sao_cfg.slice_sao_chroma_disable = 0;
107 h265->sao_cfg.slice_sao_luma_disable = 0;
108 h265->dblk_cfg.slice_deblocking_filter_disabled_flag = 0;
109 h265->cu_cfg.strong_intra_smoothing_enabled_flag = 1;
110 h265->merge_cfg.max_mrg_cnd = 2;
111 h265->merge_cfg.merge_left_flag = 1;
112 h265->merge_cfg.merge_up_flag = 1;
113
114 /*
115 * default prep:
116 * 720p
117 * YUV420SP
118 */
119 prep->change = 0;
120 prep->width = 1280;
121 prep->height = 720;
122 prep->hor_stride = 1280;
123 prep->ver_stride = 720;
124 prep->format = MPP_FMT_YUV420SP;
125 prep->color = MPP_FRAME_SPC_UNSPECIFIED;
126 prep->colorprim = MPP_FRAME_PRI_UNSPECIFIED;
127 prep->colortrc = MPP_FRAME_TRC_UNSPECIFIED;
128 prep->range = MPP_FRAME_RANGE_UNSPECIFIED;
129 prep->rotation = MPP_ENC_ROT_0;
130 prep->rotation_ext = MPP_ENC_ROT_0;
131 prep->mirroring = 0;
132 prep->mirroring_ext = 0;
133 prep->denoise = 0;
134 prep->flip = 0;
135
136 /*
137 * default rc_cfg:
138 * CBR
139 * 2Mbps +-25%
140 * 30fps
141 * gop 60
142 */
143 rc_cfg->change = 0;
144 rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM;
145 rc_cfg->bps_target = 2000 * 1000;
146 rc_cfg->bps_max = rc_cfg->bps_target * 5 / 4;
147 rc_cfg->bps_min = rc_cfg->bps_target * 3 / 4;
148 rc_cfg->fps_in_flex = 0;
149 rc_cfg->fps_in_num = 30;
150 rc_cfg->fps_in_denorm = 1;
151 rc_cfg->fps_out_flex = 0;
152 rc_cfg->fps_out_num = 30;
153 rc_cfg->fps_out_denorm = 1;
154 rc_cfg->gop = 60;
155 rc_cfg->max_reenc_times = 1;
156 rc_cfg->max_i_prop = 30;
157 rc_cfg->min_i_prop = 10;
158 rc_cfg->init_ip_ratio = 160;
159 rc_cfg->qp_init = 26;
160 rc_cfg->qp_max = 51;
161 rc_cfg->qp_min = 10;
162 rc_cfg->qp_max_i = 51;
163 rc_cfg->qp_min_i = 15;
164 rc_cfg->qp_delta_ip = 4;
165 rc_cfg->qp_delta_vi = 2;
166
167 INIT_LIST_HEAD(&p->rc_list);
168
169 h265e_dbg_func("leave ctx %p\n", ctx);
170 return ret;
171 }
172
h265e_deinit(void * ctx)173 static MPP_RET h265e_deinit(void *ctx)
174 {
175 H265eCtx *p = (H265eCtx *)ctx;
176
177 h265e_dbg_func("enter ctx %p\n", ctx);
178
179 if (ctx == NULL) {
180 mpp_err_f("invalid NULL ctx\n");
181 return MPP_ERR_NULL_PTR;
182 }
183
184 h265e_deinit_extra_info(p->extra_info);
185
186 MPP_FREE(p->extra_info);
187 MPP_FREE(p->param_buf);
188 if (p->packeted_param)
189 mpp_packet_deinit(&p->packeted_param);
190
191 h265e_dpb_deinit(p->dpb);
192
193 h265e_dbg_func("leave ctx %p\n", ctx);
194 return MPP_OK;
195 }
196
h265e_gen_hdr(void * ctx,MppPacket pkt)197 static MPP_RET h265e_gen_hdr(void *ctx, MppPacket pkt)
198 {
199 H265eCtx *p = (H265eCtx *)ctx;
200
201 h265e_dbg_func("enter ctx %p\n", ctx);
202
203 h265e_set_extra_info(p);
204 h265e_get_extra_info(p, pkt);
205
206 if (NULL == p->dpb)
207 h265e_dpb_init(&p->dpb);
208
209 h265e_dbg_func("leave ctx %p\n", ctx);
210
211 return MPP_OK;
212 }
213
h265e_start(void * ctx,HalEncTask * task)214 static MPP_RET h265e_start(void *ctx, HalEncTask *task)
215 {
216 H265eCtx *p = (H265eCtx *)ctx;
217 (void) p;
218 h265e_dbg_func("enter\n");
219
220 /*
221 * Step 2: Fps conversion
222 *
223 * Determine current frame which should be encoded or not according to
224 * input and output frame rate.
225 */
226
227 if (!task->valid)
228 mpp_log_f("drop one frame\n");
229
230 /*
231 * Step 3: Backup dpb for reencode
232 */
233 //h265e_dpb_copy(&p->dpb_bak, p->dpb);
234 h265e_dbg_func("leave\n");
235
236 return MPP_OK;
237 }
238
h265e_proc_dpb(void * ctx,HalEncTask * task)239 static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task)
240 {
241 H265eCtx *p = (H265eCtx *)ctx;
242 EncRcTask *rc_task = task->rc_task;
243 EncCpbStatus *cpb = &task->rc_task->cpb;
244 h265e_dbg_func("enter\n");
245 h265e_dpb_proc_cpb(p->dpb, cpb);
246 h265e_dpb_get_curr(p->dpb);
247 h265e_slice_init(ctx, cpb->curr);
248 h265e_dpb_build_list(p->dpb, cpb);
249
250 rc_task->frm = p->dpb->curr->status;
251
252 h265e_dbg_func("leave\n");
253 return MPP_OK;
254 }
255
h265e_proc_hal(void * ctx,HalEncTask * task)256 static MPP_RET h265e_proc_hal(void *ctx, HalEncTask *task)
257 {
258 H265eCtx *p = (H265eCtx *)ctx;
259 H265eSyntax_new *syntax = NULL;
260 EncFrmStatus *frm = &task->rc_task->frm;
261 MppPacket packet = task->packet;
262 MppMeta meta = mpp_packet_get_meta(packet);
263
264 if (ctx == NULL) {
265 mpp_err_f("invalid NULL ctx\n");
266 return MPP_ERR_NULL_PTR;
267 }
268
269 mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, frm->temporal_id);
270 h265e_dbg_func("enter ctx %p \n", ctx);
271 syntax = &p->syntax;
272 h265e_syntax_fill(ctx);
273 task->valid = 1;
274 task->syntax.data = syntax;
275 h265e_dbg_func("leave ctx %p \n", ctx);
276 return MPP_OK;
277 }
278
h265e_proc_enc_skip(void * ctx,HalEncTask * task)279 static MPP_RET h265e_proc_enc_skip(void *ctx, HalEncTask *task)
280 {
281 H265eCtx *p = (H265eCtx *)ctx;
282 MppPacket pkt = task->packet;
283 RK_U8 *ptr = mpp_packet_get_pos(pkt);
284 RK_U32 offset = mpp_packet_get_length(pkt);
285 RK_U32 len = mpp_packet_get_size(pkt) - offset;
286 RK_U32 new_length = 0;
287
288 h265e_dbg_func("enter\n");
289 ptr += offset;
290 p->slice->m_sliceQp = task->rc_task->info.quality_target;
291 new_length = h265e_code_slice_skip_frame(ctx, p->slice, ptr, len);
292 task->length = new_length;
293 task->rc_task->info.bit_real = 8 * new_length;
294 ///mpp_packet_set_length(pkt, offset + new_length);
295
296 h265e_dbg_func("leave\n");
297 return MPP_OK;
298 }
299
h265e_add_sei(MppPacket pkt,RK_S32 * length,RK_U8 uuid[16],const void * data,RK_S32 size)300 static MPP_RET h265e_add_sei(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
301 const void *data, RK_S32 size)
302 {
303 RK_U8 *ptr = mpp_packet_get_pos(pkt);
304 RK_U32 offset = mpp_packet_get_length(pkt);
305 RK_U32 new_length = 0;
306
307 ptr += offset;
308
309 if (uuid == uuid_refresh_cfg) {
310 RK_U32 recovery_frame_cnt = ((RK_U32 *)data)[0] - 1;
311 new_length = h265e_sei_recovery_point(ptr, uuid, &recovery_frame_cnt, 0);
312 } else {
313 new_length = h265e_data_to_sei(ptr, uuid, data, size);
314 }
315 *length = new_length;
316
317 mpp_packet_set_length(pkt, offset + new_length);
318 mpp_packet_add_segment_info(pkt, NAL_SEI_PREFIX, offset, new_length);
319
320 return MPP_OK;
321 }
322
h265e_proc_prep_cfg(MppEncPrepCfg * dst,MppEncPrepCfg * src)323 static MPP_RET h265e_proc_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src)
324 {
325 MPP_RET ret = MPP_OK;
326 RK_U32 change = src->change;
327 RK_S32 mirroring;
328 RK_S32 rotation;
329
330 mpp_assert(change);
331
332 MppEncPrepCfg bak = *dst;
333
334 if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT)
335 dst->format = src->format;
336
337 if (change & MPP_ENC_PREP_CFG_CHANGE_COLOR_RANGE)
338 dst->range = src->range;
339
340 if (change & MPP_ENC_PREP_CFG_CHANGE_COLOR_SPACE)
341 dst->color = src->color;
342
343 if (change & MPP_ENC_PREP_CFG_CHANGE_COLOR_PRIME)
344 dst->colorprim = src->colorprim;
345
346 if (change & MPP_ENC_PREP_CFG_CHANGE_COLOR_TRC)
347 dst->colortrc = src->colortrc;
348
349 if (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION)
350 dst->rotation_ext = src->rotation_ext;
351
352 if (change & MPP_ENC_PREP_CFG_CHANGE_MIRRORING)
353 dst->mirroring_ext = src->mirroring_ext;
354
355 if (change & MPP_ENC_PREP_CFG_CHANGE_FLIP)
356 dst->flip = src->flip;
357
358 if (change & MPP_ENC_PREP_CFG_CHANGE_DENOISE)
359 dst->denoise = src->denoise;
360
361 if (change & MPP_ENC_PREP_CFG_CHANGE_SHARPEN)
362 dst->sharpen = src->sharpen;
363
364 // parameter checking
365 if (dst->rotation_ext >= MPP_ENC_ROT_BUTT || dst->rotation_ext < 0 ||
366 dst->mirroring_ext < 0 || dst->flip < 0) {
367 mpp_err("invalid trans: rotation %d, mirroring %d\n", dst->rotation_ext, dst->mirroring_ext);
368 ret = MPP_ERR_VALUE;
369 }
370
371 /* For unifying the encoder's params used by CFG_SET and CFG_GET command,
372 * there is distinction between user's set and set in hal.
373 * User can externally set rotation_ext, mirroring_ext and flip,
374 * which should be transformed to mirroring and rotation in hal.
375 */
376 mirroring = dst->mirroring_ext;
377 rotation = dst->rotation_ext;
378
379 if (dst->flip) {
380 mirroring = !mirroring;
381 rotation += MPP_ENC_ROT_180;
382 rotation &= MPP_ENC_ROT_270;
383 }
384
385 dst->mirroring = mirroring;
386 dst->rotation = rotation;
387
388 if ((change & MPP_ENC_PREP_CFG_CHANGE_INPUT) ||
389 (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION)) {
390 if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) {
391 dst->width = src->height;
392 dst->height = src->width;
393 } else {
394 dst->width = src->width;
395 dst->height = src->height;
396 }
397 dst->hor_stride = src->hor_stride;
398 dst->ver_stride = src->ver_stride;
399 }
400
401 dst->change |= change;
402
403 // parameter checking
404 if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) {
405 if (dst->height > dst->hor_stride || dst->width > dst->ver_stride) {
406 mpp_err("invalid size w:h [%d:%d] stride [%d:%d]\n",
407 dst->width, dst->height, dst->hor_stride, dst->ver_stride);
408 ret = MPP_ERR_VALUE;
409 }
410 } else {
411 if (dst->width > dst->hor_stride || dst->height > dst->ver_stride) {
412 mpp_err("invalid size w:h [%d:%d] stride [%d:%d]\n",
413 dst->width, dst->height, dst->hor_stride, dst->ver_stride);
414 ret = MPP_ERR_VALUE;
415 }
416 }
417
418 if (MPP_FRAME_FMT_IS_FBC(dst->format) && (dst->mirroring || dst->rotation || dst->flip)) {
419 // rk3588 rkvenc support fbc with rotation
420 if (!strstr(mpp_get_soc_name(), "rk3588")) {
421 mpp_err("invalid cfg fbc data no support mirror %d, rotation %d, or flip %d",
422 dst->mirroring, dst->rotation, dst->flip);
423 ret = MPP_ERR_VALUE;
424 }
425 }
426
427 if (dst->range >= MPP_FRAME_RANGE_NB ||
428 dst->color >= MPP_FRAME_SPC_NB ||
429 dst->colorprim >= MPP_FRAME_PRI_NB ||
430 dst->colortrc >= MPP_FRAME_TRC_NB) {
431 mpp_err("invalid color range %d colorspace %d primaries %d transfer characteristic %d\n",
432 dst->range, dst->color, dst->colorprim, dst->colortrc);
433 ret = MPP_ERR_VALUE;
434 }
435
436 if (ret) {
437 mpp_err_f("failed to accept new prep config\n");
438 *dst = bak;
439 } else {
440 mpp_log_f("MPP_ENC_SET_PREP_CFG w:h [%d:%d] stride [%d:%d]\n",
441 dst->width, dst->height,
442 dst->hor_stride, dst->ver_stride);
443 }
444
445 return ret;
446 }
447
448
h265e_proc_h265_cfg(MppEncH265Cfg * dst,MppEncH265Cfg * src)449 static MPP_RET h265e_proc_h265_cfg(MppEncH265Cfg *dst, MppEncH265Cfg *src)
450 {
451 RK_U32 change = src->change;
452
453 // TODO: do codec check first
454 if (change & MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE) {
455 dst->profile = src->profile;
456 dst->level = src->level;
457 }
458
459 if (change & MPP_ENC_H265_CFG_CU_CHANGE) {
460 memcpy(&dst->cu_cfg, &src->cu_cfg, sizeof(src->cu_cfg));
461 }
462 if (change & MPP_ENC_H265_CFG_DBLK_CHANGE) {
463 memcpy(&dst->dblk_cfg, &src->dblk_cfg, sizeof(src->dblk_cfg));
464 }
465 if (change & MPP_ENC_H265_CFG_SAO_CHANGE) {
466 memcpy(&dst->sao_cfg, &src->sao_cfg, sizeof(src->sao_cfg));
467 }
468 if (change & MPP_ENC_H265_CFG_TRANS_CHANGE) {
469 if (src->trans_cfg.cb_qp_offset != src->trans_cfg.cr_qp_offset) {
470 mpp_log("cr_qp_offset %d MUST equal to cb_qp_offset %d. FORCE to same value\n",
471 src->trans_cfg.cb_qp_offset, src->trans_cfg.cr_qp_offset);
472 src->trans_cfg.cr_qp_offset = src->trans_cfg.cb_qp_offset;
473 }
474 memcpy(&dst->trans_cfg, &src->trans_cfg, sizeof(src->trans_cfg));
475 }
476
477 if (change & MPP_ENC_H265_CFG_SLICE_CHANGE) {
478 memcpy(&dst->slice_cfg, &src->slice_cfg, sizeof(src->slice_cfg));
479 }
480
481 if (change & MPP_ENC_H265_CFG_ENTROPY_CHANGE) {
482 memcpy(&dst->entropy_cfg, &src->entropy_cfg, sizeof(src->entropy_cfg));
483 }
484
485 if (change & MPP_ENC_H265_CFG_MERGE_CHANGE) {
486 memcpy(&dst->merge_cfg, &src->merge_cfg, sizeof(src->merge_cfg));
487 }
488
489 if (change & MPP_ENC_H265_CFG_CHANGE_VUI) {
490 memcpy(&dst->vui, &src->vui, sizeof(src->vui));
491 }
492
493 if (change & MPP_ENC_H265_CFG_SAO_CHANGE) {
494 memcpy(&dst->sao_cfg, &src->sao_cfg, sizeof(src->sao_cfg));
495 }
496
497 if (change & MPP_ENC_H265_CFG_TILE_CHANGE)
498 dst->auto_tile = src->auto_tile;
499
500 if (change & MPP_ENC_H265_CFG_SLICE_LPFACS_CHANGE)
501 dst->lpf_acs_sli_en = src->lpf_acs_sli_en;
502
503 if (change & MPP_ENC_H265_CFG_TILE_LPFACS_CHANGE)
504 dst->lpf_acs_tile_disable = src->lpf_acs_tile_disable;
505
506 /*
507 * NOTE: use OR here for avoiding overwrite on multiple config
508 * When next encoding is trigger the change flag will be clear
509 */
510 dst->change |= change;
511
512 return MPP_OK;
513 }
514
h265e_proc_split_cfg(MppEncSliceSplit * dst,MppEncSliceSplit * src)515 static MPP_RET h265e_proc_split_cfg(MppEncSliceSplit *dst, MppEncSliceSplit *src)
516 {
517 MPP_RET ret = MPP_OK;
518 RK_U32 change = src->change;
519
520 if (change & MPP_ENC_SPLIT_CFG_CHANGE_MODE) {
521 dst->split_mode = src->split_mode;
522 dst->split_arg = src->split_arg;
523 }
524
525 if (change & MPP_ENC_SPLIT_CFG_CHANGE_ARG)
526 dst->split_arg = src->split_arg;
527
528 if (change & MPP_ENC_SPLIT_CFG_CHANGE_OUTPUT)
529 dst->split_out = src->split_out;
530
531 /* cleanup arg and out when split mode is disabled */
532 if (!dst->split_mode) {
533 dst->split_arg = 0;
534 dst->split_out = 0;
535 }
536
537 dst->change |= change;
538 src->change = 0;
539
540 return ret;
541 }
542
h265e_proc_cfg(void * ctx,MpiCmd cmd,void * param)543 static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
544 {
545 H265eCtx *p = (H265eCtx *)ctx;
546 MppEncCfgSet *cfg = p->cfg;
547 MPP_RET ret = MPP_OK;
548
549 h265e_dbg_func("enter ctx %p cmd %08x\n", ctx, cmd);
550
551 switch (cmd) {
552 case MPP_ENC_SET_CFG : {
553 MppEncCfgImpl *impl = (MppEncCfgImpl *)param;
554 MppEncCfgSet *src = &impl->cfg;
555
556 if (src->prep.change) {
557 ret |= h265e_proc_prep_cfg(&cfg->prep, &src->prep);
558 src->prep.change = 0;
559 }
560
561 if (cfg->rc.refresh_en) {
562 RK_U32 mb_rows;
563
564 if (MPP_ENC_RC_INTRA_REFRESH_ROW == cfg->rc.refresh_mode)
565 mb_rows = MPP_ALIGN(cfg->prep.height, 64) / 64;
566 else
567 mb_rows = MPP_ALIGN(cfg->prep.width, 64) / 64;
568
569 cfg->rc.refresh_length = (mb_rows + cfg->rc.refresh_num - 1) / cfg->rc.refresh_num;
570 if (cfg->rc.gop < cfg->rc.refresh_length)
571 cfg->rc.refresh_length = cfg->rc.gop;
572 }
573
574 if (src->codec.h265.change) {
575 ret |= h265e_proc_h265_cfg(&cfg->codec.h265, &src->codec.h265);
576 src->codec.h265.change = 0;
577 }
578 if (src->split.change) {
579 ret |= h265e_proc_split_cfg(&cfg->split, &src->split);
580 src->split.change = 0;
581 }
582 } break;
583 case MPP_ENC_GET_EXTRA_INFO: {
584 MppPacket pkt_out = (MppPacket )param;
585 h265e_set_extra_info(p);
586 h265e_get_extra_info(p, pkt_out);
587 } break;
588 case MPP_ENC_SET_PREP_CFG : {
589 ret = h265e_proc_prep_cfg(&cfg->prep, param);
590 } break;
591 case MPP_ENC_SET_CODEC_CFG: {
592 MppEncCodecCfg *codec = (MppEncCodecCfg *)param;
593 ret = h265e_proc_h265_cfg(&cfg->codec.h265, &codec->h265);
594 } break;
595
596 case MPP_ENC_SET_SEI_CFG: {
597 } break;
598 case MPP_ENC_SET_SPLIT : {
599 MppEncSliceSplit *src = (MppEncSliceSplit *)param;
600 MppEncH265SliceCfg *slice_cfg = &cfg->codec.h265.slice_cfg;
601
602 if (src->split_mode > MPP_ENC_SPLIT_NONE) {
603 slice_cfg->split_enable = 1;
604 slice_cfg->split_mode = 0;
605 if (src->split_mode == MPP_ENC_SPLIT_BY_CTU)
606 slice_cfg->split_mode = 1;
607 slice_cfg->slice_size = src->split_arg;
608 } else {
609 slice_cfg->split_enable = 0;
610 }
611 } break;
612 default:
613 mpp_err("No correspond %08x found, and can not config!\n", cmd);
614 ret = MPP_NOK;
615 break;
616 }
617
618 h265e_dbg_func("leave ctx %p\n", ctx);
619 return ret;
620 }
621
622 const EncImplApi api_h265e = {
623 "h265e_control",
624 MPP_VIDEO_CodingHEVC,
625 sizeof(H265eCtx),
626 0,
627 h265e_init,
628 h265e_deinit,
629 h265e_proc_cfg,
630 h265e_gen_hdr,
631 h265e_start,
632 h265e_proc_dpb,
633 h265e_proc_hal,
634 h265e_add_sei,
635 h265e_proc_enc_skip,
636 };
637