1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_enc_refs"
7*437bfbebSnyanmisaka
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka #include "mpp_mem.h"
12*437bfbebSnyanmisaka #include "mpp_debug.h"
13*437bfbebSnyanmisaka #include "mpp_common.h"
14*437bfbebSnyanmisaka
15*437bfbebSnyanmisaka #include "mpp_enc_ref.h"
16*437bfbebSnyanmisaka #include "mpp_enc_refs.h"
17*437bfbebSnyanmisaka
18*437bfbebSnyanmisaka #define MAX_CPB_ST_FRM 16
19*437bfbebSnyanmisaka #define MAX_CPB_LT_FRM 16
20*437bfbebSnyanmisaka #define MAX_CPB_TID_FRM 16
21*437bfbebSnyanmisaka #define MAX_CPB_LT_IDX 16
22*437bfbebSnyanmisaka #define MAX_CPB_FRM ((MAX_CPB_ST_FRM) + (MAX_CPB_LT_FRM))
23*437bfbebSnyanmisaka
24*437bfbebSnyanmisaka #define MPP_ENC_REFS_DBG_FUNC (0x00000001)
25*437bfbebSnyanmisaka #define MPP_ENC_REFS_DBG_FLOW (0x00000002)
26*437bfbebSnyanmisaka #define MPP_ENC_REFS_DBG_FRM (0x00000004)
27*437bfbebSnyanmisaka #define MPP_ENC_REFS_DBG_SIZE (0x00000008)
28*437bfbebSnyanmisaka
29*437bfbebSnyanmisaka #define enc_refs_dbg_func(fmt, ...) _mpp_dbg_f(enc_refs_debug, MPP_ENC_REFS_DBG_FUNC, fmt, ## __VA_ARGS__)
30*437bfbebSnyanmisaka #define enc_refs_dbg_flow(fmt, ...) _mpp_dbg_f(enc_refs_debug, MPP_ENC_REFS_DBG_FLOW, fmt, ## __VA_ARGS__)
31*437bfbebSnyanmisaka #define enc_refs_dbg_frm(fmt, ...) _mpp_dbg(enc_refs_debug, MPP_ENC_REFS_DBG_FRM, fmt, ## __VA_ARGS__)
32*437bfbebSnyanmisaka #define enc_refs_dbg_size(fmt, ...) _mpp_dbg(enc_refs_debug, MPP_ENC_REFS_DBG_SIZE, fmt, ## __VA_ARGS__)
33*437bfbebSnyanmisaka
34*437bfbebSnyanmisaka #define ENC_REFS_REF_CFG_CHANGED (0x00000001)
35*437bfbebSnyanmisaka #define ENC_REFS_USR_CFG_CHANGED (0x00000002)
36*437bfbebSnyanmisaka #define ENC_REFS_IGOP_CHANGED (0x00000004)
37*437bfbebSnyanmisaka
38*437bfbebSnyanmisaka typedef struct RefsCnt_t {
39*437bfbebSnyanmisaka RK_S32 delay;
40*437bfbebSnyanmisaka RK_S32 delay_cnt;
41*437bfbebSnyanmisaka RK_S32 len;
42*437bfbebSnyanmisaka RK_S32 cnt;
43*437bfbebSnyanmisaka RK_S32 idx;
44*437bfbebSnyanmisaka
45*437bfbebSnyanmisaka RK_S32 lt_idx;
46*437bfbebSnyanmisaka RK_S32 tid;
47*437bfbebSnyanmisaka MppEncRefMode ref_mode;
48*437bfbebSnyanmisaka RK_S32 ref_arg;
49*437bfbebSnyanmisaka } RefsCnt;
50*437bfbebSnyanmisaka
51*437bfbebSnyanmisaka typedef struct EncVirtualCpb_t {
52*437bfbebSnyanmisaka MppEncCpbInfo info;
53*437bfbebSnyanmisaka
54*437bfbebSnyanmisaka /*
55*437bfbebSnyanmisaka * max 32 reference slot for frame searching
56*437bfbebSnyanmisaka * (max 16 lt + max 16 st)
57*437bfbebSnyanmisaka * st_slot 0 ~ 15
58*437bfbebSnyanmisaka * lt_slot 16 ~ 31
59*437bfbebSnyanmisaka */
60*437bfbebSnyanmisaka EncFrmStatus cpb_refs[MAX_CPB_FRM];
61*437bfbebSnyanmisaka
62*437bfbebSnyanmisaka /* max 32 reference mode */
63*437bfbebSnyanmisaka EncFrmStatus mode_refs[MAX_CPB_FRM];
64*437bfbebSnyanmisaka
65*437bfbebSnyanmisaka /*
66*437bfbebSnyanmisaka * reference mode storage with args
67*437bfbebSnyanmisaka * st + tid - max 16
68*437bfbebSnyanmisaka * lt + idx - max 16
69*437bfbebSnyanmisaka */
70*437bfbebSnyanmisaka EncFrmStatus st_tid_refs[MAX_CPB_TID_FRM];
71*437bfbebSnyanmisaka EncFrmStatus lt_idx_refs[MAX_CPB_LT_IDX];
72*437bfbebSnyanmisaka
73*437bfbebSnyanmisaka /* long-term counter */
74*437bfbebSnyanmisaka /* lt ref will have multiple counters */
75*437bfbebSnyanmisaka RefsCnt lt_cnter[MAX_CPB_LT_IDX];
76*437bfbebSnyanmisaka
77*437bfbebSnyanmisaka /* max two list and each list as two frames */
78*437bfbebSnyanmisaka EncFrmStatus list0[2];
79*437bfbebSnyanmisaka EncFrmStatus list1[2];
80*437bfbebSnyanmisaka /* frame kept in cpb */
81*437bfbebSnyanmisaka EncFrmStatus cpb_st[2];
82*437bfbebSnyanmisaka
83*437bfbebSnyanmisaka /* runtime record */
84*437bfbebSnyanmisaka RK_S32 frm_idx; /* overall frame index */
85*437bfbebSnyanmisaka RK_S32 seq_idx; /* sequence index in one gop */
86*437bfbebSnyanmisaka RK_S32 seq_cnt;
87*437bfbebSnyanmisaka RK_S32 st_cfg_pos;
88*437bfbebSnyanmisaka RK_S32 st_cfg_repeat_pos;
89*437bfbebSnyanmisaka } EncVirtualCpb;
90*437bfbebSnyanmisaka
91*437bfbebSnyanmisaka typedef struct MppEncRefsImpl_t {
92*437bfbebSnyanmisaka RK_U32 changed;
93*437bfbebSnyanmisaka MppEncRefCfgImpl *ref_cfg;
94*437bfbebSnyanmisaka MppEncRefFrmUsrCfg usr_cfg;
95*437bfbebSnyanmisaka RK_S32 igop;
96*437bfbebSnyanmisaka RK_U32 refresh_length;
97*437bfbebSnyanmisaka
98*437bfbebSnyanmisaka RK_S32 hdr_need_update;
99*437bfbebSnyanmisaka
100*437bfbebSnyanmisaka EncVirtualCpb cpb;
101*437bfbebSnyanmisaka EncVirtualCpb cpb_stash;
102*437bfbebSnyanmisaka } MppEncRefsImpl;
103*437bfbebSnyanmisaka
104*437bfbebSnyanmisaka RK_U32 enc_refs_debug = 0;
105*437bfbebSnyanmisaka
_dump_frm(EncFrmStatus * frm,const char * func,RK_S32 line)106*437bfbebSnyanmisaka void _dump_frm(EncFrmStatus *frm, const char *func, RK_S32 line)
107*437bfbebSnyanmisaka {
108*437bfbebSnyanmisaka if (!frm->valid)
109*437bfbebSnyanmisaka return ;
110*437bfbebSnyanmisaka
111*437bfbebSnyanmisaka if (frm->is_non_ref) {
112*437bfbebSnyanmisaka mpp_log("%s:%d valid %d frm %d %s tid %d non-ref -> [%x:%d]\n",
113*437bfbebSnyanmisaka func, line, frm->valid, frm->seq_idx,
114*437bfbebSnyanmisaka frm->is_intra ? "intra" : "inter",
115*437bfbebSnyanmisaka frm->temporal_id, frm->ref_mode, frm->ref_arg);
116*437bfbebSnyanmisaka } else if (frm->is_lt_ref) {
117*437bfbebSnyanmisaka mpp_log("%s:%d valid %d frm %d %s tid %d lt-ref -> [%x:%d] lt_idx %d\n",
118*437bfbebSnyanmisaka func, line, frm->valid, frm->seq_idx,
119*437bfbebSnyanmisaka frm->is_intra ? "intra" : "inter",
120*437bfbebSnyanmisaka frm->temporal_id, frm->ref_mode, frm->ref_arg,
121*437bfbebSnyanmisaka frm->lt_idx);
122*437bfbebSnyanmisaka } else {
123*437bfbebSnyanmisaka mpp_log("%s:%d valid %d frm %d %s tid %d st-ref -> [%x:%d]\n",
124*437bfbebSnyanmisaka func, line, frm->valid, frm->seq_idx,
125*437bfbebSnyanmisaka frm->is_intra ? "intra" : "inter",
126*437bfbebSnyanmisaka frm->temporal_id, frm->ref_mode, frm->ref_arg);
127*437bfbebSnyanmisaka }
128*437bfbebSnyanmisaka }
129*437bfbebSnyanmisaka
130*437bfbebSnyanmisaka #define dump_cpb(cpb) _dump_cpb(cpb, __FUNCTION__, __LINE__)
131*437bfbebSnyanmisaka
_dump_cpb(EncVirtualCpb * cpb,const char * func,RK_S32 line)132*437bfbebSnyanmisaka void _dump_cpb(EncVirtualCpb *cpb, const char *func, RK_S32 line)
133*437bfbebSnyanmisaka {
134*437bfbebSnyanmisaka MppEncCpbInfo *info = &cpb->info;
135*437bfbebSnyanmisaka RK_S32 i;
136*437bfbebSnyanmisaka
137*437bfbebSnyanmisaka mpp_log("%s:%d cpb %p status:\n", func, line, cpb);
138*437bfbebSnyanmisaka mpp_log("cpb info: dpb_size %d max_lt/st cnt [%d:%d] \n",
139*437bfbebSnyanmisaka info->dpb_size, info->max_lt_cnt, info->max_st_cnt);
140*437bfbebSnyanmisaka mpp_log("cpb info: max_lt_idx %d max_st_tid %d\n",
141*437bfbebSnyanmisaka info->max_lt_idx, info->max_st_tid);
142*437bfbebSnyanmisaka mpp_log("cpb info: lt_gop %d st_gop %d\n",
143*437bfbebSnyanmisaka info->lt_gop, info->st_gop);
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka mpp_log("cpb cpb_refs:\n");
146*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_FRM; i++)
147*437bfbebSnyanmisaka dump_frm(&cpb->cpb_refs[i]);
148*437bfbebSnyanmisaka
149*437bfbebSnyanmisaka mpp_log("cpb mode_refs:\n");
150*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_FRM; i++)
151*437bfbebSnyanmisaka dump_frm(&cpb->mode_refs[i]);
152*437bfbebSnyanmisaka
153*437bfbebSnyanmisaka mpp_log("cpb st_tid_refs:\n");
154*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_TID_FRM; i++)
155*437bfbebSnyanmisaka dump_frm(&cpb->st_tid_refs[i]);
156*437bfbebSnyanmisaka
157*437bfbebSnyanmisaka mpp_log("cpb lt_idx_refs:\n");
158*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_LT_IDX; i++)
159*437bfbebSnyanmisaka dump_frm(&cpb->lt_idx_refs[i]);
160*437bfbebSnyanmisaka
161*437bfbebSnyanmisaka mpp_log("cpb runtime: frm_idx %d seq_idx %d seq_cnt %d st_cfg [%d:%d]\n",
162*437bfbebSnyanmisaka cpb->frm_idx, cpb->seq_idx, cpb->seq_cnt,
163*437bfbebSnyanmisaka cpb->st_cfg_pos, cpb->st_cfg_repeat_pos);
164*437bfbebSnyanmisaka }
165*437bfbebSnyanmisaka
mpp_enc_refs_init(MppEncRefs * refs)166*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_init(MppEncRefs *refs)
167*437bfbebSnyanmisaka {
168*437bfbebSnyanmisaka if (NULL == refs) {
169*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
170*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
171*437bfbebSnyanmisaka }
172*437bfbebSnyanmisaka
173*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
174*437bfbebSnyanmisaka
175*437bfbebSnyanmisaka MppEncRefsImpl *p = mpp_calloc(MppEncRefsImpl, 1);
176*437bfbebSnyanmisaka *refs = p;
177*437bfbebSnyanmisaka if (NULL == p) {
178*437bfbebSnyanmisaka mpp_err_f("create refs_impl failed\n");
179*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
180*437bfbebSnyanmisaka }
181*437bfbebSnyanmisaka
182*437bfbebSnyanmisaka mpp_env_get_u32("enc_refs_debug", &enc_refs_debug, 0);
183*437bfbebSnyanmisaka
184*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", p);
185*437bfbebSnyanmisaka return MPP_OK;
186*437bfbebSnyanmisaka }
187*437bfbebSnyanmisaka
mpp_enc_refs_deinit(MppEncRefs * refs)188*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_deinit(MppEncRefs *refs)
189*437bfbebSnyanmisaka {
190*437bfbebSnyanmisaka if (NULL == refs) {
191*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
192*437bfbebSnyanmisaka return MPP_ERR_VALUE;
193*437bfbebSnyanmisaka }
194*437bfbebSnyanmisaka
195*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
196*437bfbebSnyanmisaka
197*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)(*refs);
198*437bfbebSnyanmisaka MPP_FREE(p);
199*437bfbebSnyanmisaka
200*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
201*437bfbebSnyanmisaka return MPP_OK;
202*437bfbebSnyanmisaka }
203*437bfbebSnyanmisaka
mpp_enc_refs_set_cfg(MppEncRefs refs,MppEncRefCfg ref_cfg)204*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_set_cfg(MppEncRefs refs, MppEncRefCfg ref_cfg)
205*437bfbebSnyanmisaka {
206*437bfbebSnyanmisaka if (NULL == refs || (ref_cfg && check_is_mpp_enc_ref_cfg(ref_cfg))) {
207*437bfbebSnyanmisaka mpp_err_f("invalid input refs %p ref_cfg %p\n", refs, ref_cfg);
208*437bfbebSnyanmisaka return MPP_ERR_VALUE;
209*437bfbebSnyanmisaka }
210*437bfbebSnyanmisaka
211*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p cfg %p\n", refs, ref_cfg);
212*437bfbebSnyanmisaka
213*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
214*437bfbebSnyanmisaka EncVirtualCpb *cpb = &p->cpb;
215*437bfbebSnyanmisaka MppEncRefCfgImpl *cfg = NULL;
216*437bfbebSnyanmisaka
217*437bfbebSnyanmisaka if (NULL == ref_cfg)
218*437bfbebSnyanmisaka ref_cfg = mpp_enc_ref_default();
219*437bfbebSnyanmisaka
220*437bfbebSnyanmisaka cfg = (MppEncRefCfgImpl *)ref_cfg;
221*437bfbebSnyanmisaka
222*437bfbebSnyanmisaka p->ref_cfg = cfg;
223*437bfbebSnyanmisaka p->changed |= ENC_REFS_REF_CFG_CHANGED;
224*437bfbebSnyanmisaka p->hdr_need_update = 0;
225*437bfbebSnyanmisaka
226*437bfbebSnyanmisaka /* clear cpb on setup new cfg */
227*437bfbebSnyanmisaka if (!cfg->keep_cpb) {
228*437bfbebSnyanmisaka memset(cpb, 0, sizeof(*cpb));
229*437bfbebSnyanmisaka p->hdr_need_update = 1;
230*437bfbebSnyanmisaka }
231*437bfbebSnyanmisaka
232*437bfbebSnyanmisaka if (cfg->lt_cfg_cnt) {
233*437bfbebSnyanmisaka RK_S32 i;
234*437bfbebSnyanmisaka
235*437bfbebSnyanmisaka mpp_assert(cfg->lt_cfg_cnt < MAX_CPB_LT_FRM);
236*437bfbebSnyanmisaka
237*437bfbebSnyanmisaka for (i = 0; i < cfg->lt_cfg_cnt; i++) {
238*437bfbebSnyanmisaka RefsCnt *lt_cnt = &cpb->lt_cnter[i];
239*437bfbebSnyanmisaka MppEncRefLtFrmCfg *lt_cfg = &cfg->lt_cfg[i];
240*437bfbebSnyanmisaka
241*437bfbebSnyanmisaka lt_cnt->delay = lt_cfg->lt_delay;
242*437bfbebSnyanmisaka lt_cnt->delay_cnt = lt_cfg->lt_delay;
243*437bfbebSnyanmisaka lt_cnt->len = lt_cfg->lt_gap;
244*437bfbebSnyanmisaka lt_cnt->lt_idx = lt_cfg->lt_idx;
245*437bfbebSnyanmisaka lt_cnt->tid = lt_cfg->temporal_id;
246*437bfbebSnyanmisaka lt_cnt->ref_mode = lt_cfg->ref_mode;
247*437bfbebSnyanmisaka lt_cnt->ref_arg = lt_cfg->ref_arg;
248*437bfbebSnyanmisaka }
249*437bfbebSnyanmisaka }
250*437bfbebSnyanmisaka
251*437bfbebSnyanmisaka MppEncCpbInfo *info = &cpb->info;
252*437bfbebSnyanmisaka
253*437bfbebSnyanmisaka if (info->dpb_size && info->dpb_size < cfg->cpb_info.dpb_size)
254*437bfbebSnyanmisaka p->hdr_need_update = 1;
255*437bfbebSnyanmisaka
256*437bfbebSnyanmisaka memcpy(info, &cfg->cpb_info, sizeof(cfg->cpb_info));
257*437bfbebSnyanmisaka
258*437bfbebSnyanmisaka enc_refs_dbg_flow("ref_cfg cpb size: lt %d st %d max lt_idx %d tid %d\n",
259*437bfbebSnyanmisaka info->max_lt_cnt, info->max_st_cnt,
260*437bfbebSnyanmisaka info->max_lt_idx, info->max_st_tid);
261*437bfbebSnyanmisaka
262*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p cfg %p\n", refs, ref_cfg);
263*437bfbebSnyanmisaka return MPP_OK;
264*437bfbebSnyanmisaka }
265*437bfbebSnyanmisaka
cleanup_cpb_refs(EncVirtualCpb * cpb)266*437bfbebSnyanmisaka static void cleanup_cpb_refs(EncVirtualCpb *cpb)
267*437bfbebSnyanmisaka {
268*437bfbebSnyanmisaka RK_U32 i;
269*437bfbebSnyanmisaka
270*437bfbebSnyanmisaka memset(cpb->cpb_refs, 0, sizeof(cpb->cpb_refs));
271*437bfbebSnyanmisaka memset(cpb->mode_refs, 0, sizeof(cpb->mode_refs));
272*437bfbebSnyanmisaka memset(cpb->st_tid_refs, 0, sizeof(cpb->st_tid_refs));
273*437bfbebSnyanmisaka memset(cpb->lt_idx_refs, 0, sizeof(cpb->lt_idx_refs));
274*437bfbebSnyanmisaka memset(cpb->list0, 0, sizeof(cpb->list0));
275*437bfbebSnyanmisaka memset(cpb->list1, 0, sizeof(cpb->list1));
276*437bfbebSnyanmisaka memset(cpb->cpb_st, 0, sizeof(cpb->cpb_st));
277*437bfbebSnyanmisaka
278*437bfbebSnyanmisaka cpb->seq_idx = 0;
279*437bfbebSnyanmisaka cpb->seq_cnt++;
280*437bfbebSnyanmisaka cpb->st_cfg_pos = 0;
281*437bfbebSnyanmisaka cpb->st_cfg_repeat_pos = 0;
282*437bfbebSnyanmisaka
283*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(cpb->lt_cnter); i++) {
284*437bfbebSnyanmisaka RefsCnt *lt_cnt = &cpb->lt_cnter[i];
285*437bfbebSnyanmisaka
286*437bfbebSnyanmisaka lt_cnt->delay_cnt = lt_cnt->delay;
287*437bfbebSnyanmisaka lt_cnt->cnt = 0;
288*437bfbebSnyanmisaka lt_cnt->idx = 0;
289*437bfbebSnyanmisaka }
290*437bfbebSnyanmisaka }
291*437bfbebSnyanmisaka
set_st_cfg_to_frm(EncFrmStatus * frm,RK_S32 seq_idx,MppEncRefStFrmCfg * st_cfg)292*437bfbebSnyanmisaka static void set_st_cfg_to_frm(EncFrmStatus *frm, RK_S32 seq_idx,
293*437bfbebSnyanmisaka MppEncRefStFrmCfg *st_cfg)
294*437bfbebSnyanmisaka {
295*437bfbebSnyanmisaka memset(frm, 0, sizeof(*frm));
296*437bfbebSnyanmisaka
297*437bfbebSnyanmisaka frm->seq_idx = seq_idx;
298*437bfbebSnyanmisaka frm->valid = 1;
299*437bfbebSnyanmisaka frm->is_idr = (seq_idx == 0);
300*437bfbebSnyanmisaka frm->is_intra = frm->is_idr;
301*437bfbebSnyanmisaka frm->is_non_ref = st_cfg->is_non_ref;
302*437bfbebSnyanmisaka frm->is_lt_ref = 0;
303*437bfbebSnyanmisaka frm->temporal_id = st_cfg->temporal_id;
304*437bfbebSnyanmisaka frm->ref_mode = st_cfg->ref_mode;
305*437bfbebSnyanmisaka frm->ref_arg = st_cfg->ref_arg;
306*437bfbebSnyanmisaka
307*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM)
308*437bfbebSnyanmisaka dump_frm(frm);
309*437bfbebSnyanmisaka }
310*437bfbebSnyanmisaka
set_frm_refresh_flag(EncFrmStatus * frm,MppEncRefsImpl * p)311*437bfbebSnyanmisaka static MPP_RET set_frm_refresh_flag(EncFrmStatus *frm, MppEncRefsImpl *p)
312*437bfbebSnyanmisaka {
313*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
314*437bfbebSnyanmisaka
315*437bfbebSnyanmisaka if (!frm || !p)
316*437bfbebSnyanmisaka return ret = MPP_ERR_NULL_PTR;
317*437bfbebSnyanmisaka
318*437bfbebSnyanmisaka if (p->refresh_length) {
319*437bfbebSnyanmisaka frm->is_i_refresh = ((frm->seq_idx % p->igop) < p->refresh_length) && p->cpb.seq_cnt > 1;
320*437bfbebSnyanmisaka frm->is_i_recovery = !(frm->seq_idx % p->igop) && p->cpb.seq_cnt > 1;
321*437bfbebSnyanmisaka } else
322*437bfbebSnyanmisaka frm->is_i_refresh = 0;
323*437bfbebSnyanmisaka
324*437bfbebSnyanmisaka return ret;
325*437bfbebSnyanmisaka }
326*437bfbebSnyanmisaka
set_lt_cfg_to_frm(EncFrmStatus * frm,RefsCnt * lt_cfg)327*437bfbebSnyanmisaka static void set_lt_cfg_to_frm(EncFrmStatus *frm, RefsCnt *lt_cfg)
328*437bfbebSnyanmisaka {
329*437bfbebSnyanmisaka frm->is_non_ref = 0;
330*437bfbebSnyanmisaka frm->is_lt_ref = 1;
331*437bfbebSnyanmisaka frm->temporal_id = lt_cfg->tid;
332*437bfbebSnyanmisaka frm->lt_idx = lt_cfg->lt_idx;
333*437bfbebSnyanmisaka
334*437bfbebSnyanmisaka if (lt_cfg->ref_mode != REF_TO_ST_REF_SETUP) {
335*437bfbebSnyanmisaka frm->ref_mode = lt_cfg->ref_mode;
336*437bfbebSnyanmisaka frm->ref_arg = lt_cfg->ref_arg;
337*437bfbebSnyanmisaka }
338*437bfbebSnyanmisaka
339*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM)
340*437bfbebSnyanmisaka dump_frm(frm);
341*437bfbebSnyanmisaka }
342*437bfbebSnyanmisaka
get_ref_from_cpb(EncVirtualCpb * cpb,EncFrmStatus * frm)343*437bfbebSnyanmisaka static EncFrmStatus *get_ref_from_cpb(EncVirtualCpb *cpb, EncFrmStatus *frm)
344*437bfbebSnyanmisaka {
345*437bfbebSnyanmisaka MppEncRefMode ref_mode = frm->ref_mode;
346*437bfbebSnyanmisaka RK_S32 ref_arg = frm->ref_arg;
347*437bfbebSnyanmisaka
348*437bfbebSnyanmisaka if (frm->is_idr)
349*437bfbebSnyanmisaka return NULL;
350*437bfbebSnyanmisaka
351*437bfbebSnyanmisaka EncFrmStatus *ref = NULL;
352*437bfbebSnyanmisaka
353*437bfbebSnyanmisaka /* step 3.1 find seq_idx by mode and arg */
354*437bfbebSnyanmisaka switch (ref_mode) {
355*437bfbebSnyanmisaka case REF_TO_PREV_REF_FRM :
356*437bfbebSnyanmisaka case REF_TO_PREV_ST_REF :
357*437bfbebSnyanmisaka case REF_TO_PREV_LT_REF :
358*437bfbebSnyanmisaka case REF_TO_PREV_INTRA : {
359*437bfbebSnyanmisaka ref = &cpb->mode_refs[ref_mode];
360*437bfbebSnyanmisaka } break;
361*437bfbebSnyanmisaka case REF_TO_TEMPORAL_LAYER : {
362*437bfbebSnyanmisaka ref = &cpb->st_tid_refs[ref_arg];
363*437bfbebSnyanmisaka } break;
364*437bfbebSnyanmisaka case REF_TO_LT_REF_IDX : {
365*437bfbebSnyanmisaka ref = &cpb->lt_idx_refs[ref_arg];
366*437bfbebSnyanmisaka } break;
367*437bfbebSnyanmisaka case REF_TO_ST_PREV_N_REF : {
368*437bfbebSnyanmisaka ref = &cpb->cpb_refs[ref_arg];
369*437bfbebSnyanmisaka } break;
370*437bfbebSnyanmisaka case REF_TO_ST_REF_SETUP :
371*437bfbebSnyanmisaka default : {
372*437bfbebSnyanmisaka mpp_err_f("frm %d not supported ref mode 0x%x\n", frm->seq_idx, ref_mode);
373*437bfbebSnyanmisaka } break;
374*437bfbebSnyanmisaka }
375*437bfbebSnyanmisaka
376*437bfbebSnyanmisaka if (ref) {
377*437bfbebSnyanmisaka if (ref->valid)
378*437bfbebSnyanmisaka enc_refs_dbg_flow("frm %d ref mode %d arg %d -> seq %d %s idx %d\n",
379*437bfbebSnyanmisaka frm->seq_idx, ref_mode, ref_arg, ref->seq_idx,
380*437bfbebSnyanmisaka ref->is_lt_ref ? "lt" : "st",
381*437bfbebSnyanmisaka ref->is_lt_ref ? ref->lt_idx : 0);
382*437bfbebSnyanmisaka else
383*437bfbebSnyanmisaka mpp_err_f("frm %d found mode %d arg %d -> ref %d but it is invalid\n",
384*437bfbebSnyanmisaka frm->seq_idx, ref_mode, ref_arg, ref->seq_idx);
385*437bfbebSnyanmisaka } else {
386*437bfbebSnyanmisaka ref = NULL;
387*437bfbebSnyanmisaka }
388*437bfbebSnyanmisaka
389*437bfbebSnyanmisaka return ref;
390*437bfbebSnyanmisaka }
391*437bfbebSnyanmisaka
check_ref_cpb_pos(EncVirtualCpb * cpb,EncFrmStatus * frm)392*437bfbebSnyanmisaka static RK_S32 check_ref_cpb_pos(EncVirtualCpb *cpb, EncFrmStatus *frm)
393*437bfbebSnyanmisaka {
394*437bfbebSnyanmisaka RK_S32 seq_idx = frm->seq_idx;
395*437bfbebSnyanmisaka RK_S32 found = 0;
396*437bfbebSnyanmisaka RK_S32 pos = -1;
397*437bfbebSnyanmisaka
398*437bfbebSnyanmisaka if (!frm->valid || frm->is_non_ref) {
399*437bfbebSnyanmisaka enc_refs_dbg_flow("frm %d is not valid ref frm\n", seq_idx);
400*437bfbebSnyanmisaka return pos;
401*437bfbebSnyanmisaka }
402*437bfbebSnyanmisaka
403*437bfbebSnyanmisaka if (frm->is_lt_ref) {
404*437bfbebSnyanmisaka /* find same lt_idx */
405*437bfbebSnyanmisaka for (pos = 0; pos < MAX_CPB_LT_FRM; pos++) {
406*437bfbebSnyanmisaka RK_S32 cpb_idx = pos + MAX_CPB_ST_FRM;
407*437bfbebSnyanmisaka EncFrmStatus *cpb_ref = &cpb->cpb_refs[cpb_idx];
408*437bfbebSnyanmisaka
409*437bfbebSnyanmisaka if (cpb_ref->valid && cpb_ref->lt_idx == frm->lt_idx) {
410*437bfbebSnyanmisaka pos = cpb_idx;
411*437bfbebSnyanmisaka enc_refs_dbg_flow("found ltr ref %d at pos %d\n", seq_idx, pos);
412*437bfbebSnyanmisaka found = 1;
413*437bfbebSnyanmisaka break;
414*437bfbebSnyanmisaka }
415*437bfbebSnyanmisaka }
416*437bfbebSnyanmisaka } else {
417*437bfbebSnyanmisaka /* search seq_idx in cpb to check the st cpb size */
418*437bfbebSnyanmisaka for (pos = 0; pos < MAX_CPB_ST_FRM; pos++) {
419*437bfbebSnyanmisaka EncFrmStatus *cpb_ref = &cpb->cpb_refs[pos];
420*437bfbebSnyanmisaka
421*437bfbebSnyanmisaka enc_refs_dbg_flow("matching ref %d at pos %d %d\n",
422*437bfbebSnyanmisaka seq_idx, pos, cpb_ref->seq_idx);
423*437bfbebSnyanmisaka
424*437bfbebSnyanmisaka if (cpb_ref->valid && cpb_ref->seq_idx == seq_idx) {
425*437bfbebSnyanmisaka enc_refs_dbg_flow("found ref %d at pos %d\n", seq_idx, pos);
426*437bfbebSnyanmisaka found = 1;
427*437bfbebSnyanmisaka break;
428*437bfbebSnyanmisaka }
429*437bfbebSnyanmisaka }
430*437bfbebSnyanmisaka }
431*437bfbebSnyanmisaka
432*437bfbebSnyanmisaka if (!found) {
433*437bfbebSnyanmisaka mpp_err_f("frm %d can NOT be found in st refs!!\n", seq_idx);
434*437bfbebSnyanmisaka pos = -1;
435*437bfbebSnyanmisaka dump_cpb(cpb);
436*437bfbebSnyanmisaka }
437*437bfbebSnyanmisaka
438*437bfbebSnyanmisaka return pos;
439*437bfbebSnyanmisaka }
440*437bfbebSnyanmisaka
save_cpb_status(EncVirtualCpb * cpb,EncFrmStatus * refs)441*437bfbebSnyanmisaka static void save_cpb_status(EncVirtualCpb *cpb, EncFrmStatus *refs)
442*437bfbebSnyanmisaka {
443*437bfbebSnyanmisaka EncFrmStatus *ref = &cpb->cpb_refs[MAX_CPB_ST_FRM];
444*437bfbebSnyanmisaka MppEncCpbInfo *info = &cpb->info;
445*437bfbebSnyanmisaka RK_S32 dpb_size = info->dpb_size;
446*437bfbebSnyanmisaka RK_S32 lt_ref_cnt = 0;
447*437bfbebSnyanmisaka RK_S32 st_ref_cnt = 0;
448*437bfbebSnyanmisaka RK_S32 ref_cnt = 0;
449*437bfbebSnyanmisaka RK_S32 i;
450*437bfbebSnyanmisaka
451*437bfbebSnyanmisaka /* save lt ref */
452*437bfbebSnyanmisaka for (i = 0; i < info->max_lt_cnt; i++, ref++) {
453*437bfbebSnyanmisaka if (!ref->valid || ref->is_non_ref || !ref->is_lt_ref)
454*437bfbebSnyanmisaka continue;
455*437bfbebSnyanmisaka
456*437bfbebSnyanmisaka mpp_assert(!ref->is_non_ref);
457*437bfbebSnyanmisaka mpp_assert(ref->is_lt_ref);
458*437bfbebSnyanmisaka mpp_assert(ref->lt_idx >= 0);
459*437bfbebSnyanmisaka
460*437bfbebSnyanmisaka enc_refs_dbg_flow("save lt ref %d to slot %d\n", ref->seq_idx, ref_cnt);
461*437bfbebSnyanmisaka refs[ref_cnt++].val = ref->val;
462*437bfbebSnyanmisaka lt_ref_cnt++;
463*437bfbebSnyanmisaka }
464*437bfbebSnyanmisaka
465*437bfbebSnyanmisaka ref = &cpb->cpb_refs[0];
466*437bfbebSnyanmisaka /* save st ref */
467*437bfbebSnyanmisaka if (ref_cnt < dpb_size) {
468*437bfbebSnyanmisaka RK_S32 max_st_cnt = info->max_st_cnt;
469*437bfbebSnyanmisaka
470*437bfbebSnyanmisaka if (max_st_cnt < dpb_size - ref_cnt)
471*437bfbebSnyanmisaka max_st_cnt = dpb_size - ref_cnt;
472*437bfbebSnyanmisaka
473*437bfbebSnyanmisaka for (i = 0; i < max_st_cnt; i++, ref++) {
474*437bfbebSnyanmisaka if (!ref->valid || ref->is_non_ref || ref->is_lt_ref)
475*437bfbebSnyanmisaka continue;
476*437bfbebSnyanmisaka
477*437bfbebSnyanmisaka mpp_assert(!ref->is_non_ref);
478*437bfbebSnyanmisaka mpp_assert(!ref->is_lt_ref);
479*437bfbebSnyanmisaka mpp_assert(ref->temporal_id >= 0);
480*437bfbebSnyanmisaka
481*437bfbebSnyanmisaka enc_refs_dbg_flow("save st ref %d to slot %d\n", ref->seq_idx, ref_cnt);
482*437bfbebSnyanmisaka refs[ref_cnt++].val = ref->val;
483*437bfbebSnyanmisaka st_ref_cnt++;
484*437bfbebSnyanmisaka }
485*437bfbebSnyanmisaka }
486*437bfbebSnyanmisaka
487*437bfbebSnyanmisaka enc_refs_dbg_flow("save ref total %d lt %d st %d\n", ref_cnt, lt_ref_cnt, st_ref_cnt);
488*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FLOW)
489*437bfbebSnyanmisaka for (i = 0; i < ref_cnt; i++)
490*437bfbebSnyanmisaka dump_frm(&refs[i]);
491*437bfbebSnyanmisaka }
492*437bfbebSnyanmisaka
store_ref_to_cpb(EncVirtualCpb * cpb,EncFrmStatus * frm)493*437bfbebSnyanmisaka static void store_ref_to_cpb(EncVirtualCpb *cpb, EncFrmStatus *frm)
494*437bfbebSnyanmisaka {
495*437bfbebSnyanmisaka RK_S32 seq_idx = frm->seq_idx;
496*437bfbebSnyanmisaka RK_S32 lt_idx = frm->lt_idx;
497*437bfbebSnyanmisaka RK_S32 tid = frm->temporal_id;
498*437bfbebSnyanmisaka RK_S32 i;
499*437bfbebSnyanmisaka
500*437bfbebSnyanmisaka mpp_assert(frm->valid);
501*437bfbebSnyanmisaka mpp_assert(lt_idx < MAX_CPB_LT_IDX);
502*437bfbebSnyanmisaka mpp_assert(tid < MAX_CPB_LT_FRM);
503*437bfbebSnyanmisaka
504*437bfbebSnyanmisaka /* non-ref do not save to cpb */
505*437bfbebSnyanmisaka if (frm->is_non_ref)
506*437bfbebSnyanmisaka return ;
507*437bfbebSnyanmisaka
508*437bfbebSnyanmisaka if (frm->is_intra)
509*437bfbebSnyanmisaka cpb->mode_refs[REF_TO_PREV_INTRA].val = frm->val;
510*437bfbebSnyanmisaka
511*437bfbebSnyanmisaka if (frm->is_lt_ref) {
512*437bfbebSnyanmisaka cpb->lt_idx_refs[lt_idx].val = frm->val;
513*437bfbebSnyanmisaka cpb->st_tid_refs[tid].val = frm->val;
514*437bfbebSnyanmisaka cpb->mode_refs[REF_TO_PREV_REF_FRM].val = frm->val;
515*437bfbebSnyanmisaka cpb->mode_refs[REF_TO_PREV_LT_REF].val = frm->val;
516*437bfbebSnyanmisaka
517*437bfbebSnyanmisaka RK_S32 found = 0;
518*437bfbebSnyanmisaka EncFrmStatus *cpb_ref = NULL;
519*437bfbebSnyanmisaka
520*437bfbebSnyanmisaka /* find same lt_idx and replace */
521*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_LT_FRM; i++) {
522*437bfbebSnyanmisaka RK_S32 cpb_idx = i + MAX_CPB_ST_FRM;
523*437bfbebSnyanmisaka cpb_ref = &cpb->cpb_refs[cpb_idx];
524*437bfbebSnyanmisaka
525*437bfbebSnyanmisaka if (!cpb_ref->valid) {
526*437bfbebSnyanmisaka found = 1;
527*437bfbebSnyanmisaka break;
528*437bfbebSnyanmisaka } else {
529*437bfbebSnyanmisaka if (cpb_ref->lt_idx == lt_idx) {
530*437bfbebSnyanmisaka found = 2;
531*437bfbebSnyanmisaka break;
532*437bfbebSnyanmisaka }
533*437bfbebSnyanmisaka }
534*437bfbebSnyanmisaka }
535*437bfbebSnyanmisaka
536*437bfbebSnyanmisaka if (found) {
537*437bfbebSnyanmisaka cpb_ref->val = frm->val;
538*437bfbebSnyanmisaka enc_refs_dbg_flow("frm %d with lt idx %d %s to pos %d\n",
539*437bfbebSnyanmisaka seq_idx, lt_idx, (found == 1) ? "add" : "replace", i);
540*437bfbebSnyanmisaka } else {
541*437bfbebSnyanmisaka mpp_err_f("frm %d with lt idx %d found no place to add or relace\n",
542*437bfbebSnyanmisaka seq_idx, lt_idx);
543*437bfbebSnyanmisaka }
544*437bfbebSnyanmisaka } else {
545*437bfbebSnyanmisaka /* do normal st sliding window */
546*437bfbebSnyanmisaka cpb->st_tid_refs[tid].val = frm->val;
547*437bfbebSnyanmisaka cpb->mode_refs[REF_TO_PREV_REF_FRM].val = frm->val;
548*437bfbebSnyanmisaka cpb->mode_refs[REF_TO_PREV_ST_REF].val = frm->val;
549*437bfbebSnyanmisaka
550*437bfbebSnyanmisaka for (i = MAX_CPB_ST_FRM - 1; i > 0; i--)
551*437bfbebSnyanmisaka cpb->cpb_refs[i].val = cpb->cpb_refs[i - 1].val;
552*437bfbebSnyanmisaka
553*437bfbebSnyanmisaka cpb->cpb_refs[0].val = frm->val;
554*437bfbebSnyanmisaka
555*437bfbebSnyanmisaka // TODO: Add prev intra valid check?
556*437bfbebSnyanmisaka }
557*437bfbebSnyanmisaka
558*437bfbebSnyanmisaka enc_refs_dbg_flow("dumping cpb refs status start\n");
559*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FLOW)
560*437bfbebSnyanmisaka for (i = 0; i < MAX_CPB_FRM; i++)
561*437bfbebSnyanmisaka if (cpb->cpb_refs[i].valid)
562*437bfbebSnyanmisaka dump_frm(&cpb->cpb_refs[i]);
563*437bfbebSnyanmisaka
564*437bfbebSnyanmisaka enc_refs_dbg_flow("dumping cpb refs status done\n");
565*437bfbebSnyanmisaka }
566*437bfbebSnyanmisaka
mpp_enc_refs_dryrun(MppEncRefs refs)567*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_dryrun(MppEncRefs refs)
568*437bfbebSnyanmisaka {
569*437bfbebSnyanmisaka if (NULL == refs) {
570*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
571*437bfbebSnyanmisaka return MPP_ERR_VALUE;
572*437bfbebSnyanmisaka }
573*437bfbebSnyanmisaka
574*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
575*437bfbebSnyanmisaka
576*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
577*437bfbebSnyanmisaka MppEncRefCfgImpl *cfg = p->ref_cfg;
578*437bfbebSnyanmisaka MppEncRefStFrmCfg *st_cfg = cfg->st_cfg;
579*437bfbebSnyanmisaka EncVirtualCpb *cpb = &p->cpb;
580*437bfbebSnyanmisaka MppEncCpbInfo *info = &cpb->info;
581*437bfbebSnyanmisaka RK_S32 lt_cfg_cnt = cfg->lt_cfg_cnt;
582*437bfbebSnyanmisaka RK_S32 st_cfg_cnt = cfg->st_cfg_cnt;
583*437bfbebSnyanmisaka RK_S32 cpb_st_used_size = 0;
584*437bfbebSnyanmisaka RK_S32 seq_idx = 0;
585*437bfbebSnyanmisaka RK_S32 st_idx;
586*437bfbebSnyanmisaka RK_S32 walk_len = MPP_MAX(lt_cfg_cnt, st_cfg_cnt);
587*437bfbebSnyanmisaka
588*437bfbebSnyanmisaka if (cfg->ready)
589*437bfbebSnyanmisaka goto DONE;
590*437bfbebSnyanmisaka
591*437bfbebSnyanmisaka cleanup_cpb_refs(cpb);
592*437bfbebSnyanmisaka
593*437bfbebSnyanmisaka cfg->max_tlayers = cpb->info.max_st_tid + 1;
594*437bfbebSnyanmisaka enc_refs_dbg_flow("dryrun start: lt_cfg %d st_cfg %d\n",
595*437bfbebSnyanmisaka lt_cfg_cnt, st_cfg_cnt);
596*437bfbebSnyanmisaka
597*437bfbebSnyanmisaka for (st_idx = 0; st_idx < walk_len; st_idx++) {
598*437bfbebSnyanmisaka st_cfg = &cfg->st_cfg[st_idx % st_cfg_cnt];
599*437bfbebSnyanmisaka EncFrmStatus frm;
600*437bfbebSnyanmisaka RK_S32 repeat = (st_cfg->repeat) ? st_cfg->repeat : 1;
601*437bfbebSnyanmisaka
602*437bfbebSnyanmisaka while (repeat-- > 0) {
603*437bfbebSnyanmisaka /* step 1. updated by st_cfg */
604*437bfbebSnyanmisaka set_st_cfg_to_frm(&frm, seq_idx++, st_cfg);
605*437bfbebSnyanmisaka set_frm_refresh_flag(&frm, p);
606*437bfbebSnyanmisaka
607*437bfbebSnyanmisaka /* step 2. updated by lt_cfg */
608*437bfbebSnyanmisaka RefsCnt *lt_cfg = &cpb->lt_cnter[0];
609*437bfbebSnyanmisaka RK_S32 set_to_lt = 0;
610*437bfbebSnyanmisaka RK_S32 i;
611*437bfbebSnyanmisaka
612*437bfbebSnyanmisaka for (i = 0; i < lt_cfg_cnt; i++, lt_cfg++) {
613*437bfbebSnyanmisaka if (lt_cfg->delay_cnt) {
614*437bfbebSnyanmisaka lt_cfg->delay_cnt--;
615*437bfbebSnyanmisaka continue;
616*437bfbebSnyanmisaka }
617*437bfbebSnyanmisaka
618*437bfbebSnyanmisaka if (!set_to_lt) {
619*437bfbebSnyanmisaka if (!lt_cfg->cnt) {
620*437bfbebSnyanmisaka set_lt_cfg_to_frm(&frm, lt_cfg);
621*437bfbebSnyanmisaka set_to_lt = 1;
622*437bfbebSnyanmisaka }
623*437bfbebSnyanmisaka }
624*437bfbebSnyanmisaka
625*437bfbebSnyanmisaka lt_cfg->cnt++;
626*437bfbebSnyanmisaka if (lt_cfg->cnt >= lt_cfg->len) {
627*437bfbebSnyanmisaka if (lt_cfg->len) {
628*437bfbebSnyanmisaka /* when there is loop len loop lt_cfg */
629*437bfbebSnyanmisaka lt_cfg->cnt = 0;
630*437bfbebSnyanmisaka lt_cfg->idx++;
631*437bfbebSnyanmisaka } else {
632*437bfbebSnyanmisaka /* else just set lt_cfg once */
633*437bfbebSnyanmisaka lt_cfg->cnt = 1;
634*437bfbebSnyanmisaka lt_cfg->idx = 1;
635*437bfbebSnyanmisaka }
636*437bfbebSnyanmisaka }
637*437bfbebSnyanmisaka }
638*437bfbebSnyanmisaka
639*437bfbebSnyanmisaka /* step 3. try find ref by the ref_mode and update used cpb size */
640*437bfbebSnyanmisaka EncFrmStatus *ref = get_ref_from_cpb(cpb, &frm);
641*437bfbebSnyanmisaka
642*437bfbebSnyanmisaka if (ref) {
643*437bfbebSnyanmisaka RK_S32 cpb_pos = check_ref_cpb_pos(cpb, ref);
644*437bfbebSnyanmisaka
645*437bfbebSnyanmisaka if (cpb_pos < MAX_CPB_ST_FRM) {
646*437bfbebSnyanmisaka if (cpb_st_used_size < cpb_pos + 1) {
647*437bfbebSnyanmisaka cpb_st_used_size = cpb_pos + 1;
648*437bfbebSnyanmisaka enc_refs_dbg_flow("cpb_st_used_size update to %d\n", cpb_st_used_size);
649*437bfbebSnyanmisaka }
650*437bfbebSnyanmisaka }
651*437bfbebSnyanmisaka }
652*437bfbebSnyanmisaka
653*437bfbebSnyanmisaka /* step 4. store frame according to status */
654*437bfbebSnyanmisaka store_ref_to_cpb(cpb, &frm);
655*437bfbebSnyanmisaka }
656*437bfbebSnyanmisaka }
657*437bfbebSnyanmisaka
658*437bfbebSnyanmisaka cleanup_cpb_refs(cpb);
659*437bfbebSnyanmisaka info->max_st_cnt = cpb_st_used_size ? cpb_st_used_size : 1;
660*437bfbebSnyanmisaka
661*437bfbebSnyanmisaka DONE:
662*437bfbebSnyanmisaka info->dpb_size = info->max_lt_cnt + info->max_st_cnt;
663*437bfbebSnyanmisaka
664*437bfbebSnyanmisaka enc_refs_dbg_size("dryrun success: cpb size %d\n", info->dpb_size);
665*437bfbebSnyanmisaka
666*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
667*437bfbebSnyanmisaka return MPP_OK;
668*437bfbebSnyanmisaka }
669*437bfbebSnyanmisaka
mpp_enc_refs_set_usr_cfg(MppEncRefs refs,MppEncRefFrmUsrCfg * cfg)670*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_set_usr_cfg(MppEncRefs refs, MppEncRefFrmUsrCfg *cfg)
671*437bfbebSnyanmisaka {
672*437bfbebSnyanmisaka if (NULL == refs) {
673*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
674*437bfbebSnyanmisaka return MPP_ERR_VALUE;
675*437bfbebSnyanmisaka }
676*437bfbebSnyanmisaka
677*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
678*437bfbebSnyanmisaka
679*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
680*437bfbebSnyanmisaka memcpy(&p->usr_cfg, cfg, sizeof(p->usr_cfg));
681*437bfbebSnyanmisaka if (cfg->force_flag)
682*437bfbebSnyanmisaka p->changed |= ENC_REFS_USR_CFG_CHANGED;
683*437bfbebSnyanmisaka
684*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
685*437bfbebSnyanmisaka return MPP_OK;
686*437bfbebSnyanmisaka }
687*437bfbebSnyanmisaka
mpp_enc_refs_set_rc_igop(MppEncRefs refs,RK_S32 igop)688*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_set_rc_igop(MppEncRefs refs, RK_S32 igop)
689*437bfbebSnyanmisaka {
690*437bfbebSnyanmisaka if (NULL == refs) {
691*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
692*437bfbebSnyanmisaka return MPP_ERR_VALUE;
693*437bfbebSnyanmisaka }
694*437bfbebSnyanmisaka
695*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
696*437bfbebSnyanmisaka
697*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
698*437bfbebSnyanmisaka
699*437bfbebSnyanmisaka if (p->igop != igop) {
700*437bfbebSnyanmisaka p->igop = igop;
701*437bfbebSnyanmisaka p->changed |= ENC_REFS_IGOP_CHANGED;
702*437bfbebSnyanmisaka }
703*437bfbebSnyanmisaka
704*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
705*437bfbebSnyanmisaka return MPP_OK;
706*437bfbebSnyanmisaka }
707*437bfbebSnyanmisaka
mpp_enc_refs_set_refresh_length(MppEncRefs refs,RK_S32 len)708*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_set_refresh_length(MppEncRefs refs, RK_S32 len)
709*437bfbebSnyanmisaka {
710*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
711*437bfbebSnyanmisaka if (NULL == refs) {
712*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
713*437bfbebSnyanmisaka return MPP_ERR_VALUE;
714*437bfbebSnyanmisaka }
715*437bfbebSnyanmisaka
716*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
717*437bfbebSnyanmisaka
718*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
719*437bfbebSnyanmisaka
720*437bfbebSnyanmisaka if (len < p->igop) {
721*437bfbebSnyanmisaka p->refresh_length = len;
722*437bfbebSnyanmisaka } else {
723*437bfbebSnyanmisaka p->refresh_length = p->igop;
724*437bfbebSnyanmisaka ret = MPP_ERR_VALUE;
725*437bfbebSnyanmisaka goto RET;
726*437bfbebSnyanmisaka }
727*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
728*437bfbebSnyanmisaka RET:
729*437bfbebSnyanmisaka return ret;
730*437bfbebSnyanmisaka }
731*437bfbebSnyanmisaka
mpp_enc_refs_update_hdr(MppEncRefs refs)732*437bfbebSnyanmisaka RK_S32 mpp_enc_refs_update_hdr(MppEncRefs refs)
733*437bfbebSnyanmisaka {
734*437bfbebSnyanmisaka if (NULL == refs) {
735*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
736*437bfbebSnyanmisaka return 0;
737*437bfbebSnyanmisaka }
738*437bfbebSnyanmisaka
739*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
740*437bfbebSnyanmisaka
741*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
742*437bfbebSnyanmisaka RK_S32 hdr_need_update = p->hdr_need_update;
743*437bfbebSnyanmisaka
744*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
745*437bfbebSnyanmisaka return hdr_need_update;
746*437bfbebSnyanmisaka }
747*437bfbebSnyanmisaka
mpp_enc_refs_get_cpb_info(MppEncRefs refs,MppEncCpbInfo * info)748*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_get_cpb_info(MppEncRefs refs, MppEncCpbInfo *info)
749*437bfbebSnyanmisaka {
750*437bfbebSnyanmisaka if (NULL == refs || NULL == info) {
751*437bfbebSnyanmisaka mpp_err_f("invalid input refs %p info %p\n", refs, info);
752*437bfbebSnyanmisaka return MPP_ERR_VALUE;
753*437bfbebSnyanmisaka }
754*437bfbebSnyanmisaka
755*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
756*437bfbebSnyanmisaka
757*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
758*437bfbebSnyanmisaka memcpy(info, &p->cpb.info, sizeof(*info));
759*437bfbebSnyanmisaka
760*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
761*437bfbebSnyanmisaka return MPP_OK;
762*437bfbebSnyanmisaka }
763*437bfbebSnyanmisaka
get_cpb_st_cfg_pos(EncVirtualCpb * cpb,MppEncRefCfgImpl * cfg)764*437bfbebSnyanmisaka static RK_S32 get_cpb_st_cfg_pos(EncVirtualCpb *cpb, MppEncRefCfgImpl *cfg)
765*437bfbebSnyanmisaka {
766*437bfbebSnyanmisaka RK_S32 st_cfg_pos = cpb->st_cfg_pos;
767*437bfbebSnyanmisaka RK_S32 st_cfg_cnt = cfg->st_cfg_cnt;
768*437bfbebSnyanmisaka
769*437bfbebSnyanmisaka /* NOTE: second loop will start from 1 */
770*437bfbebSnyanmisaka if (st_cfg_pos >= st_cfg_cnt)
771*437bfbebSnyanmisaka st_cfg_pos = (st_cfg_cnt > 1) ? (1) : (0);
772*437bfbebSnyanmisaka
773*437bfbebSnyanmisaka return st_cfg_pos;
774*437bfbebSnyanmisaka }
775*437bfbebSnyanmisaka
mpp_enc_refs_get_cpb(MppEncRefs refs,EncCpbStatus * status)776*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_get_cpb(MppEncRefs refs, EncCpbStatus *status)
777*437bfbebSnyanmisaka {
778*437bfbebSnyanmisaka if (NULL == refs) {
779*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
780*437bfbebSnyanmisaka return MPP_ERR_VALUE;
781*437bfbebSnyanmisaka }
782*437bfbebSnyanmisaka
783*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
784*437bfbebSnyanmisaka
785*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
786*437bfbebSnyanmisaka MppEncRefCfgImpl *cfg = p->ref_cfg;
787*437bfbebSnyanmisaka EncVirtualCpb *cpb = &p->cpb;
788*437bfbebSnyanmisaka MppEncRefStFrmCfg *st_cfg = NULL;
789*437bfbebSnyanmisaka MppEncRefFrmUsrCfg *usr_cfg = &p->usr_cfg;
790*437bfbebSnyanmisaka EncFrmStatus *frm = &status->curr;
791*437bfbebSnyanmisaka EncFrmStatus *ref = &status->refr;
792*437bfbebSnyanmisaka RefsCnt *lt_cfg = cpb->lt_cnter;
793*437bfbebSnyanmisaka RK_S32 set_to_lt = 0;
794*437bfbebSnyanmisaka RK_S32 cleanup_cpb = 0;
795*437bfbebSnyanmisaka RK_S32 prev_frm_is_pass1 = frm->save_pass1;
796*437bfbebSnyanmisaka RK_S32 i;
797*437bfbebSnyanmisaka
798*437bfbebSnyanmisaka /* step 1. check igop from cfg_set and force idr for usr_cfg */
799*437bfbebSnyanmisaka if (p->changed & ENC_REFS_IGOP_CHANGED)
800*437bfbebSnyanmisaka cleanup_cpb = 1;
801*437bfbebSnyanmisaka
802*437bfbebSnyanmisaka if (p->igop && (cpb->seq_idx >= p->igop)) {
803*437bfbebSnyanmisaka if (p->refresh_length) {
804*437bfbebSnyanmisaka p->cpb.seq_cnt = cpb->seq_idx / p->igop + 1;
805*437bfbebSnyanmisaka } else
806*437bfbebSnyanmisaka cleanup_cpb = 1;
807*437bfbebSnyanmisaka }
808*437bfbebSnyanmisaka
809*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_IDR) {
810*437bfbebSnyanmisaka usr_cfg->force_flag &= (~ENC_FORCE_IDR);
811*437bfbebSnyanmisaka cleanup_cpb = 1;
812*437bfbebSnyanmisaka p->cpb.seq_cnt = 0;
813*437bfbebSnyanmisaka }
814*437bfbebSnyanmisaka
815*437bfbebSnyanmisaka if (cleanup_cpb) {
816*437bfbebSnyanmisaka /* update seq_idx for igop loop and force idr */
817*437bfbebSnyanmisaka cleanup_cpb_refs(cpb);
818*437bfbebSnyanmisaka } else if (p->changed & ENC_REFS_REF_CFG_CHANGED) {
819*437bfbebSnyanmisaka cpb->st_cfg_pos = 0;
820*437bfbebSnyanmisaka cpb->st_cfg_repeat_pos = 0;
821*437bfbebSnyanmisaka }
822*437bfbebSnyanmisaka
823*437bfbebSnyanmisaka p->changed = 0;
824*437bfbebSnyanmisaka
825*437bfbebSnyanmisaka cpb->frm_idx++;
826*437bfbebSnyanmisaka cpb->st_cfg_pos = get_cpb_st_cfg_pos(cpb, cfg);
827*437bfbebSnyanmisaka st_cfg = &cfg->st_cfg[cpb->st_cfg_pos];
828*437bfbebSnyanmisaka /* step 2. updated by st_cfg */
829*437bfbebSnyanmisaka set_st_cfg_to_frm(frm, cpb->seq_idx++, st_cfg);
830*437bfbebSnyanmisaka set_frm_refresh_flag(frm, p);
831*437bfbebSnyanmisaka
832*437bfbebSnyanmisaka lt_cfg = p->cpb.lt_cnter;
833*437bfbebSnyanmisaka
834*437bfbebSnyanmisaka /* step 3. updated by lt_cfg */
835*437bfbebSnyanmisaka for (i = 0; i < cfg->lt_cfg_cnt; i++, lt_cfg++) {
836*437bfbebSnyanmisaka if (lt_cfg->delay_cnt) {
837*437bfbebSnyanmisaka lt_cfg->delay_cnt--;
838*437bfbebSnyanmisaka continue;
839*437bfbebSnyanmisaka }
840*437bfbebSnyanmisaka
841*437bfbebSnyanmisaka if (!set_to_lt) {
842*437bfbebSnyanmisaka if (!lt_cfg->cnt) {
843*437bfbebSnyanmisaka set_lt_cfg_to_frm(frm, lt_cfg);
844*437bfbebSnyanmisaka set_to_lt = 1;
845*437bfbebSnyanmisaka }
846*437bfbebSnyanmisaka }
847*437bfbebSnyanmisaka
848*437bfbebSnyanmisaka lt_cfg->cnt++;
849*437bfbebSnyanmisaka if (lt_cfg->cnt >= lt_cfg->len) {
850*437bfbebSnyanmisaka if (lt_cfg->len) {
851*437bfbebSnyanmisaka /* when there is loop len loop lt_cfg */
852*437bfbebSnyanmisaka lt_cfg->cnt = 0;
853*437bfbebSnyanmisaka lt_cfg->idx++;
854*437bfbebSnyanmisaka } else {
855*437bfbebSnyanmisaka /* else just set lt_cfg once */
856*437bfbebSnyanmisaka lt_cfg->cnt = 1;
857*437bfbebSnyanmisaka lt_cfg->idx = 1;
858*437bfbebSnyanmisaka }
859*437bfbebSnyanmisaka }
860*437bfbebSnyanmisaka }
861*437bfbebSnyanmisaka
862*437bfbebSnyanmisaka /* step 4. process force flags and force ref_mode */
863*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_LT_REF_IDX) {
864*437bfbebSnyanmisaka frm->is_non_ref = 0;
865*437bfbebSnyanmisaka frm->is_lt_ref = 1;
866*437bfbebSnyanmisaka frm->lt_idx = usr_cfg->force_lt_idx;
867*437bfbebSnyanmisaka if (frm->is_idr && frm->lt_idx) {
868*437bfbebSnyanmisaka frm->lt_idx = 0;
869*437bfbebSnyanmisaka mpp_err_f("can not set IDR to ltr with non-zero index\n");
870*437bfbebSnyanmisaka }
871*437bfbebSnyanmisaka /* lt_ref will be forced to tid 0 */
872*437bfbebSnyanmisaka frm->temporal_id = 0;
873*437bfbebSnyanmisaka
874*437bfbebSnyanmisaka /* reset st_cfg to next loop */
875*437bfbebSnyanmisaka cpb->st_cfg_repeat_pos = 0;
876*437bfbebSnyanmisaka cpb->st_cfg_pos = 0;
877*437bfbebSnyanmisaka usr_cfg->force_flag &= ~ENC_FORCE_LT_REF_IDX;
878*437bfbebSnyanmisaka }
879*437bfbebSnyanmisaka
880*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_TEMPORAL_ID) {
881*437bfbebSnyanmisaka if (usr_cfg->force_temporal_id >= cfg->max_tlayers ||
882*437bfbebSnyanmisaka frm->is_idr || frm->is_lt_ref)
883*437bfbebSnyanmisaka mpp_err_f("Invalid temporal_id %d, frm is %s\n", usr_cfg->force_temporal_id,
884*437bfbebSnyanmisaka frm->is_idr ? "IDR" : (frm->is_lt_ref ? "LTR" : "st"));
885*437bfbebSnyanmisaka else
886*437bfbebSnyanmisaka frm->temporal_id = usr_cfg->force_temporal_id;
887*437bfbebSnyanmisaka
888*437bfbebSnyanmisaka usr_cfg->force_flag &= ~ENC_FORCE_TEMPORAL_ID;
889*437bfbebSnyanmisaka }
890*437bfbebSnyanmisaka
891*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_REF_MODE) {
892*437bfbebSnyanmisaka frm->ref_mode = usr_cfg->force_ref_mode;
893*437bfbebSnyanmisaka frm->ref_arg = usr_cfg->force_ref_arg;
894*437bfbebSnyanmisaka
895*437bfbebSnyanmisaka usr_cfg->force_flag &= ~ENC_FORCE_REF_MODE;
896*437bfbebSnyanmisaka }
897*437bfbebSnyanmisaka
898*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_PSKIP_NON_REF) {
899*437bfbebSnyanmisaka frm->is_non_ref = 1;
900*437bfbebSnyanmisaka
901*437bfbebSnyanmisaka usr_cfg->force_flag &= ~ENC_FORCE_PSKIP_NON_REF;
902*437bfbebSnyanmisaka }
903*437bfbebSnyanmisaka
904*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_PSKIP_IS_REF) {
905*437bfbebSnyanmisaka frm->force_pskip_is_ref = 1;
906*437bfbebSnyanmisaka
907*437bfbebSnyanmisaka usr_cfg->force_flag &= ~ENC_FORCE_PSKIP_IS_REF;
908*437bfbebSnyanmisaka }
909*437bfbebSnyanmisaka
910*437bfbebSnyanmisaka frm->non_recn = frm->is_non_ref || (p->igop == 1);
911*437bfbebSnyanmisaka
912*437bfbebSnyanmisaka /* update st_cfg for st_cfg loop */
913*437bfbebSnyanmisaka cpb->st_cfg_repeat_pos++;
914*437bfbebSnyanmisaka if (cpb->st_cfg_repeat_pos > st_cfg->repeat) {
915*437bfbebSnyanmisaka cpb->st_cfg_repeat_pos = 0;
916*437bfbebSnyanmisaka cpb->st_cfg_pos++;
917*437bfbebSnyanmisaka }
918*437bfbebSnyanmisaka
919*437bfbebSnyanmisaka /* step 4. try find ref by the ref_mode */
920*437bfbebSnyanmisaka EncFrmStatus *ref_found = get_ref_from_cpb(&p->cpb, frm);
921*437bfbebSnyanmisaka if (ref_found) {
922*437bfbebSnyanmisaka RK_S32 cpb_idx = check_ref_cpb_pos(&p->cpb, ref_found);
923*437bfbebSnyanmisaka
924*437bfbebSnyanmisaka mpp_assert(cpb_idx >= 0);
925*437bfbebSnyanmisaka cpb->list0[0].val = ref->val;
926*437bfbebSnyanmisaka ref->val = ref_found->val;
927*437bfbebSnyanmisaka } else
928*437bfbebSnyanmisaka ref->val = 0;
929*437bfbebSnyanmisaka
930*437bfbebSnyanmisaka /* step 5. check use previous pass one frame as input */
931*437bfbebSnyanmisaka if (prev_frm_is_pass1)
932*437bfbebSnyanmisaka frm->use_pass1 = 1;
933*437bfbebSnyanmisaka
934*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM) {
935*437bfbebSnyanmisaka mpp_log_f("frm status:\n");
936*437bfbebSnyanmisaka dump_frm(frm);
937*437bfbebSnyanmisaka mpp_log_f("ref status:\n");
938*437bfbebSnyanmisaka dump_frm(ref);
939*437bfbebSnyanmisaka }
940*437bfbebSnyanmisaka
941*437bfbebSnyanmisaka /* step 5. generate cpb init */
942*437bfbebSnyanmisaka memset(status->init, 0, sizeof(status->init));
943*437bfbebSnyanmisaka save_cpb_status(&p->cpb, status->init);
944*437bfbebSnyanmisaka // TODO: cpb_init must be the same to cpb_final
945*437bfbebSnyanmisaka
946*437bfbebSnyanmisaka /* step 6. store frame according to status */
947*437bfbebSnyanmisaka store_ref_to_cpb(&p->cpb, frm);
948*437bfbebSnyanmisaka
949*437bfbebSnyanmisaka /* step 7. generate cpb final */
950*437bfbebSnyanmisaka memset(status->final, 0, sizeof(status->final));
951*437bfbebSnyanmisaka save_cpb_status(&p->cpb, status->final);
952*437bfbebSnyanmisaka
953*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
954*437bfbebSnyanmisaka return MPP_OK;
955*437bfbebSnyanmisaka }
956*437bfbebSnyanmisaka
mpp_enc_refs_next_frm_is_intra(MppEncRefs refs)957*437bfbebSnyanmisaka RK_S32 mpp_enc_refs_next_frm_is_intra(MppEncRefs refs)
958*437bfbebSnyanmisaka {
959*437bfbebSnyanmisaka if (NULL == refs) {
960*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
961*437bfbebSnyanmisaka return MPP_ERR_VALUE;
962*437bfbebSnyanmisaka }
963*437bfbebSnyanmisaka
964*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
965*437bfbebSnyanmisaka
966*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
967*437bfbebSnyanmisaka EncVirtualCpb *cpb = &p->cpb;
968*437bfbebSnyanmisaka MppEncRefFrmUsrCfg *usr_cfg = &p->usr_cfg;
969*437bfbebSnyanmisaka RK_S32 is_intra = 0;
970*437bfbebSnyanmisaka
971*437bfbebSnyanmisaka if (p->changed & ENC_REFS_IGOP_CHANGED)
972*437bfbebSnyanmisaka is_intra = 1;
973*437bfbebSnyanmisaka
974*437bfbebSnyanmisaka if (p->igop && cpb->seq_idx >= p->igop)
975*437bfbebSnyanmisaka is_intra = 1;
976*437bfbebSnyanmisaka
977*437bfbebSnyanmisaka if (usr_cfg->force_flag & ENC_FORCE_IDR)
978*437bfbebSnyanmisaka is_intra = 1;
979*437bfbebSnyanmisaka
980*437bfbebSnyanmisaka if (!cpb->frm_idx)
981*437bfbebSnyanmisaka is_intra = 0;
982*437bfbebSnyanmisaka
983*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
984*437bfbebSnyanmisaka
985*437bfbebSnyanmisaka return is_intra;
986*437bfbebSnyanmisaka }
987*437bfbebSnyanmisaka
mpp_enc_refs_get_cpb_pass1(MppEncRefs refs,EncCpbStatus * status)988*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_get_cpb_pass1(MppEncRefs refs, EncCpbStatus *status)
989*437bfbebSnyanmisaka {
990*437bfbebSnyanmisaka if (NULL == refs) {
991*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
992*437bfbebSnyanmisaka return MPP_ERR_VALUE;
993*437bfbebSnyanmisaka }
994*437bfbebSnyanmisaka
995*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
996*437bfbebSnyanmisaka
997*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
998*437bfbebSnyanmisaka EncVirtualCpb *cpb = &p->cpb;
999*437bfbebSnyanmisaka EncFrmStatus *frm = &status->curr;
1000*437bfbebSnyanmisaka EncFrmStatus *ref = &status->refr;
1001*437bfbebSnyanmisaka
1002*437bfbebSnyanmisaka frm->valid = 1;
1003*437bfbebSnyanmisaka frm->save_pass1 = 1;
1004*437bfbebSnyanmisaka frm->is_non_ref = 1;
1005*437bfbebSnyanmisaka frm->is_lt_ref = 0;
1006*437bfbebSnyanmisaka frm->temporal_id = 0;
1007*437bfbebSnyanmisaka frm->ref_mode = REF_TO_PREV_REF_FRM;
1008*437bfbebSnyanmisaka frm->ref_arg = 0;
1009*437bfbebSnyanmisaka frm->non_recn = 0;
1010*437bfbebSnyanmisaka
1011*437bfbebSnyanmisaka /* step 4. try find ref by the ref_mode */
1012*437bfbebSnyanmisaka EncFrmStatus *ref_found = get_ref_from_cpb(cpb, frm);
1013*437bfbebSnyanmisaka if (ref_found) {
1014*437bfbebSnyanmisaka RK_S32 cpb_idx = check_ref_cpb_pos(cpb, ref_found);
1015*437bfbebSnyanmisaka
1016*437bfbebSnyanmisaka mpp_assert(cpb_idx >= 0);
1017*437bfbebSnyanmisaka cpb->list0[0].val = ref->val;
1018*437bfbebSnyanmisaka ref->val = ref_found->val;
1019*437bfbebSnyanmisaka } else
1020*437bfbebSnyanmisaka ref->val = 0;
1021*437bfbebSnyanmisaka
1022*437bfbebSnyanmisaka if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM) {
1023*437bfbebSnyanmisaka mpp_log_f("frm status:\n");
1024*437bfbebSnyanmisaka dump_frm(frm);
1025*437bfbebSnyanmisaka mpp_log_f("ref status:\n");
1026*437bfbebSnyanmisaka dump_frm(ref);
1027*437bfbebSnyanmisaka }
1028*437bfbebSnyanmisaka
1029*437bfbebSnyanmisaka /* step 5. generate cpb init */
1030*437bfbebSnyanmisaka memset(status->init, 0, sizeof(status->init));
1031*437bfbebSnyanmisaka save_cpb_status(cpb, status->init);
1032*437bfbebSnyanmisaka // TODO: cpb_init must be the same to cpb_final
1033*437bfbebSnyanmisaka
1034*437bfbebSnyanmisaka /* step 6. store frame according to status */
1035*437bfbebSnyanmisaka store_ref_to_cpb(cpb, frm);
1036*437bfbebSnyanmisaka
1037*437bfbebSnyanmisaka /* step 7. generate cpb final */
1038*437bfbebSnyanmisaka memset(status->final, 0, sizeof(status->final));
1039*437bfbebSnyanmisaka save_cpb_status(cpb, status->final);
1040*437bfbebSnyanmisaka
1041*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
1042*437bfbebSnyanmisaka return MPP_OK;
1043*437bfbebSnyanmisaka }
mpp_enc_refs_stash(MppEncRefs refs)1044*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_stash(MppEncRefs refs)
1045*437bfbebSnyanmisaka {
1046*437bfbebSnyanmisaka if (NULL == refs) {
1047*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
1048*437bfbebSnyanmisaka return MPP_ERR_VALUE;
1049*437bfbebSnyanmisaka }
1050*437bfbebSnyanmisaka
1051*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
1052*437bfbebSnyanmisaka
1053*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
1054*437bfbebSnyanmisaka memcpy(&p->cpb_stash, &p->cpb, sizeof(p->cpb_stash));
1055*437bfbebSnyanmisaka
1056*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
1057*437bfbebSnyanmisaka return MPP_OK;
1058*437bfbebSnyanmisaka }
1059*437bfbebSnyanmisaka
mpp_enc_refs_rollback(MppEncRefs refs)1060*437bfbebSnyanmisaka MPP_RET mpp_enc_refs_rollback(MppEncRefs refs)
1061*437bfbebSnyanmisaka {
1062*437bfbebSnyanmisaka if (NULL == refs) {
1063*437bfbebSnyanmisaka mpp_err_f("invalid NULL input refs\n");
1064*437bfbebSnyanmisaka return MPP_ERR_VALUE;
1065*437bfbebSnyanmisaka }
1066*437bfbebSnyanmisaka
1067*437bfbebSnyanmisaka enc_refs_dbg_func("enter %p\n", refs);
1068*437bfbebSnyanmisaka
1069*437bfbebSnyanmisaka MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
1070*437bfbebSnyanmisaka memcpy(&p->cpb, &p->cpb_stash, sizeof(p->cpb));
1071*437bfbebSnyanmisaka
1072*437bfbebSnyanmisaka enc_refs_dbg_func("leave %p\n", refs);
1073*437bfbebSnyanmisaka return MPP_OK;
1074*437bfbebSnyanmisaka }
1075