xref: /OK3568_Linux_fs/external/mpp/mpp/codec/enc/h265/h265e_api.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "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