1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka *
4*437bfbebSnyanmisaka * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka * You may obtain a copy of the License at
7*437bfbebSnyanmisaka *
8*437bfbebSnyanmisaka * http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka *
10*437bfbebSnyanmisaka * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka * limitations under the License.
15*437bfbebSnyanmisaka */
16*437bfbebSnyanmisaka
17*437bfbebSnyanmisaka #define MODULE_TAG "h265e_api"
18*437bfbebSnyanmisaka
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka #include <limits.h>
21*437bfbebSnyanmisaka
22*437bfbebSnyanmisaka #include "mpp_env.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka
25*437bfbebSnyanmisaka #include "rc.h"
26*437bfbebSnyanmisaka #include "mpp_soc.h"
27*437bfbebSnyanmisaka #include "mpp_enc_cfg.h"
28*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
29*437bfbebSnyanmisaka #include "mpp_enc_impl.h"
30*437bfbebSnyanmisaka
31*437bfbebSnyanmisaka #include "h265e_api.h"
32*437bfbebSnyanmisaka #include "h265e_slice.h"
33*437bfbebSnyanmisaka #include "h265e_codec.h"
34*437bfbebSnyanmisaka #include "h265e_syntax_new.h"
35*437bfbebSnyanmisaka #include "h265e_ps.h"
36*437bfbebSnyanmisaka #include "h265e_header_gen.h"
37*437bfbebSnyanmisaka
38*437bfbebSnyanmisaka RK_U32 h265e_debug = 0;
39*437bfbebSnyanmisaka
h265e_init(void * ctx,EncImplCfg * ctrlCfg)40*437bfbebSnyanmisaka static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
41*437bfbebSnyanmisaka {
42*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
43*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
44*437bfbebSnyanmisaka MppEncRcCfg *rc_cfg = &ctrlCfg->cfg->rc;
45*437bfbebSnyanmisaka MppEncPrepCfg *prep = &ctrlCfg->cfg->prep;
46*437bfbebSnyanmisaka MppEncH265Cfg *h265 = NULL;
47*437bfbebSnyanmisaka RockchipSocType soc_type;
48*437bfbebSnyanmisaka
49*437bfbebSnyanmisaka if (ctx == NULL) {
50*437bfbebSnyanmisaka mpp_err_f("invalid NULL ctx\n");
51*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
52*437bfbebSnyanmisaka }
53*437bfbebSnyanmisaka
54*437bfbebSnyanmisaka mpp_env_get_u32("h265e_debug", &h265e_debug, 0);
55*437bfbebSnyanmisaka h265e_dbg_func("enter ctx %p\n", ctx);
56*437bfbebSnyanmisaka
57*437bfbebSnyanmisaka mpp_assert(ctrlCfg->coding == MPP_VIDEO_CodingHEVC);
58*437bfbebSnyanmisaka p->cfg = ctrlCfg->cfg;
59*437bfbebSnyanmisaka
60*437bfbebSnyanmisaka memset(&p->syntax, 0, sizeof(p->syntax));
61*437bfbebSnyanmisaka
62*437bfbebSnyanmisaka p->extra_info = mpp_calloc(H265eExtraInfo, 1);
63*437bfbebSnyanmisaka
64*437bfbebSnyanmisaka h265e_init_extra_info(p->extra_info);
65*437bfbebSnyanmisaka /* set defualt value of codec */
66*437bfbebSnyanmisaka h265 = &p->cfg->h265;
67*437bfbebSnyanmisaka h265->intra_qp = 26;
68*437bfbebSnyanmisaka h265->qpmap_mode = 1;
69*437bfbebSnyanmisaka
70*437bfbebSnyanmisaka h265->profile = MPP_PROFILE_HEVC_MAIN;
71*437bfbebSnyanmisaka h265->level = 120;
72*437bfbebSnyanmisaka h265->const_intra_pred = 0; /* constraint intra prediction flag */
73*437bfbebSnyanmisaka
74*437bfbebSnyanmisaka soc_type = mpp_get_soc_type();
75*437bfbebSnyanmisaka if (soc_type == ROCKCHIP_SOC_RK3528 ||
76*437bfbebSnyanmisaka soc_type == ROCKCHIP_SOC_RK3576 ||
77*437bfbebSnyanmisaka soc_type == ROCKCHIP_SOC_RV1126B)
78*437bfbebSnyanmisaka h265->max_cu_size = 32;
79*437bfbebSnyanmisaka else
80*437bfbebSnyanmisaka h265->max_cu_size = 64;
81*437bfbebSnyanmisaka
82*437bfbebSnyanmisaka h265->tmvp_enable = 0;
83*437bfbebSnyanmisaka h265->amp_enable = 0;
84*437bfbebSnyanmisaka h265->sao_enable = 1;
85*437bfbebSnyanmisaka
86*437bfbebSnyanmisaka h265->num_ref = 1;
87*437bfbebSnyanmisaka
88*437bfbebSnyanmisaka h265->slice_cfg.split_enable = 0;
89*437bfbebSnyanmisaka h265->entropy_cfg.cabac_init_flag = 1;
90*437bfbebSnyanmisaka h265->sao_cfg.slice_sao_chroma_disable = 0;
91*437bfbebSnyanmisaka h265->sao_cfg.slice_sao_luma_disable = 0;
92*437bfbebSnyanmisaka h265->dblk_cfg.slice_deblocking_filter_disabled_flag = 0;
93*437bfbebSnyanmisaka h265->cu_cfg.strong_intra_smoothing_enabled_flag = 1;
94*437bfbebSnyanmisaka h265->merge_cfg.max_mrg_cnd = 2;
95*437bfbebSnyanmisaka h265->merge_cfg.merge_left_flag = 1;
96*437bfbebSnyanmisaka h265->merge_cfg.merge_up_flag = 1;
97*437bfbebSnyanmisaka h265->trans_cfg.diff_cu_qp_delta_depth = 0;
98*437bfbebSnyanmisaka h265->vui.vui_en = 1;
99*437bfbebSnyanmisaka p->cfg->tune.scene_mode = MPP_ENC_SCENE_MODE_DEFAULT;
100*437bfbebSnyanmisaka p->cfg->tune.lambda_idx_i = 2;
101*437bfbebSnyanmisaka p->cfg->tune.lambda_idx_p = 4;
102*437bfbebSnyanmisaka p->cfg->tune.anti_flicker_str = 2;
103*437bfbebSnyanmisaka p->cfg->tune.atr_str_i = 3;
104*437bfbebSnyanmisaka p->cfg->tune.atr_str_p = 0;
105*437bfbebSnyanmisaka p->cfg->tune.atl_str = 1;
106*437bfbebSnyanmisaka p->cfg->tune.sao_str_i = 0;
107*437bfbebSnyanmisaka p->cfg->tune.sao_str_p = 1;
108*437bfbebSnyanmisaka p->cfg->tune.deblur_str = 3;
109*437bfbebSnyanmisaka p->cfg->tune.deblur_en = 0;
110*437bfbebSnyanmisaka p->cfg->tune.rc_container = 0;
111*437bfbebSnyanmisaka p->cfg->tune.vmaf_opt = 0;
112*437bfbebSnyanmisaka
113*437bfbebSnyanmisaka /* smart v3 parameters */
114*437bfbebSnyanmisaka p->cfg->tune.bg_delta_qp_i = -10;
115*437bfbebSnyanmisaka p->cfg->tune.bg_delta_qp_p = -10;
116*437bfbebSnyanmisaka p->cfg->tune.fg_delta_qp_i = 3;
117*437bfbebSnyanmisaka p->cfg->tune.fg_delta_qp_p = 1;
118*437bfbebSnyanmisaka p->cfg->tune.bmap_qpmin_i = 30;
119*437bfbebSnyanmisaka p->cfg->tune.bmap_qpmin_p = 30;
120*437bfbebSnyanmisaka p->cfg->tune.bmap_qpmax_i = 45;
121*437bfbebSnyanmisaka p->cfg->tune.bmap_qpmax_p = 47;
122*437bfbebSnyanmisaka p->cfg->tune.min_bg_fqp = 30;
123*437bfbebSnyanmisaka p->cfg->tune.max_bg_fqp = 45;
124*437bfbebSnyanmisaka p->cfg->tune.min_fg_fqp = 25;
125*437bfbebSnyanmisaka p->cfg->tune.max_fg_fqp = 35;
126*437bfbebSnyanmisaka
127*437bfbebSnyanmisaka /*
128*437bfbebSnyanmisaka * default prep:
129*437bfbebSnyanmisaka * 720p
130*437bfbebSnyanmisaka * YUV420SP
131*437bfbebSnyanmisaka */
132*437bfbebSnyanmisaka prep->width = 1280;
133*437bfbebSnyanmisaka prep->height = 720;
134*437bfbebSnyanmisaka prep->hor_stride = 1280;
135*437bfbebSnyanmisaka prep->ver_stride = 720;
136*437bfbebSnyanmisaka prep->format = MPP_FMT_YUV420SP;
137*437bfbebSnyanmisaka prep->color = MPP_FRAME_SPC_UNSPECIFIED;
138*437bfbebSnyanmisaka prep->colorprim = MPP_FRAME_PRI_UNSPECIFIED;
139*437bfbebSnyanmisaka prep->colortrc = MPP_FRAME_TRC_UNSPECIFIED;
140*437bfbebSnyanmisaka prep->range = MPP_FRAME_RANGE_UNSPECIFIED;
141*437bfbebSnyanmisaka prep->rotation = MPP_ENC_ROT_0;
142*437bfbebSnyanmisaka prep->rotation_ext = MPP_ENC_ROT_0;
143*437bfbebSnyanmisaka prep->mirroring = 0;
144*437bfbebSnyanmisaka prep->mirroring_ext = 0;
145*437bfbebSnyanmisaka prep->denoise = 0;
146*437bfbebSnyanmisaka prep->flip = 0;
147*437bfbebSnyanmisaka
148*437bfbebSnyanmisaka /*
149*437bfbebSnyanmisaka * default rc_cfg:
150*437bfbebSnyanmisaka * CBR
151*437bfbebSnyanmisaka * 2Mbps +-25%
152*437bfbebSnyanmisaka * 30fps
153*437bfbebSnyanmisaka * gop 60
154*437bfbebSnyanmisaka */
155*437bfbebSnyanmisaka rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM;
156*437bfbebSnyanmisaka rc_cfg->bps_target = 2000 * 1000;
157*437bfbebSnyanmisaka rc_cfg->bps_max = rc_cfg->bps_target * 5 / 4;
158*437bfbebSnyanmisaka rc_cfg->bps_min = rc_cfg->bps_target * 3 / 4;
159*437bfbebSnyanmisaka rc_cfg->fps_in_flex = 0;
160*437bfbebSnyanmisaka rc_cfg->fps_in_num = 30;
161*437bfbebSnyanmisaka rc_cfg->fps_in_denom = 1;
162*437bfbebSnyanmisaka rc_cfg->fps_out_flex = 0;
163*437bfbebSnyanmisaka rc_cfg->fps_out_num = 30;
164*437bfbebSnyanmisaka rc_cfg->fps_out_denom = 1;
165*437bfbebSnyanmisaka rc_cfg->gop = 60;
166*437bfbebSnyanmisaka rc_cfg->max_reenc_times = 1;
167*437bfbebSnyanmisaka rc_cfg->max_i_prop = 30;
168*437bfbebSnyanmisaka rc_cfg->min_i_prop = 10;
169*437bfbebSnyanmisaka rc_cfg->init_ip_ratio = 160;
170*437bfbebSnyanmisaka rc_cfg->qp_init = 26;
171*437bfbebSnyanmisaka rc_cfg->qp_max = 51;
172*437bfbebSnyanmisaka rc_cfg->qp_min = 10;
173*437bfbebSnyanmisaka rc_cfg->qp_max_i = 51;
174*437bfbebSnyanmisaka rc_cfg->qp_min_i = 15;
175*437bfbebSnyanmisaka rc_cfg->qp_delta_ip = 4;
176*437bfbebSnyanmisaka rc_cfg->qp_delta_vi = 2;
177*437bfbebSnyanmisaka rc_cfg->fqp_min_i = INT_MAX;
178*437bfbebSnyanmisaka rc_cfg->fqp_min_p = INT_MAX;
179*437bfbebSnyanmisaka rc_cfg->fqp_max_i = INT_MAX;
180*437bfbebSnyanmisaka rc_cfg->fqp_max_p = INT_MAX;
181*437bfbebSnyanmisaka INIT_LIST_HEAD(&p->rc_list);
182*437bfbebSnyanmisaka
183*437bfbebSnyanmisaka h265e_dbg_func("leave ctx %p\n", ctx);
184*437bfbebSnyanmisaka return ret;
185*437bfbebSnyanmisaka }
186*437bfbebSnyanmisaka
h265e_deinit(void * ctx)187*437bfbebSnyanmisaka static MPP_RET h265e_deinit(void *ctx)
188*437bfbebSnyanmisaka {
189*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
190*437bfbebSnyanmisaka
191*437bfbebSnyanmisaka h265e_dbg_func("enter ctx %p\n", ctx);
192*437bfbebSnyanmisaka
193*437bfbebSnyanmisaka if (ctx == NULL) {
194*437bfbebSnyanmisaka mpp_err_f("invalid NULL ctx\n");
195*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
196*437bfbebSnyanmisaka }
197*437bfbebSnyanmisaka
198*437bfbebSnyanmisaka h265e_deinit_extra_info(p->extra_info);
199*437bfbebSnyanmisaka
200*437bfbebSnyanmisaka MPP_FREE(p->extra_info);
201*437bfbebSnyanmisaka
202*437bfbebSnyanmisaka h265e_dpb_deinit(p->dpb);
203*437bfbebSnyanmisaka
204*437bfbebSnyanmisaka h265e_dbg_func("leave ctx %p\n", ctx);
205*437bfbebSnyanmisaka return MPP_OK;
206*437bfbebSnyanmisaka }
207*437bfbebSnyanmisaka
h265e_gen_hdr(void * ctx,MppPacket pkt)208*437bfbebSnyanmisaka static MPP_RET h265e_gen_hdr(void *ctx, MppPacket pkt)
209*437bfbebSnyanmisaka {
210*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
211*437bfbebSnyanmisaka
212*437bfbebSnyanmisaka h265e_dbg_func("enter ctx %p\n", ctx);
213*437bfbebSnyanmisaka
214*437bfbebSnyanmisaka h265e_set_extra_info(p);
215*437bfbebSnyanmisaka h265e_get_extra_info(p, pkt);
216*437bfbebSnyanmisaka
217*437bfbebSnyanmisaka if (NULL == p->dpb)
218*437bfbebSnyanmisaka h265e_dpb_init(&p->dpb);
219*437bfbebSnyanmisaka
220*437bfbebSnyanmisaka h265e_dbg_func("leave ctx %p\n", ctx);
221*437bfbebSnyanmisaka
222*437bfbebSnyanmisaka return MPP_OK;
223*437bfbebSnyanmisaka }
224*437bfbebSnyanmisaka
h265e_start(void * ctx,HalEncTask * task)225*437bfbebSnyanmisaka static MPP_RET h265e_start(void *ctx, HalEncTask *task)
226*437bfbebSnyanmisaka {
227*437bfbebSnyanmisaka h265e_dbg_func("enter\n");
228*437bfbebSnyanmisaka
229*437bfbebSnyanmisaka if (mpp_frame_has_meta(task->frame)) {
230*437bfbebSnyanmisaka MppEncRefFrmUsrCfg *frm_cfg = task->frm_cfg;
231*437bfbebSnyanmisaka EncRcForceCfg *rc_force = &task->rc_task->force;
232*437bfbebSnyanmisaka MppMeta meta = mpp_frame_get_meta(task->frame);
233*437bfbebSnyanmisaka RK_S32 force_lt_idx = -1;
234*437bfbebSnyanmisaka RK_S32 force_use_lt_idx = -1;
235*437bfbebSnyanmisaka RK_S32 force_frame_qp = -1;
236*437bfbebSnyanmisaka RK_S32 base_layer_pid = -1;
237*437bfbebSnyanmisaka RK_S32 force_tid = -1;
238*437bfbebSnyanmisaka
239*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_ENC_MARK_LTR, &force_lt_idx);
240*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &force_use_lt_idx);
241*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_ENC_FRAME_QP, &force_frame_qp);
242*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_ENC_BASE_LAYER_PID, &base_layer_pid);
243*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &force_tid);
244*437bfbebSnyanmisaka
245*437bfbebSnyanmisaka if (force_lt_idx >= 0) {
246*437bfbebSnyanmisaka frm_cfg->force_flag |= ENC_FORCE_LT_REF_IDX;
247*437bfbebSnyanmisaka frm_cfg->force_lt_idx = force_lt_idx;
248*437bfbebSnyanmisaka }
249*437bfbebSnyanmisaka
250*437bfbebSnyanmisaka if (force_use_lt_idx >= 0) {
251*437bfbebSnyanmisaka frm_cfg->force_flag |= ENC_FORCE_REF_MODE;
252*437bfbebSnyanmisaka frm_cfg->force_ref_mode = REF_TO_LT_REF_IDX;
253*437bfbebSnyanmisaka frm_cfg->force_ref_arg = force_use_lt_idx;
254*437bfbebSnyanmisaka }
255*437bfbebSnyanmisaka
256*437bfbebSnyanmisaka if (force_tid >= 0) {
257*437bfbebSnyanmisaka frm_cfg->force_flag |= ENC_FORCE_TEMPORAL_ID;
258*437bfbebSnyanmisaka frm_cfg->force_temporal_id = force_tid;
259*437bfbebSnyanmisaka }
260*437bfbebSnyanmisaka
261*437bfbebSnyanmisaka if (force_frame_qp >= 0) {
262*437bfbebSnyanmisaka rc_force->force_flag = ENC_RC_FORCE_QP;
263*437bfbebSnyanmisaka rc_force->force_qp = force_frame_qp;
264*437bfbebSnyanmisaka } else {
265*437bfbebSnyanmisaka rc_force->force_flag &= (~ENC_RC_FORCE_QP);
266*437bfbebSnyanmisaka rc_force->force_qp = -1;
267*437bfbebSnyanmisaka }
268*437bfbebSnyanmisaka
269*437bfbebSnyanmisaka if (base_layer_pid >= 0) {
270*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
271*437bfbebSnyanmisaka MppEncH265Cfg *h265 = &p->cfg->h265;
272*437bfbebSnyanmisaka
273*437bfbebSnyanmisaka h265->base_layer_pid = base_layer_pid;
274*437bfbebSnyanmisaka }
275*437bfbebSnyanmisaka }
276*437bfbebSnyanmisaka
277*437bfbebSnyanmisaka /*
278*437bfbebSnyanmisaka * Step 2: Fps conversion
279*437bfbebSnyanmisaka *
280*437bfbebSnyanmisaka * Determine current frame which should be encoded or not according to
281*437bfbebSnyanmisaka * input and output frame rate.
282*437bfbebSnyanmisaka */
283*437bfbebSnyanmisaka
284*437bfbebSnyanmisaka if (!task->valid)
285*437bfbebSnyanmisaka mpp_log_f("drop one frame\n");
286*437bfbebSnyanmisaka
287*437bfbebSnyanmisaka /*
288*437bfbebSnyanmisaka * Step 3: Backup dpb for reencode
289*437bfbebSnyanmisaka */
290*437bfbebSnyanmisaka //h265e_dpb_copy(&p->dpb_bak, p->dpb);
291*437bfbebSnyanmisaka h265e_dbg_func("leave\n");
292*437bfbebSnyanmisaka
293*437bfbebSnyanmisaka return MPP_OK;
294*437bfbebSnyanmisaka }
295*437bfbebSnyanmisaka
h265e_proc_dpb(void * ctx,HalEncTask * task)296*437bfbebSnyanmisaka static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task)
297*437bfbebSnyanmisaka {
298*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
299*437bfbebSnyanmisaka EncRcTask *rc_task = task->rc_task;
300*437bfbebSnyanmisaka EncCpbStatus *cpb = &task->rc_task->cpb;
301*437bfbebSnyanmisaka
302*437bfbebSnyanmisaka h265e_dbg_func("enter\n");
303*437bfbebSnyanmisaka h265e_dpb_proc_cpb(p->dpb, cpb);
304*437bfbebSnyanmisaka h265e_dpb_get_curr(p->dpb);
305*437bfbebSnyanmisaka h265e_slice_init(ctx, cpb->curr);
306*437bfbebSnyanmisaka h265e_dpb_build_list(p->dpb, cpb);
307*437bfbebSnyanmisaka
308*437bfbebSnyanmisaka rc_task->frm = p->dpb->curr->status;
309*437bfbebSnyanmisaka
310*437bfbebSnyanmisaka h265e_dbg_func("leave\n");
311*437bfbebSnyanmisaka return MPP_OK;
312*437bfbebSnyanmisaka }
313*437bfbebSnyanmisaka
h265e_proc_hal(void * ctx,HalEncTask * task)314*437bfbebSnyanmisaka static MPP_RET h265e_proc_hal(void *ctx, HalEncTask *task)
315*437bfbebSnyanmisaka {
316*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
317*437bfbebSnyanmisaka MppEncH265Cfg *h265 = &p->cfg->h265;
318*437bfbebSnyanmisaka
319*437bfbebSnyanmisaka if (ctx == NULL) {
320*437bfbebSnyanmisaka mpp_err_f("invalid NULL ctx\n");
321*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
322*437bfbebSnyanmisaka }
323*437bfbebSnyanmisaka
324*437bfbebSnyanmisaka /* check max temporal layer id */
325*437bfbebSnyanmisaka {
326*437bfbebSnyanmisaka MppEncCpbInfo *cpb_info = mpp_enc_ref_cfg_get_cpb_info(p->cfg->ref_cfg);
327*437bfbebSnyanmisaka RK_S32 cpb_max_tid = cpb_info->max_st_tid;
328*437bfbebSnyanmisaka RK_S32 cfg_max_tid = h265->max_tid;
329*437bfbebSnyanmisaka
330*437bfbebSnyanmisaka if (cpb_max_tid != cfg_max_tid) {
331*437bfbebSnyanmisaka mpp_log("max tid is update to match cpb %d -> %d\n",
332*437bfbebSnyanmisaka cfg_max_tid, cpb_max_tid);
333*437bfbebSnyanmisaka h265->max_tid = cpb_max_tid;
334*437bfbebSnyanmisaka }
335*437bfbebSnyanmisaka }
336*437bfbebSnyanmisaka
337*437bfbebSnyanmisaka if (h265->max_tid) {
338*437bfbebSnyanmisaka EncFrmStatus *frm = &task->rc_task->frm;
339*437bfbebSnyanmisaka MppPacket packet = task->packet;
340*437bfbebSnyanmisaka MppMeta meta = mpp_packet_get_meta(packet);
341*437bfbebSnyanmisaka
342*437bfbebSnyanmisaka mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, frm->temporal_id);
343*437bfbebSnyanmisaka if (!frm->is_non_ref && frm->is_lt_ref)
344*437bfbebSnyanmisaka mpp_meta_set_s32(meta, KEY_LONG_REF_IDX, frm->lt_idx);
345*437bfbebSnyanmisaka }
346*437bfbebSnyanmisaka
347*437bfbebSnyanmisaka h265e_dbg_func("enter ctx %p \n", ctx);
348*437bfbebSnyanmisaka
349*437bfbebSnyanmisaka h265e_syntax_fill(ctx);
350*437bfbebSnyanmisaka
351*437bfbebSnyanmisaka task->valid = 1;
352*437bfbebSnyanmisaka task->syntax.number = 1;
353*437bfbebSnyanmisaka task->syntax.data = &p->syntax;
354*437bfbebSnyanmisaka
355*437bfbebSnyanmisaka h265e_dbg_func("leave ctx %p \n", ctx);
356*437bfbebSnyanmisaka return MPP_OK;
357*437bfbebSnyanmisaka }
358*437bfbebSnyanmisaka
h265e_proc_enc_skip(void * ctx,HalEncTask * task)359*437bfbebSnyanmisaka static MPP_RET h265e_proc_enc_skip(void *ctx, HalEncTask *task)
360*437bfbebSnyanmisaka {
361*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
362*437bfbebSnyanmisaka MppPacket pkt = task->packet;
363*437bfbebSnyanmisaka H265eSyntax_new *syntax = &p->syntax;
364*437bfbebSnyanmisaka RK_U8 *ptr = mpp_packet_get_pos(pkt);
365*437bfbebSnyanmisaka RK_U32 offset = mpp_packet_get_length(pkt);
366*437bfbebSnyanmisaka RK_U32 len = mpp_packet_get_size(pkt) - offset;
367*437bfbebSnyanmisaka RK_U32 new_length = 0;
368*437bfbebSnyanmisaka
369*437bfbebSnyanmisaka h265e_dbg_func("enter\n");
370*437bfbebSnyanmisaka ptr += offset;
371*437bfbebSnyanmisaka p->slice->m_sliceQp = task->rc_task->info.quality_target;
372*437bfbebSnyanmisaka new_length = h265e_code_slice_skip_frame(ctx, p->slice, ptr, len);
373*437bfbebSnyanmisaka task->length = new_length;
374*437bfbebSnyanmisaka task->rc_task->info.bit_real = 8 * new_length;
375*437bfbebSnyanmisaka p->dpb->curr->prev_ref_idx = syntax->sp.recon_pic.slot_idx;
376*437bfbebSnyanmisaka mpp_packet_add_segment_info(pkt, NAL_TRAIL_R, offset, new_length);
377*437bfbebSnyanmisaka mpp_buffer_sync_partial_end(mpp_packet_get_buffer(pkt), offset, new_length);
378*437bfbebSnyanmisaka
379*437bfbebSnyanmisaka h265e_dbg_func("leave\n");
380*437bfbebSnyanmisaka return MPP_OK;
381*437bfbebSnyanmisaka }
382*437bfbebSnyanmisaka
h265e_add_sei(MppPacket pkt,RK_S32 * length,RK_U8 uuid[16],const void * data,RK_S32 size)383*437bfbebSnyanmisaka static MPP_RET h265e_add_sei(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
384*437bfbebSnyanmisaka const void *data, RK_S32 size)
385*437bfbebSnyanmisaka {
386*437bfbebSnyanmisaka RK_U8 *ptr = mpp_packet_get_pos(pkt);
387*437bfbebSnyanmisaka RK_U32 offset = mpp_packet_get_length(pkt);
388*437bfbebSnyanmisaka RK_U32 new_length = 0;
389*437bfbebSnyanmisaka
390*437bfbebSnyanmisaka ptr += offset;
391*437bfbebSnyanmisaka
392*437bfbebSnyanmisaka if (uuid == uuid_refresh_cfg) {
393*437bfbebSnyanmisaka RK_U32 recovery_frame_cnt = ((RK_U32 *)data)[0] - 1;
394*437bfbebSnyanmisaka new_length = h265e_sei_recovery_point(ptr, uuid, &recovery_frame_cnt, 0);
395*437bfbebSnyanmisaka } else {
396*437bfbebSnyanmisaka new_length = h265e_data_to_sei(ptr, uuid, data, size);
397*437bfbebSnyanmisaka }
398*437bfbebSnyanmisaka *length = new_length;
399*437bfbebSnyanmisaka
400*437bfbebSnyanmisaka mpp_packet_set_length(pkt, offset + new_length);
401*437bfbebSnyanmisaka mpp_packet_add_segment_info(pkt, NAL_SEI_PREFIX, offset, new_length);
402*437bfbebSnyanmisaka
403*437bfbebSnyanmisaka return MPP_OK;
404*437bfbebSnyanmisaka }
405*437bfbebSnyanmisaka
h265e_proc_cfg(void * ctx,MpiCmd cmd,void * param)406*437bfbebSnyanmisaka static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
407*437bfbebSnyanmisaka {
408*437bfbebSnyanmisaka H265eCtx *p = (H265eCtx *)ctx;
409*437bfbebSnyanmisaka MppEncCfgSet *cfg = p->cfg;
410*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
411*437bfbebSnyanmisaka
412*437bfbebSnyanmisaka h265e_dbg_func("enter ctx %p cmd %08x\n", ctx, cmd);
413*437bfbebSnyanmisaka
414*437bfbebSnyanmisaka switch (cmd) {
415*437bfbebSnyanmisaka case MPP_ENC_SET_CFG : {
416*437bfbebSnyanmisaka } break;
417*437bfbebSnyanmisaka case MPP_ENC_GET_EXTRA_INFO: {
418*437bfbebSnyanmisaka MppPacket pkt_out = (MppPacket )param;
419*437bfbebSnyanmisaka h265e_set_extra_info(p);
420*437bfbebSnyanmisaka h265e_get_extra_info(p, pkt_out);
421*437bfbebSnyanmisaka } break;
422*437bfbebSnyanmisaka case MPP_ENC_SET_SEI_CFG: {
423*437bfbebSnyanmisaka } break;
424*437bfbebSnyanmisaka case MPP_ENC_SET_SPLIT : {
425*437bfbebSnyanmisaka MppEncSliceSplit *src = (MppEncSliceSplit *)param;
426*437bfbebSnyanmisaka MppEncH265SliceCfg *slice_cfg = &cfg->h265.slice_cfg;
427*437bfbebSnyanmisaka
428*437bfbebSnyanmisaka if (src->split_mode > MPP_ENC_SPLIT_NONE) {
429*437bfbebSnyanmisaka slice_cfg->split_enable = 1;
430*437bfbebSnyanmisaka slice_cfg->split_mode = 0;
431*437bfbebSnyanmisaka if (src->split_mode == MPP_ENC_SPLIT_BY_CTU)
432*437bfbebSnyanmisaka slice_cfg->split_mode = 1;
433*437bfbebSnyanmisaka slice_cfg->slice_size = src->split_arg;
434*437bfbebSnyanmisaka } else {
435*437bfbebSnyanmisaka slice_cfg->split_enable = 0;
436*437bfbebSnyanmisaka }
437*437bfbebSnyanmisaka } break;
438*437bfbebSnyanmisaka default:
439*437bfbebSnyanmisaka mpp_err("No correspond %08x found, and can not config!\n", cmd);
440*437bfbebSnyanmisaka ret = MPP_NOK;
441*437bfbebSnyanmisaka break;
442*437bfbebSnyanmisaka }
443*437bfbebSnyanmisaka
444*437bfbebSnyanmisaka h265e_dbg_func("leave ctx %p\n", ctx);
445*437bfbebSnyanmisaka return ret;
446*437bfbebSnyanmisaka }
447*437bfbebSnyanmisaka
448*437bfbebSnyanmisaka const EncImplApi api_h265e = {
449*437bfbebSnyanmisaka "h265e_control",
450*437bfbebSnyanmisaka MPP_VIDEO_CodingHEVC,
451*437bfbebSnyanmisaka sizeof(H265eCtx),
452*437bfbebSnyanmisaka 0,
453*437bfbebSnyanmisaka h265e_init,
454*437bfbebSnyanmisaka h265e_deinit,
455*437bfbebSnyanmisaka h265e_proc_cfg,
456*437bfbebSnyanmisaka h265e_gen_hdr,
457*437bfbebSnyanmisaka h265e_start,
458*437bfbebSnyanmisaka h265e_proc_dpb,
459*437bfbebSnyanmisaka h265e_proc_hal,
460*437bfbebSnyanmisaka h265e_add_sei,
461*437bfbebSnyanmisaka h265e_proc_enc_skip,
462*437bfbebSnyanmisaka };
463