xref: /rockchip-linux_mpp/mpp/codec/enc/h264/h264e_dpb.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG  "h264e_dpb"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_mem.h"
22*437bfbebSnyanmisaka #include "mpp_common.h"
23*437bfbebSnyanmisaka 
24*437bfbebSnyanmisaka #include "h264e_debug.h"
25*437bfbebSnyanmisaka #include "h264e_dpb.h"
26*437bfbebSnyanmisaka #include "h264e_slice.h"
27*437bfbebSnyanmisaka 
h264e_dpb_dump_usage(H264eDpb * dpb,const char * fmt)28*437bfbebSnyanmisaka void h264e_dpb_dump_usage(H264eDpb *dpb, const char *fmt)
29*437bfbebSnyanmisaka {
30*437bfbebSnyanmisaka     RK_S32 i = 0;
31*437bfbebSnyanmisaka     char buf[256];
32*437bfbebSnyanmisaka     RK_S32 pos = 0;
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka     pos += snprintf(buf, sizeof(buf) - 1, "total %2d ", dpb->total_cnt);
35*437bfbebSnyanmisaka 
36*437bfbebSnyanmisaka     for (i = 0; i < dpb->total_cnt; i++) {
37*437bfbebSnyanmisaka         H264eDpbFrm *frm = &dpb->frames[i];
38*437bfbebSnyanmisaka 
39*437bfbebSnyanmisaka         pos += snprintf(buf + pos, sizeof(buf) - 1 - pos, "%04x ", frm->on_used);
40*437bfbebSnyanmisaka     }
41*437bfbebSnyanmisaka     mpp_log("%s %s", fmt, buf);
42*437bfbebSnyanmisaka }
43*437bfbebSnyanmisaka 
h264e_dpb_dump_frm(H264eDpb * dpb,const char * caller,RK_S32 line)44*437bfbebSnyanmisaka void h264e_dpb_dump_frm(H264eDpb *dpb, const char *caller, RK_S32 line)
45*437bfbebSnyanmisaka {
46*437bfbebSnyanmisaka     RK_S32 i = 0;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     mpp_log_f("dump dpb frame info in %s line %d\n", caller, line);
49*437bfbebSnyanmisaka 
50*437bfbebSnyanmisaka     mpp_log_f("dpb %p total count %d size %d\n", dpb, dpb->total_cnt, dpb->dpb_size);
51*437bfbebSnyanmisaka     mpp_log_f("dpb %5s %5s %5s %5s %5s %5s %5s %5s %5s\n",
52*437bfbebSnyanmisaka               "slot", "use", "seq", "type", "tid", "ref", "idx", "mode", "arg");
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     for (i = 0; i < dpb->total_cnt; i++) {
55*437bfbebSnyanmisaka         H264eDpbFrm *frm = &dpb->frames[i];
56*437bfbebSnyanmisaka         EncFrmStatus *status = &frm->status;
57*437bfbebSnyanmisaka 
58*437bfbebSnyanmisaka         mpp_log_f("frm %5d %5d %5d %5s %5d %5s %5d %5x %5d\n",
59*437bfbebSnyanmisaka                   i, frm->on_used, status->seq_idx,
60*437bfbebSnyanmisaka                   (status->is_intra) ? (status->is_idr ? "I" : "i" ) :
61*437bfbebSnyanmisaka                       status->is_non_ref ? "p" : "P",
62*437bfbebSnyanmisaka                       status->temporal_id,
63*437bfbebSnyanmisaka                       status->is_non_ref ? "non" : status->is_lt_ref ? "lt" : "st",
64*437bfbebSnyanmisaka                       status->lt_idx,
65*437bfbebSnyanmisaka                       status->ref_mode,
66*437bfbebSnyanmisaka                       status->ref_arg);
67*437bfbebSnyanmisaka     }
68*437bfbebSnyanmisaka }
69*437bfbebSnyanmisaka 
h264e_dpb_dump_listX(H264eDpbFrm ** list,RK_S32 count)70*437bfbebSnyanmisaka void h264e_dpb_dump_listX(H264eDpbFrm **list, RK_S32 count)
71*437bfbebSnyanmisaka {
72*437bfbebSnyanmisaka     RK_S32 i;
73*437bfbebSnyanmisaka 
74*437bfbebSnyanmisaka     for (i = 0; i < count; i++) {
75*437bfbebSnyanmisaka         H264eDpbFrm *frm = list[i];
76*437bfbebSnyanmisaka         EncFrmStatus *status = &frm->status;
77*437bfbebSnyanmisaka 
78*437bfbebSnyanmisaka         mpp_log_f("frm  %2d   %d  %-3d %s    %-3d %-3s %-3d %-4x %-3d\n",
79*437bfbebSnyanmisaka                   i, frm->on_used, status->seq_idx,
80*437bfbebSnyanmisaka                   (status->is_intra) ? (status->is_idr ? "I" : "i" ) :
81*437bfbebSnyanmisaka                       status->is_non_ref ? "p" : "P",
82*437bfbebSnyanmisaka                       status->temporal_id,
83*437bfbebSnyanmisaka                       status->is_non_ref ? "non" : status->is_lt_ref ? "lt" : "st",
84*437bfbebSnyanmisaka                       status->lt_idx,
85*437bfbebSnyanmisaka                       status->ref_mode,
86*437bfbebSnyanmisaka                       status->ref_arg);
87*437bfbebSnyanmisaka     }
88*437bfbebSnyanmisaka }
89*437bfbebSnyanmisaka 
h264e_dpb_dump_list(H264eDpb * dpb)90*437bfbebSnyanmisaka void h264e_dpb_dump_list(H264eDpb *dpb)
91*437bfbebSnyanmisaka {
92*437bfbebSnyanmisaka     mpp_log_f("dump dpb list info\n");
93*437bfbebSnyanmisaka 
94*437bfbebSnyanmisaka     mpp_log_f("dpb  size %d used %d st %d lt %d\n",
95*437bfbebSnyanmisaka               dpb->dpb_size, dpb->used_size, dpb->st_size, dpb->lt_size);
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     if (dpb->st_size + dpb->lt_size) {
98*437bfbebSnyanmisaka         mpp_log_f("list slot use seq type tid ref idx mode arg\n", dpb, dpb->total_cnt);
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka         h264e_dpb_dump_listX(dpb->list, dpb->st_size + dpb->lt_size);
101*437bfbebSnyanmisaka     }
102*437bfbebSnyanmisaka }
103*437bfbebSnyanmisaka 
h264e_dpb_init(H264eDpb * dpb,H264eReorderInfo * reorder,H264eMarkingInfo * marking)104*437bfbebSnyanmisaka MPP_RET h264e_dpb_init(H264eDpb *dpb, H264eReorderInfo *reorder, H264eMarkingInfo *marking)
105*437bfbebSnyanmisaka {
106*437bfbebSnyanmisaka     RK_S32 i;
107*437bfbebSnyanmisaka 
108*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p\n", dpb);
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka     memset(dpb, 0, sizeof(*dpb));
111*437bfbebSnyanmisaka 
112*437bfbebSnyanmisaka     dpb->reorder    = reorder;
113*437bfbebSnyanmisaka     dpb->marking    = marking;
114*437bfbebSnyanmisaka     for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(dpb->frames); i++)
115*437bfbebSnyanmisaka         dpb->frames[i].slot_idx = i;
116*437bfbebSnyanmisaka 
117*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
118*437bfbebSnyanmisaka 
119*437bfbebSnyanmisaka     return MPP_OK;
120*437bfbebSnyanmisaka }
121*437bfbebSnyanmisaka 
h264e_dpb_setup(H264eDpb * dpb,MppEncCfgSet * cfg,H264eSps * sps)122*437bfbebSnyanmisaka MPP_RET h264e_dpb_setup(H264eDpb *dpb, MppEncCfgSet* cfg, H264eSps *sps)
123*437bfbebSnyanmisaka {
124*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
125*437bfbebSnyanmisaka     MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(cfg->ref_cfg);
126*437bfbebSnyanmisaka 
127*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p\n", dpb);
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     RK_S32 ref_frm_num = sps->num_ref_frames;
130*437bfbebSnyanmisaka     RK_S32 log2_max_frm_num = sps->log2_max_frame_num_minus4 + 4;
131*437bfbebSnyanmisaka     RK_S32 log2_max_poc_lsb = sps->log2_max_poc_lsb_minus4 + 4;
132*437bfbebSnyanmisaka 
133*437bfbebSnyanmisaka     /* NOTE: new configure needs to clear dpb first */
134*437bfbebSnyanmisaka     h264e_dpb_init(dpb, dpb->reorder, dpb->marking);
135*437bfbebSnyanmisaka 
136*437bfbebSnyanmisaka     memcpy(&dpb->info, info, sizeof(dpb->info));
137*437bfbebSnyanmisaka     dpb->dpb_size = info->dpb_size;
138*437bfbebSnyanmisaka     dpb->total_cnt = info->dpb_size + 1;
139*437bfbebSnyanmisaka     dpb->max_frm_num = 1 << log2_max_frm_num;
140*437bfbebSnyanmisaka     dpb->max_poc_lsb = (1 << log2_max_poc_lsb);
141*437bfbebSnyanmisaka     dpb->poc_type = sps->pic_order_cnt_type;
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka     if (cfg->hw.extra_buf)
144*437bfbebSnyanmisaka         dpb->total_cnt++;
145*437bfbebSnyanmisaka 
146*437bfbebSnyanmisaka     h264e_dbg_dpb("max  ref frm num %d total slot %d\n",
147*437bfbebSnyanmisaka                   ref_frm_num, dpb->total_cnt);
148*437bfbebSnyanmisaka     h264e_dbg_dpb("log2 max frm num %d -> %d\n",
149*437bfbebSnyanmisaka                   log2_max_frm_num, dpb->max_frm_num);
150*437bfbebSnyanmisaka     h264e_dbg_dpb("log2 max poc lsb %d -> %d\n",
151*437bfbebSnyanmisaka                   log2_max_poc_lsb, dpb->max_poc_lsb);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka     return ret;
156*437bfbebSnyanmisaka }
157*437bfbebSnyanmisaka 
find_cpb_frame(H264eDpb * dpb,EncFrmStatus * frm)158*437bfbebSnyanmisaka H264eDpbFrm *find_cpb_frame(H264eDpb *dpb, EncFrmStatus *frm)
159*437bfbebSnyanmisaka {
160*437bfbebSnyanmisaka     H264eDpbFrm *frms = dpb->frames;
161*437bfbebSnyanmisaka     RK_S32 seq_idx = frm->seq_idx;
162*437bfbebSnyanmisaka     RK_S32 cnt = dpb->total_cnt;
163*437bfbebSnyanmisaka     RK_S32 i;
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     if (!frm->valid)
166*437bfbebSnyanmisaka         return NULL;
167*437bfbebSnyanmisaka 
168*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d start finding slot\n", frm->seq_idx);
169*437bfbebSnyanmisaka 
170*437bfbebSnyanmisaka     for (i = 0; i < cnt; i++) {
171*437bfbebSnyanmisaka         EncFrmStatus *p = &frms[i].status;
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka         if (p->valid && p->seq_idx == seq_idx) {
174*437bfbebSnyanmisaka             h264e_dbg_dpb("frm %d match slot %d valid %d\n",
175*437bfbebSnyanmisaka                           p->seq_idx, i, p->valid);
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka             mpp_assert(p->is_non_ref == frm->is_non_ref);
178*437bfbebSnyanmisaka             mpp_assert(p->is_lt_ref == frm->is_lt_ref);
179*437bfbebSnyanmisaka             mpp_assert(p->lt_idx == frm->lt_idx);
180*437bfbebSnyanmisaka             mpp_assert(p->temporal_id == frm->temporal_id);
181*437bfbebSnyanmisaka             return &frms[i];
182*437bfbebSnyanmisaka         }
183*437bfbebSnyanmisaka     }
184*437bfbebSnyanmisaka 
185*437bfbebSnyanmisaka     mpp_err_f("can not find match frm %d\n", seq_idx);
186*437bfbebSnyanmisaka     h264e_dpb_dump_frms(dpb);
187*437bfbebSnyanmisaka     abort();
188*437bfbebSnyanmisaka 
189*437bfbebSnyanmisaka     return NULL;
190*437bfbebSnyanmisaka }
191*437bfbebSnyanmisaka 
192*437bfbebSnyanmisaka 
cmp_st_list(const void * p0,const void * p1)193*437bfbebSnyanmisaka static int cmp_st_list(const void *p0, const void *p1)
194*437bfbebSnyanmisaka {
195*437bfbebSnyanmisaka     H264eDpbFrm *frm0 = *(H264eDpbFrm **)p0;
196*437bfbebSnyanmisaka     H264eDpbFrm *frm1 = *(H264eDpbFrm **)p1;
197*437bfbebSnyanmisaka 
198*437bfbebSnyanmisaka     if (frm0->frame_num == frm1->frame_num)
199*437bfbebSnyanmisaka         return 0;
200*437bfbebSnyanmisaka     if (frm0->frame_num < frm1->frame_num)
201*437bfbebSnyanmisaka         return 1;
202*437bfbebSnyanmisaka     else
203*437bfbebSnyanmisaka         return -1;
204*437bfbebSnyanmisaka }
205*437bfbebSnyanmisaka 
cmp_lt_list(const void * p0,const void * p1)206*437bfbebSnyanmisaka static int cmp_lt_list(const void *p0, const void *p1)
207*437bfbebSnyanmisaka {
208*437bfbebSnyanmisaka     H264eDpbFrm *frm0 = *(H264eDpbFrm **)p0;
209*437bfbebSnyanmisaka     H264eDpbFrm *frm1 = *(H264eDpbFrm **)p1;
210*437bfbebSnyanmisaka 
211*437bfbebSnyanmisaka     if (frm0->lt_idx == frm1->lt_idx)
212*437bfbebSnyanmisaka         return 0;
213*437bfbebSnyanmisaka     if (frm0->lt_idx > frm1->lt_idx)
214*437bfbebSnyanmisaka         return 1;
215*437bfbebSnyanmisaka     else
216*437bfbebSnyanmisaka         return -1;
217*437bfbebSnyanmisaka }
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka /*
220*437bfbebSnyanmisaka  * Build list function
221*437bfbebSnyanmisaka  *
222*437bfbebSnyanmisaka  * This function should build the default list for current frame.
223*437bfbebSnyanmisaka  * Then check the reference frame is the default one or not.
224*437bfbebSnyanmisaka  * Reorder command is need if the reference frame is not match.
225*437bfbebSnyanmisaka  */
h264e_dpb_build_list(H264eDpb * dpb,EncCpbStatus * cpb)226*437bfbebSnyanmisaka void h264e_dpb_build_list(H264eDpb *dpb, EncCpbStatus *cpb)
227*437bfbebSnyanmisaka {
228*437bfbebSnyanmisaka     RK_S32 i, j;
229*437bfbebSnyanmisaka     RK_S32 st_size = 0;
230*437bfbebSnyanmisaka     RK_S32 lt_size = 0;
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p\n", dpb);
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka     /* clear list */
235*437bfbebSnyanmisaka     memset(dpb->list, 0, sizeof(dpb->list));
236*437bfbebSnyanmisaka 
237*437bfbebSnyanmisaka     if (cpb->curr.is_intra) {
238*437bfbebSnyanmisaka         h264e_dbg_dpb("leave %p\n", dpb);
239*437bfbebSnyanmisaka         return ;
240*437bfbebSnyanmisaka     }
241*437bfbebSnyanmisaka 
242*437bfbebSnyanmisaka     // 2.1 init list
243*437bfbebSnyanmisaka     // 2.1.1 found all short term and long term ref
244*437bfbebSnyanmisaka     h264e_dbg_list("cpb init scaning start\n");
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka     for (i = 0; i < MAX_CPB_REFS; i++) {
247*437bfbebSnyanmisaka         EncFrmStatus *frm = &cpb->init[i];
248*437bfbebSnyanmisaka 
249*437bfbebSnyanmisaka         if (!frm->valid)
250*437bfbebSnyanmisaka             continue;
251*437bfbebSnyanmisaka 
252*437bfbebSnyanmisaka         mpp_assert(!frm->is_non_ref);
253*437bfbebSnyanmisaka 
254*437bfbebSnyanmisaka         h264e_dbg_list("idx %d frm %d valid %d is_non_ref %d lt_ref %d\n",
255*437bfbebSnyanmisaka                        i, frm->seq_idx, frm->valid, frm->is_non_ref, frm->is_lt_ref);
256*437bfbebSnyanmisaka 
257*437bfbebSnyanmisaka         H264eDpbFrm *p = find_cpb_frame(dpb, frm);
258*437bfbebSnyanmisaka         if (!frm->is_lt_ref) {
259*437bfbebSnyanmisaka             dpb->stref[st_size++] = p;
260*437bfbebSnyanmisaka             p->status.val = frm->val;
261*437bfbebSnyanmisaka             h264e_dbg_list("found st %d st_size %d %p\n", i, st_size, frm);
262*437bfbebSnyanmisaka         } else {
263*437bfbebSnyanmisaka             dpb->ltref[lt_size++] = p;
264*437bfbebSnyanmisaka             p->status.val = frm->val;
265*437bfbebSnyanmisaka             h264e_dbg_list("found lt %d lt_size %d %p\n", i, lt_size, frm);
266*437bfbebSnyanmisaka         }
267*437bfbebSnyanmisaka     }
268*437bfbebSnyanmisaka 
269*437bfbebSnyanmisaka     h264e_dbg_list("cpb init scaning done\n");
270*437bfbebSnyanmisaka     h264e_dbg_dpb("dpb_size %d st_size %d lt_size %d\n", dpb->dpb_size, st_size, lt_size);
271*437bfbebSnyanmisaka 
272*437bfbebSnyanmisaka     // sort st list
273*437bfbebSnyanmisaka     if (st_size > 1) {
274*437bfbebSnyanmisaka         if (h264e_debug & H264E_DBG_LIST) {
275*437bfbebSnyanmisaka             mpp_log_f("dpb st list before sort\n");
276*437bfbebSnyanmisaka             h264e_dpb_dump_listX(dpb->stref, st_size);
277*437bfbebSnyanmisaka         }
278*437bfbebSnyanmisaka 
279*437bfbebSnyanmisaka         qsort(dpb->stref, st_size, sizeof(dpb->stref[0]), cmp_st_list);
280*437bfbebSnyanmisaka 
281*437bfbebSnyanmisaka         if (h264e_debug & H264E_DBG_LIST) {
282*437bfbebSnyanmisaka             mpp_log_f("dpb st list after  sort\n");
283*437bfbebSnyanmisaka             h264e_dpb_dump_listX(dpb->stref, st_size);
284*437bfbebSnyanmisaka         }
285*437bfbebSnyanmisaka     }
286*437bfbebSnyanmisaka 
287*437bfbebSnyanmisaka     if (lt_size > 1) {
288*437bfbebSnyanmisaka         if (h264e_debug & H264E_DBG_LIST) {
289*437bfbebSnyanmisaka             mpp_log_f("dpb lt list before sort\n");
290*437bfbebSnyanmisaka             h264e_dpb_dump_listX(dpb->ltref, lt_size);
291*437bfbebSnyanmisaka         }
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka         qsort(dpb->ltref, lt_size, sizeof(dpb->ltref[0]), cmp_lt_list);
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka         if (h264e_debug & H264E_DBG_LIST) {
296*437bfbebSnyanmisaka             mpp_log_f("dpb lt list after  sort\n");
297*437bfbebSnyanmisaka             h264e_dpb_dump_listX(dpb->ltref, lt_size);
298*437bfbebSnyanmisaka         }
299*437bfbebSnyanmisaka     }
300*437bfbebSnyanmisaka 
301*437bfbebSnyanmisaka     // generate list before reorder
302*437bfbebSnyanmisaka     memset(dpb->list, 0, sizeof(dpb->list));
303*437bfbebSnyanmisaka     j = 0;
304*437bfbebSnyanmisaka     for (i = 0; i < st_size; i++)
305*437bfbebSnyanmisaka         dpb->list[j++] = dpb->stref[i];
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka     for (i = 0; i < lt_size; i++)
308*437bfbebSnyanmisaka         dpb->list[j++] = dpb->ltref[i];
309*437bfbebSnyanmisaka 
310*437bfbebSnyanmisaka     dpb->st_size = st_size;
311*437bfbebSnyanmisaka     dpb->lt_size = lt_size;
312*437bfbebSnyanmisaka 
313*437bfbebSnyanmisaka     mpp_assert(dpb->dpb_size >= st_size + lt_size);
314*437bfbebSnyanmisaka 
315*437bfbebSnyanmisaka     if (h264e_debug & H264E_DBG_LIST)
316*437bfbebSnyanmisaka         h264e_dpb_dump_list(dpb);
317*437bfbebSnyanmisaka 
318*437bfbebSnyanmisaka     /* generate syntax */
319*437bfbebSnyanmisaka     h264e_reorder_wr_rewind(dpb->reorder);
320*437bfbebSnyanmisaka 
321*437bfbebSnyanmisaka     if (dpb->st_size + dpb->lt_size) {
322*437bfbebSnyanmisaka         H264eDpbFrm *curr = dpb->curr;
323*437bfbebSnyanmisaka         H264eDpbFrm *refr = dpb->refr;
324*437bfbebSnyanmisaka         H264eDpbFrm *def_ref = dpb->list[0];
325*437bfbebSnyanmisaka 
326*437bfbebSnyanmisaka         RK_S32 curr_frm_cnt = curr->status.seq_idx;
327*437bfbebSnyanmisaka         RK_S32 set_ref_frm_cnt = refr->status.seq_idx;
328*437bfbebSnyanmisaka         RK_S32 def_ref_frm_cnt = def_ref->status.seq_idx;
329*437bfbebSnyanmisaka 
330*437bfbebSnyanmisaka         h264e_dbg_list("refer curr %d def %d set %d reorder %d\n",
331*437bfbebSnyanmisaka                        curr_frm_cnt, def_ref_frm_cnt, set_ref_frm_cnt,
332*437bfbebSnyanmisaka                        (def_ref_frm_cnt != set_ref_frm_cnt));
333*437bfbebSnyanmisaka 
334*437bfbebSnyanmisaka         if (def_ref_frm_cnt != set_ref_frm_cnt) {
335*437bfbebSnyanmisaka             H264eRplmo op;
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka             h264e_dbg_list("reorder to frm %d\n", refr->status.seq_idx);
338*437bfbebSnyanmisaka 
339*437bfbebSnyanmisaka             mpp_assert(!refr->status.is_non_ref);
340*437bfbebSnyanmisaka 
341*437bfbebSnyanmisaka             op.modification_of_pic_nums_idc = (refr->status.is_lt_ref) ? (2) : (0);
342*437bfbebSnyanmisaka             if (refr->status.is_lt_ref) {
343*437bfbebSnyanmisaka                 op.modification_of_pic_nums_idc = 2;
344*437bfbebSnyanmisaka                 op.long_term_pic_idx = refr->status.lt_idx;
345*437bfbebSnyanmisaka 
346*437bfbebSnyanmisaka                 h264e_dbg_list("reorder lt idx %d \n", op.long_term_pic_idx);
347*437bfbebSnyanmisaka             } else {
348*437bfbebSnyanmisaka                 op.modification_of_pic_nums_idc = curr->frame_num > refr->frame_num ? 0 : 1;
349*437bfbebSnyanmisaka                 op.abs_diff_pic_num_minus1 = MPP_ABS(curr->frame_num - refr->frame_num) - 1;
350*437bfbebSnyanmisaka 
351*437bfbebSnyanmisaka                 h264e_dbg_list("reorder st cur %d refr %d diff - 1 %d\n",
352*437bfbebSnyanmisaka                                curr->frame_num, refr->frame_num,
353*437bfbebSnyanmisaka                                op.abs_diff_pic_num_minus1);
354*437bfbebSnyanmisaka             }
355*437bfbebSnyanmisaka 
356*437bfbebSnyanmisaka             h264e_reorder_wr_op(dpb->reorder, &op);
357*437bfbebSnyanmisaka         }
358*437bfbebSnyanmisaka     } else {
359*437bfbebSnyanmisaka         h264e_dbg_list("refer NULL\n");
360*437bfbebSnyanmisaka     }
361*437bfbebSnyanmisaka 
362*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
363*437bfbebSnyanmisaka }
364*437bfbebSnyanmisaka 
h264e_dpb_build_marking(H264eDpb * dpb)365*437bfbebSnyanmisaka void h264e_dpb_build_marking(H264eDpb *dpb)
366*437bfbebSnyanmisaka {
367*437bfbebSnyanmisaka     H264eDpbFrm *frm = dpb->curr;
368*437bfbebSnyanmisaka     H264eMarkingInfo *marking = dpb->marking;
369*437bfbebSnyanmisaka 
370*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p\n", dpb);
371*437bfbebSnyanmisaka 
372*437bfbebSnyanmisaka     h264e_marking_wr_rewind(marking);
373*437bfbebSnyanmisaka 
374*437bfbebSnyanmisaka     // refernce frame can not mark itself as unreferenced.
375*437bfbebSnyanmisaka     if (frm->status.is_idr) {
376*437bfbebSnyanmisaka         marking->idr_flag = 1;
377*437bfbebSnyanmisaka         marking->no_output_of_prior_pics = 0;
378*437bfbebSnyanmisaka         marking->long_term_reference_flag = frm->status.is_lt_ref;
379*437bfbebSnyanmisaka         goto DONE;
380*437bfbebSnyanmisaka     }
381*437bfbebSnyanmisaka 
382*437bfbebSnyanmisaka     marking->idr_flag = 0;
383*437bfbebSnyanmisaka     marking->long_term_reference_flag = 0;
384*437bfbebSnyanmisaka     marking->adaptive_ref_pic_buffering = 0;
385*437bfbebSnyanmisaka 
386*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d ref %d lt %d T%d\n",
387*437bfbebSnyanmisaka                   frm->status.seq_idx, !frm->status.is_non_ref,
388*437bfbebSnyanmisaka                   frm->status.is_lt_ref, frm->status.temporal_id);
389*437bfbebSnyanmisaka 
390*437bfbebSnyanmisaka     if (frm->status.is_non_ref)
391*437bfbebSnyanmisaka         goto DONE;
392*437bfbebSnyanmisaka 
393*437bfbebSnyanmisaka     // When current frame is lt_ref update max_lt_idx
394*437bfbebSnyanmisaka     if (frm->status.is_lt_ref) {
395*437bfbebSnyanmisaka         H264eMmco op;
396*437bfbebSnyanmisaka 
397*437bfbebSnyanmisaka         dpb->next_max_lt_idx = dpb->info.max_lt_idx;
398*437bfbebSnyanmisaka 
399*437bfbebSnyanmisaka         if (dpb->next_max_lt_idx != dpb->curr_max_lt_idx) {
400*437bfbebSnyanmisaka             RK_S32 max_lt_idx_p1 = dpb->next_max_lt_idx + 1;
401*437bfbebSnyanmisaka 
402*437bfbebSnyanmisaka             op.mmco = 4;
403*437bfbebSnyanmisaka             op.max_long_term_frame_idx_plus1 = max_lt_idx_p1;
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka             h264e_marking_wr_op(marking, &op);
406*437bfbebSnyanmisaka             h264e_dbg_mmco("add mmco 4 %d\n", max_lt_idx_p1);
407*437bfbebSnyanmisaka 
408*437bfbebSnyanmisaka             dpb->curr_max_lt_idx = dpb->next_max_lt_idx;
409*437bfbebSnyanmisaka         }
410*437bfbebSnyanmisaka 
411*437bfbebSnyanmisaka         op.mmco = 6;
412*437bfbebSnyanmisaka         op.long_term_frame_idx = frm->lt_idx;
413*437bfbebSnyanmisaka 
414*437bfbebSnyanmisaka         h264e_marking_wr_op(marking, &op);
415*437bfbebSnyanmisaka         h264e_dbg_mmco("add mmco 6 %d\n", frm->lt_idx);
416*437bfbebSnyanmisaka     }
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka     // TODO: check and mark used frame
419*437bfbebSnyanmisaka DONE:
420*437bfbebSnyanmisaka     h264e_dbg_dpb("dpb size %d used %d\n", dpb->dpb_size, dpb->used_size);
421*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
422*437bfbebSnyanmisaka }
423*437bfbebSnyanmisaka 
h264e_dpb_proc(H264eDpb * dpb,EncCpbStatus * cpb)424*437bfbebSnyanmisaka MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
425*437bfbebSnyanmisaka {
426*437bfbebSnyanmisaka     EncFrmStatus *curr = &cpb->curr;
427*437bfbebSnyanmisaka     EncFrmStatus *refr = &cpb->refr;
428*437bfbebSnyanmisaka     EncFrmStatus *init = cpb->init;
429*437bfbebSnyanmisaka     H264eDpbFrm *frames = dpb->frames;
430*437bfbebSnyanmisaka     H264eDpbRt *rt = &dpb->rt;
431*437bfbebSnyanmisaka     RK_S32 used_size = 0;
432*437bfbebSnyanmisaka     RK_S32 seq_idx = curr->seq_idx;
433*437bfbebSnyanmisaka     RK_S32 i;
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p total %d\n", dpb, dpb->total_cnt);
436*437bfbebSnyanmisaka 
437*437bfbebSnyanmisaka     if (curr->is_idr) {
438*437bfbebSnyanmisaka         for (i = 0; i < H264E_MAX_REFS_CNT + 1; i++) {
439*437bfbebSnyanmisaka             frames[i].dpb_used = 0;
440*437bfbebSnyanmisaka             frames[i].status.valid = 0;
441*437bfbebSnyanmisaka         }
442*437bfbebSnyanmisaka         dpb->used_size = 0;
443*437bfbebSnyanmisaka         dpb->curr_max_lt_idx = 0;
444*437bfbebSnyanmisaka         dpb->next_max_lt_idx = 0;
445*437bfbebSnyanmisaka     } else {
446*437bfbebSnyanmisaka         if (curr->seq_idx == rt->last_seq_idx) {
447*437bfbebSnyanmisaka             h264e_dbg_dpb("NOTE: reenc found at %d\n", curr->seq_idx);
448*437bfbebSnyanmisaka             memcpy(rt, &dpb->rt_bak, sizeof(*rt));
449*437bfbebSnyanmisaka             memcpy(frames, dpb->frm_bak, sizeof(dpb->frm_bak));
450*437bfbebSnyanmisaka         }
451*437bfbebSnyanmisaka     }
452*437bfbebSnyanmisaka 
453*437bfbebSnyanmisaka     if (h264e_debug & H264E_DBG_DPB)
454*437bfbebSnyanmisaka         h264e_dpb_dump_frms(dpb);
455*437bfbebSnyanmisaka     /*
456*437bfbebSnyanmisaka      * 1. scan and map cpb to internal cpb h264edpb is bridge from
457*437bfbebSnyanmisaka      *    user defined cpb to hal slot index
458*437bfbebSnyanmisaka      */
459*437bfbebSnyanmisaka     for (i = 0; i < MAX_CPB_REFS; i++) {
460*437bfbebSnyanmisaka         H264eDpbFrm *frm = find_cpb_frame(dpb, &init[i]);
461*437bfbebSnyanmisaka         dpb->map[i] = frm;
462*437bfbebSnyanmisaka         if (frm) {
463*437bfbebSnyanmisaka             if (!frm->on_used && !frm->status.force_pskip_is_ref)
464*437bfbebSnyanmisaka                 mpp_err_f("warning frm %d is used by cpb but on not used status\n",
465*437bfbebSnyanmisaka                           frm->seq_idx);
466*437bfbebSnyanmisaka             frm->dpb_used = 1;
467*437bfbebSnyanmisaka             used_size++;
468*437bfbebSnyanmisaka         }
469*437bfbebSnyanmisaka     }
470*437bfbebSnyanmisaka 
471*437bfbebSnyanmisaka     mpp_assert(dpb->used_size == used_size);
472*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d init cpb used size %d vs %d\n", seq_idx,
473*437bfbebSnyanmisaka                   used_size, dpb->used_size);
474*437bfbebSnyanmisaka 
475*437bfbebSnyanmisaka     /* backup current runtime status */
476*437bfbebSnyanmisaka     memcpy(&dpb->rt_bak, rt, sizeof(dpb->rt_bak));
477*437bfbebSnyanmisaka     memcpy(dpb->frm_bak, frames, sizeof(dpb->frm_bak));
478*437bfbebSnyanmisaka 
479*437bfbebSnyanmisaka     /* mark current cpb */
480*437bfbebSnyanmisaka     RK_S32 found_curr = 0;
481*437bfbebSnyanmisaka 
482*437bfbebSnyanmisaka     /* 2. scan all slot for used map and find a slot for current */
483*437bfbebSnyanmisaka     dpb->curr = NULL;
484*437bfbebSnyanmisaka 
485*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d start finding slot for storage\n", seq_idx);
486*437bfbebSnyanmisaka     for (i = 0; i < H264E_MAX_REFS_CNT + 1; i++) {
487*437bfbebSnyanmisaka         H264eDpbFrm *p = &frames[i];
488*437bfbebSnyanmisaka         RK_S32 curr_frm_num = rt->last_frm_num + rt->last_is_ref;
489*437bfbebSnyanmisaka         RK_S32 curr_poc_lsb = rt->last_poc_lsb;
490*437bfbebSnyanmisaka         RK_S32 curr_poc_msb = rt->last_poc_msb;
491*437bfbebSnyanmisaka         RK_S32 valid = 0;
492*437bfbebSnyanmisaka         RK_S32 j;
493*437bfbebSnyanmisaka 
494*437bfbebSnyanmisaka         for (j = 0; j < MAX_CPB_REFS; j++) {
495*437bfbebSnyanmisaka             if (p == dpb->map[j] || p->as_pskip_ref) {
496*437bfbebSnyanmisaka                 valid = 1;
497*437bfbebSnyanmisaka                 break;
498*437bfbebSnyanmisaka             }
499*437bfbebSnyanmisaka         }
500*437bfbebSnyanmisaka 
501*437bfbebSnyanmisaka         h264e_dbg_dpb("slot %2d check in cpb init valid %d used %04x\n",
502*437bfbebSnyanmisaka                       i, valid, p->on_used);
503*437bfbebSnyanmisaka 
504*437bfbebSnyanmisaka         if (valid) {
505*437bfbebSnyanmisaka             if ((!p->as_pskip_ref) &&
506*437bfbebSnyanmisaka                 (!p->on_used || !p->status.valid)) {
507*437bfbebSnyanmisaka                 mpp_assert(p->on_used);
508*437bfbebSnyanmisaka                 mpp_assert(p->status.valid);
509*437bfbebSnyanmisaka                 h264e_dpb_dump_frms(dpb);
510*437bfbebSnyanmisaka             }
511*437bfbebSnyanmisaka             continue;
512*437bfbebSnyanmisaka         }
513*437bfbebSnyanmisaka 
514*437bfbebSnyanmisaka         h264e_dbg_dpb("slot %2d used %04x checking\n", i, p->on_used);
515*437bfbebSnyanmisaka 
516*437bfbebSnyanmisaka         if (p->hal_used)
517*437bfbebSnyanmisaka             continue;
518*437bfbebSnyanmisaka 
519*437bfbebSnyanmisaka         if (found_curr) {
520*437bfbebSnyanmisaka             p->dpb_used = 0;
521*437bfbebSnyanmisaka             p->status.valid = 0;
522*437bfbebSnyanmisaka             continue;
523*437bfbebSnyanmisaka         }
524*437bfbebSnyanmisaka 
525*437bfbebSnyanmisaka         h264e_dbg_dpb("slot %2d used %04x mark as current\n", i, p->on_used);
526*437bfbebSnyanmisaka 
527*437bfbebSnyanmisaka         dpb->curr = p;
528*437bfbebSnyanmisaka         p->status.val = curr->val;
529*437bfbebSnyanmisaka         p->seq_idx = curr->seq_idx;
530*437bfbebSnyanmisaka         if (curr->is_idr) {
531*437bfbebSnyanmisaka             p->frame_num = 0;
532*437bfbebSnyanmisaka             p->poc = 0;
533*437bfbebSnyanmisaka             curr_frm_num = 0;
534*437bfbebSnyanmisaka             curr_poc_lsb = 0;
535*437bfbebSnyanmisaka             curr_poc_msb = 0;
536*437bfbebSnyanmisaka         } else {
537*437bfbebSnyanmisaka             if (curr_frm_num >= dpb->max_frm_num)
538*437bfbebSnyanmisaka                 curr_frm_num = 0;
539*437bfbebSnyanmisaka 
540*437bfbebSnyanmisaka             p->frame_num = curr_frm_num;
541*437bfbebSnyanmisaka 
542*437bfbebSnyanmisaka             if (dpb->poc_type == 0)
543*437bfbebSnyanmisaka                 curr_poc_lsb += 2;
544*437bfbebSnyanmisaka             else if (dpb->poc_type == 2)
545*437bfbebSnyanmisaka                 curr_poc_lsb += 1 + rt->last_is_ref;
546*437bfbebSnyanmisaka             else
547*437bfbebSnyanmisaka                 mpp_err_f("do not support poc type 1\n");
548*437bfbebSnyanmisaka 
549*437bfbebSnyanmisaka             if (curr_poc_lsb >= dpb->max_poc_lsb) {
550*437bfbebSnyanmisaka                 curr_poc_lsb = 0;
551*437bfbebSnyanmisaka                 curr_poc_msb++;
552*437bfbebSnyanmisaka             }
553*437bfbebSnyanmisaka 
554*437bfbebSnyanmisaka             p->poc = curr_poc_lsb + curr_poc_msb * dpb->max_poc_lsb;
555*437bfbebSnyanmisaka 
556*437bfbebSnyanmisaka         }
557*437bfbebSnyanmisaka         p->lt_idx = curr->lt_idx;
558*437bfbebSnyanmisaka         p->dpb_used = 1;
559*437bfbebSnyanmisaka 
560*437bfbebSnyanmisaka         rt->last_seq_idx = curr->seq_idx;
561*437bfbebSnyanmisaka         rt->last_is_ref  = !curr->is_non_ref;
562*437bfbebSnyanmisaka         rt->last_frm_num = curr_frm_num;
563*437bfbebSnyanmisaka         rt->last_poc_lsb = curr_poc_lsb;
564*437bfbebSnyanmisaka         rt->last_poc_msb = curr_poc_msb;
565*437bfbebSnyanmisaka 
566*437bfbebSnyanmisaka         found_curr = 1;
567*437bfbebSnyanmisaka         h264e_dbg_dpb("frm %d update slot %d with frame_num %d poc %d\n",
568*437bfbebSnyanmisaka                       seq_idx, i, p->frame_num, p->poc);
569*437bfbebSnyanmisaka     }
570*437bfbebSnyanmisaka 
571*437bfbebSnyanmisaka     mpp_assert(dpb->curr);
572*437bfbebSnyanmisaka 
573*437bfbebSnyanmisaka     if (NULL == dpb->curr)
574*437bfbebSnyanmisaka         mpp_err_f("frm %d failed to find a slot for curr %d\n", seq_idx);
575*437bfbebSnyanmisaka 
576*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d start finding slot for refr %d\n", seq_idx, refr->seq_idx);
577*437bfbebSnyanmisaka     dpb->refr = find_cpb_frame(dpb, refr);
578*437bfbebSnyanmisaka     if (NULL == dpb->refr)
579*437bfbebSnyanmisaka         dpb->refr = dpb->curr;
580*437bfbebSnyanmisaka 
581*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d curr %d refr %d start building list\n",
582*437bfbebSnyanmisaka                   seq_idx, dpb->curr->slot_idx, dpb->refr->slot_idx);
583*437bfbebSnyanmisaka 
584*437bfbebSnyanmisaka     h264e_dpb_build_list(dpb, cpb);
585*437bfbebSnyanmisaka 
586*437bfbebSnyanmisaka     if (h264e_debug & H264E_DBG_DPB)
587*437bfbebSnyanmisaka         h264e_dpb_dump_frms(dpb);
588*437bfbebSnyanmisaka 
589*437bfbebSnyanmisaka     h264e_dpb_build_marking(dpb);
590*437bfbebSnyanmisaka 
591*437bfbebSnyanmisaka     if (h264e_debug & H264E_DBG_DPB)
592*437bfbebSnyanmisaka         h264e_dpb_dump_frms(dpb);
593*437bfbebSnyanmisaka 
594*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
595*437bfbebSnyanmisaka 
596*437bfbebSnyanmisaka     return MPP_OK;
597*437bfbebSnyanmisaka }
598*437bfbebSnyanmisaka 
h264e_dpb_check(H264eDpb * dpb,EncCpbStatus * cpb)599*437bfbebSnyanmisaka void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb)
600*437bfbebSnyanmisaka {
601*437bfbebSnyanmisaka     H264eDpbFrm *curr = dpb->curr;
602*437bfbebSnyanmisaka     H264eDpbFrm *refr = dpb->refr;
603*437bfbebSnyanmisaka     RK_S32 i;
604*437bfbebSnyanmisaka 
605*437bfbebSnyanmisaka     h264e_dbg_dpb("enter %p\n", dpb);
606*437bfbebSnyanmisaka 
607*437bfbebSnyanmisaka     h264e_dbg_dpb("frm %d refr -> frm %d ready\n",
608*437bfbebSnyanmisaka                   curr->seq_idx, refr->seq_idx);
609*437bfbebSnyanmisaka 
610*437bfbebSnyanmisaka     if (curr->status.is_non_ref) {
611*437bfbebSnyanmisaka         curr->dpb_used = 0;
612*437bfbebSnyanmisaka         curr->status.valid = 0;
613*437bfbebSnyanmisaka     } else {
614*437bfbebSnyanmisaka         /* sliding window process */
615*437bfbebSnyanmisaka         RK_S32 used_size = dpb->used_size;
616*437bfbebSnyanmisaka         RK_S32 dpb_size = dpb->dpb_size;
617*437bfbebSnyanmisaka 
618*437bfbebSnyanmisaka         h264e_dbg_dpb("frm %d %s insert dpb used %d max %d\n",
619*437bfbebSnyanmisaka                       curr->seq_idx, curr->status.is_lt_ref ? "lt" : "st",
620*437bfbebSnyanmisaka                       used_size, dpb_size);
621*437bfbebSnyanmisaka 
622*437bfbebSnyanmisaka         used_size++;
623*437bfbebSnyanmisaka 
624*437bfbebSnyanmisaka         /* replace lt ref with same lt_idx */
625*437bfbebSnyanmisaka         if (curr->status.is_lt_ref) {
626*437bfbebSnyanmisaka             RK_S32 lt_idx = curr->lt_idx;
627*437bfbebSnyanmisaka 
628*437bfbebSnyanmisaka             dpb->lt_size++;
629*437bfbebSnyanmisaka 
630*437bfbebSnyanmisaka             for (i = 0; i < dpb->total_cnt; i++) {
631*437bfbebSnyanmisaka                 H264eDpbFrm *tmp = &dpb->frames[i];
632*437bfbebSnyanmisaka 
633*437bfbebSnyanmisaka                 if (tmp == curr)
634*437bfbebSnyanmisaka                     continue;
635*437bfbebSnyanmisaka 
636*437bfbebSnyanmisaka                 if (!tmp->dpb_used)
637*437bfbebSnyanmisaka                     continue;
638*437bfbebSnyanmisaka 
639*437bfbebSnyanmisaka                 if (!tmp->status.valid)
640*437bfbebSnyanmisaka                     continue;
641*437bfbebSnyanmisaka 
642*437bfbebSnyanmisaka                 mpp_assert(!tmp->status.is_non_ref);
643*437bfbebSnyanmisaka 
644*437bfbebSnyanmisaka                 if (!tmp->status.is_lt_ref)
645*437bfbebSnyanmisaka                     continue;
646*437bfbebSnyanmisaka 
647*437bfbebSnyanmisaka                 if (tmp->lt_idx == lt_idx) {
648*437bfbebSnyanmisaka                     tmp->dpb_used = 0;
649*437bfbebSnyanmisaka                     tmp->status.valid = 0;
650*437bfbebSnyanmisaka                     h264e_dbg_dpb("frm %d lt_idx %d replace %d\n",
651*437bfbebSnyanmisaka                                   curr->seq_idx, curr->lt_idx, tmp->slot_idx);
652*437bfbebSnyanmisaka                     dpb->lt_size--;
653*437bfbebSnyanmisaka                     used_size--;
654*437bfbebSnyanmisaka                 }
655*437bfbebSnyanmisaka             }
656*437bfbebSnyanmisaka         } else {
657*437bfbebSnyanmisaka             dpb->st_size++;
658*437bfbebSnyanmisaka         }
659*437bfbebSnyanmisaka 
660*437bfbebSnyanmisaka         if (used_size > dpb_size) {
661*437bfbebSnyanmisaka             mpp_assert(dpb->lt_size <= dpb_size);
662*437bfbebSnyanmisaka 
663*437bfbebSnyanmisaka             while (used_size > dpb_size) {
664*437bfbebSnyanmisaka                 RK_S32 small_poc = 0x7fffffff;
665*437bfbebSnyanmisaka                 H264eDpbFrm *unref = NULL;
666*437bfbebSnyanmisaka 
667*437bfbebSnyanmisaka                 h264e_dbg_dpb("sliding window cpb proc: st %d lt %d max %d\n",
668*437bfbebSnyanmisaka                               dpb->st_size, dpb->lt_size, dpb_size);
669*437bfbebSnyanmisaka 
670*437bfbebSnyanmisaka                 for (i = 0; i < dpb->total_cnt; i++) {
671*437bfbebSnyanmisaka                     H264eDpbFrm *tmp = &dpb->frames[i];
672*437bfbebSnyanmisaka 
673*437bfbebSnyanmisaka                     h264e_dbg_dpb("frm %d num %d poc %d\n",
674*437bfbebSnyanmisaka                                   tmp->seq_idx, tmp->frame_num, tmp->poc);
675*437bfbebSnyanmisaka 
676*437bfbebSnyanmisaka                     if (tmp->as_pskip_ref)
677*437bfbebSnyanmisaka                         continue;
678*437bfbebSnyanmisaka 
679*437bfbebSnyanmisaka                     if (!tmp->on_used)
680*437bfbebSnyanmisaka                         continue;
681*437bfbebSnyanmisaka 
682*437bfbebSnyanmisaka                     if (!tmp->status.valid)
683*437bfbebSnyanmisaka                         continue;
684*437bfbebSnyanmisaka 
685*437bfbebSnyanmisaka                     mpp_assert(!tmp->status.is_non_ref);
686*437bfbebSnyanmisaka 
687*437bfbebSnyanmisaka                     if (tmp->status.is_lt_ref)
688*437bfbebSnyanmisaka                         continue;
689*437bfbebSnyanmisaka 
690*437bfbebSnyanmisaka                     if (tmp->poc < small_poc) {
691*437bfbebSnyanmisaka                         unref = tmp;
692*437bfbebSnyanmisaka                         small_poc = tmp->poc;
693*437bfbebSnyanmisaka 
694*437bfbebSnyanmisaka                         h264e_dbg_dpb("frm %d update smallest poc to %d\n",
695*437bfbebSnyanmisaka                                       tmp->seq_idx, tmp->poc);
696*437bfbebSnyanmisaka                     }
697*437bfbebSnyanmisaka                 }
698*437bfbebSnyanmisaka 
699*437bfbebSnyanmisaka                 if (unref) {
700*437bfbebSnyanmisaka                     h264e_dbg_dpb("removing frm %d poc %d\n",
701*437bfbebSnyanmisaka                                   unref->seq_idx, unref->poc);
702*437bfbebSnyanmisaka 
703*437bfbebSnyanmisaka                     unref->dpb_used = 0;
704*437bfbebSnyanmisaka                     dpb->st_size--;
705*437bfbebSnyanmisaka                     mpp_assert(dpb->st_size >= 0);
706*437bfbebSnyanmisaka                     used_size--;
707*437bfbebSnyanmisaka                 } else
708*437bfbebSnyanmisaka                     break;
709*437bfbebSnyanmisaka             }
710*437bfbebSnyanmisaka         }
711*437bfbebSnyanmisaka 
712*437bfbebSnyanmisaka         dpb->used_size = used_size;
713*437bfbebSnyanmisaka         if (used_size > dpb_size) {
714*437bfbebSnyanmisaka             mpp_err_f("error found used_size %d > dpb_size %d\n", used_size, dpb_size);
715*437bfbebSnyanmisaka             mpp_assert(used_size <= dpb_size);
716*437bfbebSnyanmisaka         }
717*437bfbebSnyanmisaka     }
718*437bfbebSnyanmisaka 
719*437bfbebSnyanmisaka     h264e_dbg_dpb("curr %d done used_size %d\n", curr->seq_idx, dpb->used_size);
720*437bfbebSnyanmisaka 
721*437bfbebSnyanmisaka     RK_S32 used_size = 0;
722*437bfbebSnyanmisaka     for (i = 0; i < MAX_CPB_REFS; i++) {
723*437bfbebSnyanmisaka         dpb->map[i] = find_cpb_frame(dpb, &cpb->final[i]);
724*437bfbebSnyanmisaka         if (dpb->map[i])
725*437bfbebSnyanmisaka             used_size++;
726*437bfbebSnyanmisaka     }
727*437bfbebSnyanmisaka 
728*437bfbebSnyanmisaka     h264e_dbg_dpb("curr %d cpb final used_size %d vs %d\n",
729*437bfbebSnyanmisaka                   curr->seq_idx, used_size, dpb->used_size);
730*437bfbebSnyanmisaka     mpp_assert(dpb->used_size == used_size);
731*437bfbebSnyanmisaka 
732*437bfbebSnyanmisaka     h264e_dbg_dpb("leave %p\n", dpb);
733*437bfbebSnyanmisaka }
734*437bfbebSnyanmisaka 
h264e_dpb_hal_start(H264eDpb * dpb,RK_S32 slot_idx)735*437bfbebSnyanmisaka MPP_RET h264e_dpb_hal_start(H264eDpb *dpb, RK_S32 slot_idx)
736*437bfbebSnyanmisaka {
737*437bfbebSnyanmisaka     H264eDpbFrm *frm = &dpb->frames[slot_idx];
738*437bfbebSnyanmisaka 
739*437bfbebSnyanmisaka     frm->hal_used++;
740*437bfbebSnyanmisaka     //h264e_dpb_dump_usage(dpb, __FUNCTION__);
741*437bfbebSnyanmisaka     return MPP_OK;
742*437bfbebSnyanmisaka }
743*437bfbebSnyanmisaka 
h264e_dpb_hal_end(H264eDpb * dpb,RK_S32 slot_idx)744*437bfbebSnyanmisaka MPP_RET h264e_dpb_hal_end(H264eDpb *dpb, RK_S32 slot_idx)
745*437bfbebSnyanmisaka {
746*437bfbebSnyanmisaka     H264eDpbFrm *frm = &dpb->frames[slot_idx];
747*437bfbebSnyanmisaka 
748*437bfbebSnyanmisaka     frm->hal_used--;
749*437bfbebSnyanmisaka     //h264e_dpb_dump_usage(dpb, __FUNCTION__);
750*437bfbebSnyanmisaka     return MPP_OK;
751*437bfbebSnyanmisaka }
752