xref: /rockchip-linux_mpp/mpp/base/mpp_enc_refs.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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