xref: /aosp_15_r20/external/libavc/decoder/mvc/imvcd_dpb_manager.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2021 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 /*****************************************************************************/
22 /*                                                                           */
23 /*  File Name         : imvcd_nalu_parser.h                                  */
24 /*                                                                           */
25 /*  Description       : Functions for MVC NALU parsing                       */
26 /*                                                                           */
27 /*****************************************************************************/
28 #include <stdbool.h>
29 
30 #include "ih264_typedefs.h"
31 #include "ih264d_error_handler.h"
32 #include "imvcd_dpb_manager.h"
33 #include "imvcd_structs.h"
34 #include "imvcd_utils.h"
35 
imvcd_dpb_set_display_num(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_display_num)36 void imvcd_dpb_set_display_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_num)
37 {
38     ps_dpb_mgr->i4_cur_display_seq = i4_display_num;
39 }
40 
imvcd_dpb_set_max_pic_num(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_max_pic_num)41 void imvcd_dpb_set_max_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_pic_num)
42 {
43     ps_dpb_mgr->i4_max_pic_num = i4_max_pic_num;
44 }
45 
imvcd_dpb_set_num_views(mvc_dpb_manager_t * ps_dpb_mgr,UWORD16 u2_num_views)46 void imvcd_dpb_set_num_views(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_num_views)
47 {
48     ps_dpb_mgr->u2_num_views = u2_num_views;
49 }
50 
imvcd_dpb_set_display_delay(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_display_delay)51 void imvcd_dpb_set_display_delay(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_delay)
52 {
53     ps_dpb_mgr->i4_display_delay = i4_display_delay;
54 }
55 
imvcd_dpb_init_au_bufs(mvc_dpb_manager_t * ps_dpb_mgr,mvc_au_buffer_t * ps_cur_au)56 void imvcd_dpb_init_au_bufs(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_cur_au)
57 {
58     WORD32 i;
59 
60     for(i = 0; i < 2; i++)
61     {
62         ps_dpb_mgr->as_init_dpb[i][0] = ps_cur_au[0];
63     }
64 }
65 
imvcd_dpb_init_view_bufs(mvc_dpb_manager_t * ps_dpb_mgr,UWORD16 u2_view_order_id,UWORD16 u2_view_id)66 void imvcd_dpb_init_view_bufs(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_view_order_id,
67                               UWORD16 u2_view_id)
68 {
69     WORD32 i;
70 
71     for(i = 0; i < 2; i++)
72     {
73         imvcd_convert_au_buf_to_view_buf(&ps_dpb_mgr->as_init_dpb[i][0],
74                                          &ps_dpb_mgr->as_view_init_dpb[i][0], u2_view_order_id,
75                                          u2_view_id);
76     }
77 }
78 
imvcd_dpb_init_ivp_ctxt(mvc_dpb_manager_t * ps_dpb_mgr,sps_mvc_ext_t * ps_sps_mvc_ext,nalu_mvc_ext_t * ps_nalu_mvc_exts)79 void imvcd_dpb_init_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr, sps_mvc_ext_t *ps_sps_mvc_ext,
80                              nalu_mvc_ext_t *ps_nalu_mvc_exts)
81 {
82     ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = ps_nalu_mvc_exts;
83     ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = ps_sps_mvc_ext;
84 
85     ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
86 }
87 
imvcd_dpb_reset_ivp_ctxt(mvc_dpb_manager_t * ps_dpb_mgr)88 void imvcd_dpb_reset_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr)
89 {
90     UWORD32 i;
91 
92     for(i = 0; i < ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs; i++)
93     {
94         ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
95                               ps_dpb_mgr->s_dpb_ivp_ctxt.au1_au_buf_ids[i],
96                               BUF_MGR_REF | BUF_MGR_IO);
97 
98         ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
99                               ps_dpb_mgr->s_dpb_ivp_ctxt.au1_mv_buf_ids[i],
100                               BUF_MGR_REF | BUF_MGR_IO);
101     }
102 
103     ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
104 }
105 
imvcd_dpb_get_view_ref_pic_list(mvc_dpb_manager_t * ps_dpb_mgr,UWORD16 u2_view_order_id,UWORD16 u2_view_id,UWORD8 u1_pred_dir)106 pic_buffer_t **imvcd_dpb_get_view_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
107                                                UWORD16 u2_view_order_id, UWORD16 u2_view_id,
108                                                UWORD8 u1_pred_dir)
109 {
110     WORD32 i;
111 
112     UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_dir] +
113                              ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_dir];
114 
115     for(i = 0; i < u1_num_ref_bufs; i++)
116     {
117         imvcd_convert_au_buf_to_view_buf(ps_dpb_mgr->aps_mod_dpb[u1_pred_dir][i],
118                                          &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i],
119                                          u2_view_order_id, u2_view_id);
120 
121         ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir][i] =
122             &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i];
123     }
124 
125     return ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir];
126 }
127 
imvcd_init_dpb_mgr(mvc_dpb_manager_t * ps_dpb_mgr,mvc_au_buf_mgr_t * ps_mvc_au_buf_mgr,mvc_au_mv_pred_buf_mgr_t * ps_mvc_au_mv_pred_buf_mgr,disp_mgr_t * ps_disp_buf_mgr)128 void imvcd_init_dpb_mgr(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
129                         mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
130                         disp_mgr_t *ps_disp_buf_mgr)
131 {
132     WORD32 i, j, k, l;
133 
134     mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
135 
136     for(i = 0; i < 2; i++)
137     {
138         mvc_au_buffer_t *ps_init_dpb = ps_dpb_mgr->as_init_dpb[i];
139         pic_buffer_t *ps_view_init_dpb = ps_dpb_mgr->as_view_init_dpb[i];
140 
141         for(j = 0; j < MVC_MAX_REF_PICS; j++)
142         {
143             for(k = 0; k < MAX_NUM_VIEWS; k++)
144             {
145                 for(l = 0; l < NUM_COMPONENTS; l++)
146                 {
147                     ps_init_dpb->as_view_buffers[k].as_component_bufs[l].pv_data = NULL;
148                 }
149             }
150 
151             ps_view_init_dpb->pu1_buf1 = NULL;
152             ps_view_init_dpb->pu1_buf2 = NULL;
153             ps_view_init_dpb->pu1_buf3 = NULL;
154 
155             ps_dpb_mgr->aps_mod_dpb[i][j] = ps_init_dpb;
156             ps_dpb_mgr->aps_view_mod_dpb[i][j] = ps_view_init_dpb;
157 
158             ps_init_dpb++;
159             ps_view_init_dpb++;
160         }
161     }
162 
163     for(i = 0; i < MVC_MAX_REF_PICS; i++)
164     {
165         ps_dpb_info[i].b_used_as_ref = false;
166         ps_dpb_info[i].ps_prev_short = NULL;
167         ps_dpb_info[i].ps_prev_long = NULL;
168         ps_dpb_info[i].ps_au_buf = NULL;
169         ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
170         ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
171         ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
172         ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
173     }
174 
175     ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
176     ps_dpb_mgr->ps_dpb_st_head = NULL;
177     ps_dpb_mgr->ps_dpb_lt_head = NULL;
178     ps_dpb_mgr->i1_gaps_deleted = 0;
179     ps_dpb_mgr->i1_poc_buf_id_entries = 0;
180     ps_dpb_mgr->u1_mmco_error_in_seq = 0;
181     ps_dpb_mgr->u1_num_gaps = 0;
182     ps_dpb_mgr->i4_display_delay = 0;
183     ps_dpb_mgr->i4_cur_display_seq = 0;
184 
185     for(i = 0; i < MAX_FRAMES; i++)
186     {
187         ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
188         ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
189         ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
190         ps_dpb_mgr->as_display_buf_info[i].i4_poc_buf_id = -1;
191         ps_dpb_mgr->as_display_buf_info[i].i4_poc = INT32_MAX;
192         ps_dpb_mgr->as_display_buf_info[i].i4_frame_num = 0;
193     }
194 
195     ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
196     ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = NULL;
197     ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = NULL;
198 
199     ps_dpb_mgr->ps_mvc_au_buf_mgr = ps_mvc_au_buf_mgr;
200     ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr = ps_mvc_au_mv_pred_buf_mgr;
201     ps_dpb_mgr->ps_disp_buf_mgr = ps_disp_buf_mgr;
202 }
203 
imvcd_dpb_assign_display_seq(mvc_dpb_manager_t * ps_dpb_mgr)204 WORD32 imvcd_dpb_assign_display_seq(mvc_dpb_manager_t *ps_dpb_mgr)
205 {
206     WORD32 i;
207 
208     display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
209 
210     WORD32 i4_min_poc = INT32_MAX;
211     WORD32 i4_min_poc_buf_id = -1;
212     WORD32 i4_min_index = -1;
213 
214     if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dpb_mgr->i4_display_delay)
215     {
216         for(i = 0; i < MAX_FRAMES; i++)
217         {
218             if((-1 != ps_display_buf_info[i].i4_poc_buf_id) &&
219                (DO_NOT_DISP != ps_display_buf_info[i].i4_poc_buf_id))
220             {
221                 /* Checking for <= is necessary to handle cases where there is one
222                    valid buffer with poc set to 0x7FFFFFFF. */
223                 if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
224                 {
225                     i4_min_poc = ps_display_buf_info[i].i4_poc;
226                     i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
227                     i4_min_index = i;
228                 }
229             }
230         }
231 
232         if((i4_min_index != -1) && (DO_NOT_DISP != i4_min_poc_buf_id))
233         {
234             ps_dpb_mgr->i4_cur_display_seq++;
235 
236             ih264_disp_mgr_add(
237                 ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
238                 ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);
239 
240             ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
241             ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
242 
243             ps_dpb_mgr->i1_poc_buf_id_entries--;
244         }
245         else if(DO_NOT_DISP == i4_min_poc_buf_id)
246         {
247             return ERROR_GAPS_IN_FRM_NUM;
248         }
249     }
250 
251     return OK;
252 }
253 
imvcd_dpb_insert_pic_in_display_list(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_display_poc,UWORD32 u4_frame_num,WORD32 i4_buf_id)254 WORD32 imvcd_dpb_insert_pic_in_display_list(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_poc,
255                                             UWORD32 u4_frame_num, WORD32 i4_buf_id)
256 {
257     WORD32 i;
258 
259     display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
260 
261     for(i = 0; i < MAX_FRAMES; i++)
262     {
263         /* Find an empty slot */
264         if(ps_display_buf_info[i].i4_poc_buf_id == -1)
265         {
266             if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
267             {
268                 ps_dpb_mgr->i1_gaps_deleted--;
269             }
270             else
271             {
272                 ps_dpb_mgr->i1_poc_buf_id_entries++;
273             }
274 
275             ps_display_buf_info[i].i4_poc_buf_id = i4_buf_id;
276             ps_display_buf_info[i].i4_poc = i4_display_poc;
277             ps_display_buf_info[i].i4_frame_num = u4_frame_num;
278 
279             break;
280         }
281     }
282 
283     if(MAX_FRAMES == i)
284     {
285         return ERROR_GAPS_IN_FRM_NUM;
286     }
287 
288     return OK;
289 }
290 
imvcd_dpb_delete_gap_frm_sliding(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_pic_num,UWORD8 * pu1_del_node)291 static WORD32 imvcd_dpb_delete_gap_frm_sliding(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
292                                                UWORD8 *pu1_del_node)
293 {
294     WORD32 i, j, j_min;
295     WORD8 i1_gap_idx;
296     WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
297     WORD32 i4_start_frm_num, i4_end_frm_num;
298     WORD32 i4_max_pic_num;
299     WORD32 i4_frm_num, i4_gap_frm_num_min;
300 
301     /* find the least frame num from gaps and current DPB node    */
302     /* Delete the least one                                       */
303     *pu1_del_node = 1;
304 
305     if(0 == ps_dpb_mgr->u1_num_gaps)
306     {
307         return OK;
308     }
309 
310     pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
311     pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
312     i4_gap_frame_num = INVALID_FRAME_NUM;
313     i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
314 
315     i1_gap_idx = -1;
316 
317     if(INVALID_FRAME_NUM != i4_pic_num)
318     {
319         i4_gap_frame_num = i4_pic_num;
320 
321         for(i = 0; i < MAX_FRAMES; i++)
322         {
323             i4_start_frm_num = pi4_gaps_start_frm_num[i];
324 
325             if(INVALID_FRAME_NUM != i4_start_frm_num)
326             {
327                 i4_end_frm_num = pi4_gaps_end_frm_num[i];
328 
329                 if(i4_end_frm_num < i4_max_pic_num)
330                 {
331                     if(i4_start_frm_num <= i4_gap_frame_num)
332                     {
333                         i4_gap_frame_num = i4_start_frm_num;
334                         i1_gap_idx = i;
335                     }
336                 }
337                 else
338                 {
339                     if(((i4_start_frm_num <= i4_gap_frame_num) &&
340                         (i4_gap_frame_num <= i4_max_pic_num)) ||
341                        ((i4_start_frm_num >= i4_gap_frame_num) &&
342                         ((i4_gap_frame_num + i4_max_pic_num) >= i4_end_frm_num)))
343                     {
344                         i4_gap_frame_num = i4_start_frm_num;
345                         i1_gap_idx = i;
346                     }
347                 }
348             }
349         }
350     }
351     else
352     {
353         /* no valid short term buffers, delete one gap from the least start */
354         /* of gap sequence                                                  */
355         i4_gap_frame_num = pi4_gaps_start_frm_num[0];
356         i1_gap_idx = 0;
357 
358         for(i = 1; i < MAX_FRAMES; i++)
359         {
360             if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
361             {
362                 if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
363                 {
364                     i4_gap_frame_num = pi4_gaps_start_frm_num[i];
365                     i1_gap_idx = i;
366                 }
367             }
368         }
369         if(INVALID_FRAME_NUM == i4_gap_frame_num)
370         {
371             return ERROR_DBP_MANAGER_T;
372         }
373     }
374 
375     if(-1 != i1_gap_idx)
376     {
377         /* find least frame_num in the poc_map, which is in this range */
378         i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
379 
380         if(i4_start_frm_num < 0)
381         {
382             i4_start_frm_num += i4_max_pic_num;
383         }
384 
385         i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
386 
387         if(i4_end_frm_num < 0)
388         {
389             i4_end_frm_num += i4_max_pic_num;
390         }
391 
392         i4_gap_frm_num_min = INT32_MIN;
393         j_min = MAX_FRAMES;
394 
395         for(j = 0; j < MAX_FRAMES; j++)
396         {
397             i4_frm_num = ps_dpb_mgr->as_display_buf_info[j].i4_frame_num;
398 
399             if((i4_start_frm_num <= i4_frm_num) && (i4_end_frm_num >= i4_frm_num))
400             {
401                 if(i4_frm_num < i4_gap_frm_num_min)
402                 {
403                     j_min = j;
404                     i4_gap_frm_num_min = i4_frm_num;
405                 }
406             }
407         }
408 
409         if(j_min != MAX_FRAMES)
410         {
411             ps_dpb_mgr->as_display_buf_info[j_min].i4_poc_buf_id = -1;
412             ps_dpb_mgr->as_display_buf_info[j_min].i4_poc = 0x7fffffff;
413             ps_dpb_mgr->as_display_buf_info[j_min].i4_frame_num = GAP_FRAME_NUM;
414 
415             ps_dpb_mgr->i1_gaps_deleted++;
416             ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
417             ps_dpb_mgr->u1_num_gaps--;
418             *pu1_del_node = 0;
419 
420             if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
421             {
422                 ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = INVALID_FRAME_NUM;
423                 ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
424             }
425         }
426     }
427 
428     return OK;
429 }
430 
imvcd_dpb_do_mmco_for_gaps(mvc_dpb_manager_t * ps_dpb_mgr,UWORD8 u1_num_ref_frames)431 WORD32 imvcd_dpb_do_mmco_for_gaps(mvc_dpb_manager_t *ps_dpb_mgr, UWORD8 u1_num_ref_frames)
432 {
433     mvc_dpb_info_t *ps_next_dpb;
434 
435     WORD32 i;
436     WORD32 i4_error_code;
437     UWORD8 u1_num_gaps;
438     UWORD8 u1_num_st_ref_bufs, u1_num_lt_ref_bufs, u1_del_node;
439 
440     WORD32 i4_frame_gaps = 1;
441 
442     // Sliding window - implements 8.2.5.3, flush out buffers
443     u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
444     u1_num_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
445 
446     while(1)
447     {
448         u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
449 
450         if((u1_num_st_ref_bufs + u1_num_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) >
451            u1_num_ref_frames)
452         {
453             if(0 == (u1_num_st_ref_bufs + u1_num_gaps))
454             {
455                 i4_frame_gaps = 0;
456 
457                 ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames - u1_num_lt_ref_bufs);
458             }
459             else
460             {
461                 u1_del_node = 1;
462                 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
463 
464                 if(u1_num_st_ref_bufs > 1)
465                 {
466                     for(i = 1; i < (u1_num_st_ref_bufs - 1); i++)
467                     {
468                         if(ps_next_dpb == NULL)
469                         {
470                             return ERROR_DBP_MANAGER_T;
471                         }
472 
473                         ps_next_dpb = ps_next_dpb->ps_prev_short;
474                     }
475 
476                     if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
477                     {
478                         return ERROR_DBP_MANAGER_T;
479                     }
480 
481                     if(u1_num_gaps)
482                     {
483                         i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
484                             ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
485                             &u1_del_node);
486 
487                         if(i4_error_code != OK)
488                         {
489                             return i4_error_code;
490                         }
491                     }
492 
493                     if(u1_del_node)
494                     {
495                         u1_num_st_ref_bufs--;
496                         ps_next_dpb->ps_prev_short->b_used_as_ref = false;
497                         ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
498                         ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
499 
500                         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
501                                             ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
502                                             ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);
503 
504                         ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
505                         ps_next_dpb->ps_prev_short = NULL;
506                     }
507                 }
508                 else
509                 {
510                     if(u1_num_st_ref_bufs)
511                     {
512                         if(u1_num_gaps)
513                         {
514                             i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
515                                 ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);
516 
517                             if(i4_error_code != OK)
518                             {
519                                 return i4_error_code;
520                             }
521                         }
522 
523                         if(u1_del_node)
524                         {
525                             u1_num_st_ref_bufs--;
526                             ps_next_dpb->b_used_as_ref = false;
527                             ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
528                             ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
529 
530                             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
531                                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
532                                                 ps_next_dpb->ps_au_buf->i4_pic_buf_id);
533 
534                             ps_next_dpb->ps_au_buf = NULL;
535                             ps_next_dpb = NULL;
536                             ps_dpb_mgr->ps_dpb_st_head = NULL;
537                             ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;
538                         }
539                     }
540                     else
541                     {
542                         i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
543                             ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
544 
545                         if(i4_error_code != OK)
546                         {
547                             return i4_error_code;
548                         }
549 
550                         if(u1_del_node)
551                         {
552                             return ERROR_DBP_MANAGER_T;
553                         }
554                     }
555                 }
556             }
557         }
558         else
559         {
560             ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
561 
562             break;
563         }
564     }
565 
566     ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;
567 
568     return OK;
569 }
570 
imvcd_dpb_delete_nonref_nondisplay_pics(mvc_dpb_manager_t * ps_dpb_mgr)571 void imvcd_dpb_delete_nonref_nondisplay_pics(mvc_dpb_manager_t *ps_dpb_mgr)
572 {
573     WORD32 i;
574 
575     display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
576 
577     /* remove all gaps marked as unused for ref */
578     for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
579     {
580         if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
581         {
582             ps_dpb_mgr->i1_gaps_deleted--;
583             ps_dpb_mgr->i1_poc_buf_id_entries--;
584             ps_display_buf_info[i].i4_poc_buf_id = -1;
585             ps_display_buf_info[i].i4_poc = 0x7fffffff;
586             ps_display_buf_info[i].i4_frame_num = 0;
587         }
588     }
589 }
590 
imvcd_reset_dpb(mvc_dpb_manager_t * ps_dpb_mgr)591 void imvcd_reset_dpb(mvc_dpb_manager_t *ps_dpb_mgr)
592 {
593     WORD32 i;
594 
595     mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
596 
597     for(i = 0; i < MVC_MAX_REF_PICS; i++)
598     {
599         if(ps_dpb_info[i].b_used_as_ref)
600         {
601             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
602                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
603                                 ps_dpb_info[i].ps_au_buf->i4_pic_buf_id);
604 
605             ps_dpb_info[i].b_used_as_ref = false;
606             ps_dpb_info[i].ps_prev_short = NULL;
607             ps_dpb_info[i].ps_prev_long = NULL;
608             ps_dpb_info[i].ps_au_buf = NULL;
609             ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
610             ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
611             ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
612             ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
613         }
614     }
615 
616     ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
617     ps_dpb_mgr->ps_dpb_st_head = NULL;
618     ps_dpb_mgr->ps_dpb_lt_head = NULL;
619     ps_dpb_mgr->u1_mmco_error_in_seq = 0;
620 
621     /* release all gaps */
622     ps_dpb_mgr->u1_num_gaps = 0;
623 
624     for(i = 0; i < MAX_FRAMES; i++)
625     {
626         ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
627         ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
628         ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
629     }
630 }
631 
imvcd_dpb_release_display_bufs(mvc_dpb_manager_t * ps_dpb_mgr)632 void imvcd_dpb_release_display_bufs(mvc_dpb_manager_t *ps_dpb_mgr)
633 {
634     WORD32 i, j;
635 
636     display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
637 
638     WORD32 i4_min_poc = 0x7fffffff;
639     WORD32 i4_min_poc_buf_id = 0;
640     WORD32 i4_min_index = 0;
641 
642     imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
643 
644     for(j = 0; j < ps_dpb_mgr->i1_poc_buf_id_entries; j++)
645     {
646         i4_min_poc = 0x7fffffff;
647 
648         for(i = 0; i < MAX_FRAMES; i++)
649         {
650             if(ps_display_buf_info[i].i4_poc_buf_id != -1)
651             {
652                 /* Checking for <= is necessary to handle cases where there is one
653                    valid buffer with poc set to 0x7FFFFFFF. */
654                 if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
655                 {
656                     i4_min_poc = ps_display_buf_info[i].i4_poc;
657                     i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
658                     i4_min_index = i;
659                 }
660             }
661         }
662 
663         if(DO_NOT_DISP != i4_min_poc_buf_id)
664         {
665             ps_dpb_mgr->i4_cur_display_seq++;
666 
667             ih264_disp_mgr_add(
668                 ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
669                 ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);
670 
671             ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
672             ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
673             ps_display_buf_info[i4_min_index].i4_frame_num = 0;
674         }
675         else
676         {
677             ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
678             ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
679             ps_display_buf_info[i4_min_index].i4_frame_num = 0;
680         }
681     }
682 
683     ps_dpb_mgr->i1_poc_buf_id_entries = 0;
684 }
685 
imvcd_assign_pic_num(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_max_frame_num,WORD32 i4_cur_frame_num,bool b_are_gaps_in_frame_num_value_allowed)686 void imvcd_assign_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_frame_num,
687                           WORD32 i4_cur_frame_num, bool b_are_gaps_in_frame_num_value_allowed)
688 {
689     mvc_dpb_info_t *ps_next_dpb;
690 
691     WORD32 i;
692     WORD32 i4_ref_frame_num;
693 
694     /* Start from ST head */
695     ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
696 
697     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
698     {
699         WORD32 i4_pic_num;
700 
701         i4_ref_frame_num = ps_next_dpb->ps_au_buf->i4_pic_num;
702 
703         if(i4_ref_frame_num > i4_cur_frame_num)
704         {
705             i4_pic_num = i4_ref_frame_num - i4_max_frame_num;
706         }
707         else
708         {
709             i4_pic_num = i4_ref_frame_num;
710         }
711 
712         ps_next_dpb->ps_au_buf->i4_pic_num = i4_pic_num;
713 
714         ps_next_dpb = ps_next_dpb->ps_prev_short;
715     }
716 
717     if(b_are_gaps_in_frame_num_value_allowed && ps_dpb_mgr->u1_num_gaps)
718     {
719         WORD32 i4_start_frm, i4_end_frm;
720 
721         /* Assign pic numbers for gaps */
722         for(i = 0; i < MAX_FRAMES; i++)
723         {
724             i4_start_frm = ps_dpb_mgr->ai4_gaps_start_frm_num[i];
725 
726             if(i4_start_frm != INVALID_FRAME_NUM)
727             {
728                 if(i4_start_frm > i4_cur_frame_num)
729                 {
730                     /* gap's frame_num is before Current frame_num in
731                      decode order */
732                     i4_start_frm -= i4_max_frame_num;
733                 }
734 
735                 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = i4_start_frm;
736                 i4_end_frm = ps_dpb_mgr->ai4_gaps_end_frm_num[i];
737 
738                 if(i4_end_frm > i4_cur_frame_num)
739                 {
740                     /* gap's frame_num is before Current frame_num in
741                      decode order */
742                     i4_end_frm -= i4_max_frame_num;
743                 }
744 
745                 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = i4_end_frm;
746             }
747         }
748     }
749 }
750 
751 /* If there is common node in both lt_list and st_list, then delete it from */
752 /* st_list */
imvcd_dpb_st_lt_deduplicator(mvc_dpb_manager_t * ps_dpb_mgr)753 UWORD8 imvcd_dpb_st_lt_deduplicator(mvc_dpb_manager_t *ps_dpb_mgr)
754 {
755     mvc_dpb_info_t *ps_dpb_lt_head = ps_dpb_mgr->ps_dpb_lt_head;
756     mvc_dpb_info_t *ps_lt_curr_dpb = ps_dpb_mgr->ps_dpb_lt_head;
757     mvc_dpb_info_t *ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head;
758 
759     UWORD8 u1_no_of_nodes_deleted = 0;
760     UWORD8 u1_num_lt_refs = ps_dpb_mgr->u1_num_lt_ref_bufs;
761     UWORD8 u1_num_st_refs = ps_dpb_mgr->u1_num_st_ref_bufs;
762 
763     while(u1_num_lt_refs && ps_dpb_lt_head)
764     {
765         if(ps_dpb_st_head &&
766            ((ps_dpb_lt_head->s_bot_field.u1_reference_info |
767              ps_dpb_lt_head->s_top_field.u1_reference_info) == (IS_SHORT_TERM | IS_LONG_TERM)))
768         {
769             mvc_dpb_info_t *ps_st_next_dpb = ps_dpb_st_head;
770             mvc_dpb_info_t *ps_st_curr_dpb = ps_dpb_st_head;
771 
772             while(u1_num_st_refs && ps_st_curr_dpb)
773             {
774                 if(ps_st_curr_dpb == ps_lt_curr_dpb)
775                 {
776                     if(u1_num_st_refs == ps_dpb_mgr->u1_num_st_ref_bufs)
777                     {
778                         ps_dpb_mgr->ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head->ps_prev_short;
779                         ps_st_curr_dpb = ps_dpb_mgr->ps_dpb_st_head;
780                     }
781                     else
782                     {
783                         ps_st_next_dpb->ps_prev_short = ps_st_curr_dpb->ps_prev_short;
784                     }
785 
786                     ps_dpb_mgr->u1_num_st_ref_bufs--;
787                     u1_no_of_nodes_deleted++;
788 
789                     break;
790                 }
791 
792                 ps_st_next_dpb = ps_st_curr_dpb;
793                 ps_st_curr_dpb = ps_st_curr_dpb->ps_prev_short;
794                 u1_num_st_refs--;
795             }
796         }
797 
798         ps_lt_curr_dpb = ps_lt_curr_dpb->ps_prev_long;
799         u1_num_lt_refs--;
800     }
801 
802     return u1_no_of_nodes_deleted;
803 }
804 
qsort_pic_num_compare(const void * pv_au1,const void * pv_au2)805 static int qsort_pic_num_compare(const void *pv_au1, const void *pv_au2)
806 {
807     return ((mvc_au_buffer_t **) pv_au1)[0]->i4_pic_num -
808            ((mvc_au_buffer_t **) pv_au2)[0]->i4_pic_num;
809 }
810 
qsort_poc_compare(const void * pv_au1,const void * pv_au2)811 static int qsort_poc_compare(const void *pv_au1, const void *pv_au2)
812 {
813     return ((mvc_au_buffer_t **) pv_au1)[0]->i4_poc - ((mvc_au_buffer_t **) pv_au2)[0]->i4_poc;
814 }
815 
qsort_lt_idx_compare(const void * pv_au1,const void * pv_au2)816 static int qsort_lt_idx_compare(const void *pv_au1, const void *pv_au2)
817 {
818     return ((mvc_au_buffer_t **) pv_au1)[0]->u1_long_term_frm_idx -
819            ((mvc_au_buffer_t **) pv_au2)[0]->u1_long_term_frm_idx;
820 }
821 
imvcd_init_ref_pic_list(mvc_dpb_manager_t * ps_dpb_mgr,nalu_mvc_ext_t * ps_cur_nalu_mvc_ext,mvc_au_buffer_t * ps_cur_au,UWORD16 u2_view_order_id)822 WORD32 imvcd_init_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
823                                mvc_au_buffer_t *ps_cur_au, UWORD16 u2_view_order_id)
824 {
825     mvc_dpb_info_t *ps_ref_au_data;
826     mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;
827 
828     WORD32 i, j;
829 
830     mvc_au_buffer_t *aps_st_au_bufs[MVC_MAX_REF_PICS] = {NULL};
831     mvc_au_buffer_t *aps_lt_au_bufs[MVC_MAX_REF_PICS] = {NULL};
832     mvc_au_buffer_t *aps_ref_pic_buf_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
833                                               ps_dpb_mgr->as_init_dpb[1]};
834     sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;
835 
836     UWORD16 u2_view_id = ps_cur_nalu_mvc_ext->u2_view_id;
837     WORD32 i4_cur_poc = ps_cur_au->i4_poc;
838     bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
839     UWORD8 *pu1_num_short_term_refs = ps_dpb_mgr->au1_num_active_st_refs;
840     UWORD8 *pu1_num_long_term_refs = ps_dpb_mgr->au1_num_active_lt_refs;
841     UWORD8 au1_total_num_refs[2] = {0};
842 
843     memset(pu1_num_short_term_refs, 0, 2 * sizeof(pu1_num_short_term_refs[0]));
844 
845     memset(pu1_num_long_term_refs, 0, 2 * sizeof(pu1_num_long_term_refs[0]));
846 
847     ps_ref_au_data = ps_dpb_mgr->ps_dpb_st_head;
848 
849     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
850     {
851         aps_st_au_bufs[i] = ps_ref_au_data->ps_au_buf;
852         ps_ref_au_data = ps_ref_au_data->ps_prev_short;
853     }
854 
855     qsort(aps_st_au_bufs, ps_dpb_mgr->u1_num_st_ref_bufs, sizeof(aps_st_au_bufs[0]),
856           b_is_b_pic ? qsort_poc_compare : qsort_pic_num_compare);
857 
858     ps_ref_au_data = ps_dpb_mgr->ps_dpb_lt_head;
859 
860     for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
861     {
862         aps_lt_au_bufs[i] = ps_ref_au_data->ps_au_buf;
863         ps_ref_au_data = ps_ref_au_data->ps_prev_long;
864     }
865 
866     qsort(aps_lt_au_bufs, ps_dpb_mgr->u1_num_lt_ref_bufs, sizeof(aps_lt_au_bufs[0]),
867           qsort_lt_idx_compare);
868 
869     if(b_is_b_pic)
870     {
871         for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
872         {
873             if(aps_st_au_bufs[i]->i4_poc >= i4_cur_poc)
874             {
875                 break;
876             }
877         }
878 
879         for(j = i - 1; j >= 0; j--)
880         {
881             aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[j][0];
882             aps_ref_pic_buf_lx[0]++;
883             pu1_num_short_term_refs[0]++;
884         }
885 
886         for(j = i; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
887         {
888             aps_ref_pic_buf_lx[1][0] = aps_st_au_bufs[j][0];
889             aps_ref_pic_buf_lx[1]++;
890             pu1_num_short_term_refs[1]++;
891         }
892     }
893     else
894     {
895         for(i = ps_dpb_mgr->u1_num_st_ref_bufs - 1; i >= 0; i--)
896         {
897             aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[i][0];
898             aps_ref_pic_buf_lx[0]++;
899             pu1_num_short_term_refs[0]++;
900         }
901     }
902 
903     for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
904     {
905         for(j = 0; j < 1 + ((WORD32) b_is_b_pic); j++)
906         {
907             aps_ref_pic_buf_lx[j][0] = aps_lt_au_bufs[i][0];
908             aps_ref_pic_buf_lx[j]->u1_long_term_pic_num =
909                 aps_ref_pic_buf_lx[j]->u1_long_term_frm_idx;
910             aps_ref_pic_buf_lx[j]++;
911             pu1_num_long_term_refs[j]++;
912         }
913     }
914 
915     if(0 != u2_view_order_id)
916     {
917         ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
918 
919         for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
920         {
921             WORD32 i4_num_refs;
922 
923             if(ps_cur_nalu_mvc_ext->u1_anchor_pic_flag)
924             {
925                 ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id];
926             }
927             else
928             {
929                 ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id];
930             }
931 
932             i4_num_refs = ps_mvc_ivp_ref_data->u1_num_refs;
933 
934             for(j = 0; j < i4_num_refs; j++)
935             {
936                 mvc_au_buffer_t *ps_au_buf;
937                 mvc_au_mv_pred_t *ps_au_mv_data;
938                 nalu_mvc_ext_t *ps_ref_nalu_mvc_ext;
939 
940                 WORD32 i4_pic_buf_id;
941                 WORD32 i4_mv_buf_id;
942 
943                 UWORD16 u2_ref_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[j];
944 
945                 ps_ref_nalu_mvc_ext = imvcd_get_nalu_mvc_ext(
946                     ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts, u2_view_order_id, u2_ref_view_id);
947 
948                 if(!ps_ref_nalu_mvc_ext->u1_inter_view_flag)
949                 {
950                     continue;
951                 }
952 
953                 ps_au_buf = ih264_buf_mgr_get_next_free(
954                     ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt, &i4_pic_buf_id);
955 
956                 if(NULL == ps_au_buf)
957                 {
958                     return ERROR_UNAVAIL_PICBUF_T;
959                 }
960                 else
961                 {
962                     ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
963                                              i4_pic_buf_id, BUF_MGR_REF);
964                 }
965 
966                 ps_au_mv_data = ih264_buf_mgr_get_next_free(
967                     ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt, &i4_mv_buf_id);
968 
969                 if(NULL == ps_au_mv_data)
970                 {
971                     return ERROR_UNAVAIL_PICBUF_T;
972                 }
973                 else
974                 {
975                     ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
976                                              i4_mv_buf_id, BUF_MGR_REF);
977                 }
978 
979                 ps_au_buf->i4_pic_buf_id = i4_pic_buf_id;
980                 ps_au_buf->i4_mv_buf_id = i4_mv_buf_id;
981                 ps_au_buf->s_ivp_data.b_is_ivp_ref = true;
982                 ps_au_buf->s_ivp_data.u2_ref_view_id = u2_ref_view_id;
983 
984                 imvcd_ivp_buf_copier(ps_cur_au, ps_au_buf, ps_cur_au->ps_au_mv_data, ps_au_mv_data,
985                                      u2_ref_view_id, u2_view_id);
986 
987                 ps_dpb_mgr->ps_mvc_au_buf_mgr->au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id] =
988                     i4_mv_buf_id;
989                 ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_pic_buf_id] = ps_au_buf;
990                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->aps_buf_id_to_mv_pred_buf_map[i4_mv_buf_id] =
991                     ps_au_mv_data;
992 
993                 ps_dpb_mgr->s_dpb_ivp_ctxt
994                     .au1_au_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_pic_buf_id;
995                 ps_dpb_mgr->s_dpb_ivp_ctxt
996                     .au1_mv_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_mv_buf_id;
997 
998                 aps_ref_pic_buf_lx[i][0] = ps_au_buf[0];
999 
1000                 aps_ref_pic_buf_lx[i]++;
1001                 pu1_num_short_term_refs[i]++;
1002                 ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs++;
1003             }
1004         }
1005     }
1006 
1007     for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
1008     {
1009         au1_total_num_refs[i] = pu1_num_short_term_refs[i] + pu1_num_long_term_refs[i];
1010 
1011         if(pu1_num_short_term_refs[i] > MVC_MAX_REF_PICS)
1012         {
1013             return ERROR_NUM_REF;
1014         }
1015 
1016         if(au1_total_num_refs[i] > MVC_MAX_REF_PICS)
1017         {
1018             return ERROR_NUM_REF;
1019         }
1020 
1021         if(0 == au1_total_num_refs[i])
1022         {
1023             return ERROR_NUM_REF;
1024         }
1025     }
1026 
1027     /* If list0 and list1 entries are same then swap the 0th and 1st entry */
1028     /* of list 1 */
1029     {
1030         mvc_au_buffer_t *aps_ref_pic_bufs_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
1031                                                    ps_dpb_mgr->as_init_dpb[1]};
1032 
1033         if((au1_total_num_refs[0] == au1_total_num_refs[1]) && (au1_total_num_refs[0] > 1))
1034         {
1035             bool b_swap;
1036 
1037             b_swap = true;
1038 
1039             for(i = 0; i < au1_total_num_refs[0]; i++)
1040             {
1041                 if(aps_ref_pic_bufs_lx[0][i]
1042                        .as_view_buffers[u2_view_id]
1043                        .as_component_bufs[Y]
1044                        .pv_data != aps_ref_pic_bufs_lx[1][i]
1045                                        .as_view_buffers[u2_view_id]
1046                                        .as_component_bufs[Y]
1047                                        .pv_data)
1048                 {
1049                     b_swap = false;
1050 
1051                     break;
1052                 }
1053             }
1054 
1055             if(b_swap)
1056             {
1057                 SWAP(aps_ref_pic_bufs_lx[1][0], aps_ref_pic_bufs_lx[1][1], mvc_au_buffer_t);
1058             }
1059         }
1060     }
1061 
1062     return OK;
1063 }
1064 
imvcd_dpb_set_missing_refs_to_default(mvc_dpb_manager_t * ps_dpb_mgr,ref_pic_list_mod_data_t * ps_ref_pic_list_mod_data,mvc_au_buffer_t * ps_cur_au,UWORD8 u1_pred_lx)1065 void imvcd_dpb_set_missing_refs_to_default(mvc_dpb_manager_t *ps_dpb_mgr,
1066                                            ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
1067                                            mvc_au_buffer_t *ps_cur_au, UWORD8 u1_pred_lx)
1068 {
1069     UWORD8 u1_num_refs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
1070                          ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];
1071 
1072     while(u1_num_refs < ps_ref_pic_list_mod_data->au1_num_active_refs[u1_pred_lx])
1073     {
1074         ps_dpb_mgr->as_init_dpb[u1_pred_lx][u1_num_refs] = ps_cur_au[0];
1075         ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx]++;
1076         u1_num_refs++;
1077     }
1078 }
1079 
imvcd_dpb_normalise_ref_pic_list(mvc_dpb_manager_t * ps_dpb_mgr,UWORD16 u2_buf_mod_bitfield,UWORD8 u1_num_bufs_modified,UWORD8 u1_pred_lx)1080 void imvcd_dpb_normalise_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_buf_mod_bitfield,
1081                                       UWORD8 u1_num_bufs_modified, UWORD8 u1_pred_lx)
1082 {
1083     WORD32 i;
1084 
1085     UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
1086                              ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];
1087 
1088     for(i = 0; i < u1_num_ref_bufs; i++)
1089     {
1090         if(u1_num_bufs_modified >= MVC_MAX_REF_PICS)
1091         {
1092             return;
1093         }
1094 
1095         if(!(u2_buf_mod_bitfield & (1 << i)))
1096         {
1097             ps_dpb_mgr->aps_mod_dpb[u1_pred_lx][u1_num_bufs_modified++] =
1098                 &ps_dpb_mgr->as_init_dpb[u1_pred_lx][i];
1099         }
1100     }
1101 }
1102 
imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t * ps_dpb_mgr,nalu_mvc_ext_t * ps_cur_nalu_mvc_ext,mvc_au_buffer_t * ps_cur_au,ref_pic_list_mod_data_t * ps_ref_pic_list_mod_data,UWORD16 u2_view_order_id)1103 WORD32 imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
1104                                       nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
1105                                       mvc_au_buffer_t *ps_cur_au,
1106                                       ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
1107                                       UWORD16 u2_view_order_id)
1108 {
1109     WORD32 i, j;
1110 
1111     sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;
1112 
1113     UWORD8 u1_anchor_pic_flag = ps_cur_nalu_mvc_ext->u1_anchor_pic_flag;
1114     WORD32 i4_cur_pic_num = ps_cur_au->i4_pic_num;
1115     WORD32 i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
1116     bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
1117 
1118     for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
1119     {
1120         mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;
1121 
1122         UWORD16 u2_max_view_idx;
1123 
1124         WORD32 i4_pred_pic_num = i4_cur_pic_num;
1125         WORD16 i2_pred_view_order_id = 0;  // -1; Need to check spec and JMVM implementation match
1126         UWORD8 *pu1_modification_of_pic_nums_idc =
1127             ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i];
1128         WORD32 *pi4_abs_diff_pic_num_minus1 =
1129             ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i];
1130         WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i];
1131         WORD32 *pi4_abs_diff_view_idx_minus1 =
1132             ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i];
1133         UWORD8 u1_num_ref_bufs =
1134             ps_dpb_mgr->au1_num_active_st_refs[i] + ps_dpb_mgr->au1_num_active_lt_refs[i];
1135         UWORD16 u2_buf_mod_bitfield = 0;
1136         UWORD8 u1_num_bufs_modified = 0;
1137 
1138         if(!ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i] ||
1139            (3 == pu1_modification_of_pic_nums_idc[0]))
1140         {
1141             imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au,
1142                                                   i);
1143 
1144             imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified,
1145                                              i);
1146 
1147             continue;
1148         }
1149 
1150         ps_mvc_ivp_ref_data =
1151             (0 == u2_view_order_id)
1152                 ? NULL
1153                 : (u1_anchor_pic_flag
1154                        ? &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id]
1155                        : &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id]);
1156         u2_max_view_idx = (0 == u2_view_order_id) ? 0 : ps_mvc_ivp_ref_data->u1_num_refs;
1157 
1158         do
1159         {
1160             if((0 == pu1_modification_of_pic_nums_idc[0]) ||
1161                (1 == pu1_modification_of_pic_nums_idc[0]))
1162             {
1163                 WORD32 i4_mod_pic_num = pi4_abs_diff_pic_num_minus1[0];
1164 
1165                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1166 
1167                 /* According to section 7.4.3.1 from spec, */
1168                 /* this value is expected to be from the */
1169                 /* closed interval [0, i4_max_pic_num - 1] */
1170                 if((i4_mod_pic_num < 0) || (i4_mod_pic_num >= i4_max_pic_num))
1171                 {
1172                     return ERROR_DBP_MANAGER_T;
1173                 }
1174 
1175                 /* +1 not accounted during initialisation, */
1176                 /* mainly to preclude integer overflow */
1177                 i4_mod_pic_num++;
1178 
1179                 if(0 == pu1_modification_of_pic_nums_idc[0])
1180                 {
1181                     i4_mod_pic_num = i4_pred_pic_num - i4_mod_pic_num;
1182 
1183                     if(i4_mod_pic_num < 0)
1184                     {
1185                         i4_mod_pic_num += i4_max_pic_num;
1186                     }
1187                 }
1188                 else
1189                 {
1190                     i4_mod_pic_num = i4_pred_pic_num + i4_mod_pic_num;
1191 
1192                     if(i4_mod_pic_num >= i4_max_pic_num)
1193                     {
1194                         i4_mod_pic_num -= i4_max_pic_num;
1195                     }
1196                 }
1197 
1198                 if(i4_mod_pic_num > i4_cur_pic_num)
1199                 {
1200                     i4_mod_pic_num -= i4_max_pic_num;
1201                 }
1202 
1203                 for(j = 0; j < u1_num_ref_bufs; j++)
1204                 {
1205                     if(ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_mod_pic_num)
1206                     {
1207                         u1_mod_buf_idx = j;
1208 
1209                         break;
1210                     }
1211                 }
1212 
1213                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1214                 {
1215                     return ERROR_DBP_MANAGER_T;
1216                 }
1217 
1218                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1219                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1220 
1221                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1222                 i4_pred_pic_num = i4_mod_pic_num;
1223             }
1224             else if(2 == pu1_modification_of_pic_nums_idc[0])
1225             {
1226                 WORD32 i4_mod_lt_pic_num = pi4_long_term_pic_num[0];
1227                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1228 
1229                 if(pi4_long_term_pic_num[0] > (MAX_REF_BUFS + 1))
1230                 {
1231                     return ERROR_DBP_MANAGER_T;
1232                 }
1233 
1234                 for(j = 0; j < u1_num_ref_bufs; j++)
1235                 {
1236                     if(!ps_dpb_mgr->as_init_dpb[i][j].b_is_short_term_ref &&
1237                        (i4_mod_lt_pic_num == ps_dpb_mgr->as_init_dpb[i][j].u1_long_term_pic_num))
1238                     {
1239                         u1_mod_buf_idx = j;
1240 
1241                         break;
1242                     }
1243                 }
1244 
1245                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1246                 {
1247                     return ERROR_DBP_MANAGER_T;
1248                 }
1249 
1250                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1251                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1252 
1253                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1254             }
1255             else if((4 == pu1_modification_of_pic_nums_idc[0]) ||
1256                     (5 == pu1_modification_of_pic_nums_idc[0]))
1257             {
1258                 WORD32 i4_target_view_id;
1259 
1260                 WORD32 i4_mod_view_order_id = pi4_abs_diff_view_idx_minus1[0];
1261                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1262 
1263                 /* According to section H.7.4.3.1.1 from spec, */
1264                 /* this value is expected to be from the */
1265                 /* closed interval [0, u2_max_view_idx - 1] */
1266                 if((i4_mod_view_order_id < 0) || (i4_mod_view_order_id >= u2_max_view_idx))
1267                 {
1268                     return ERROR_DBP_MANAGER_T;
1269                 }
1270 
1271                 /* +1 not accounted during initialisation, */
1272                 /* mainly to preclude integer overflow */
1273                 i4_mod_view_order_id++;
1274 
1275                 if(4 == pu1_modification_of_pic_nums_idc[0])
1276                 {
1277                     i4_mod_view_order_id = i2_pred_view_order_id - i4_mod_view_order_id;
1278 
1279                     if(i4_mod_view_order_id < 0)
1280                     {
1281                         i4_mod_view_order_id += u2_max_view_idx;
1282                     }
1283                 }
1284                 else
1285                 {
1286                     i4_mod_view_order_id = i2_pred_view_order_id + i4_mod_view_order_id;
1287 
1288                     if(i4_mod_view_order_id >= u2_max_view_idx)
1289                     {
1290                         i4_mod_view_order_id -= u2_max_view_idx;
1291                     }
1292                 }
1293 
1294                 if((0 == u2_view_order_id) || (NULL == ps_mvc_ivp_ref_data))
1295                 {
1296                     return ERROR_DBP_MANAGER_T;
1297                 }
1298 
1299                 i4_target_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[i4_mod_view_order_id];
1300 
1301                 for(j = 0; j < u1_num_ref_bufs; j++)
1302                 {
1303                     if(ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.b_is_ivp_ref)
1304                     {
1305                         if((ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_cur_pic_num) &&
1306                            (ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.u2_ref_view_id ==
1307                             i4_target_view_id))
1308                         {
1309                             u1_mod_buf_idx = j;
1310 
1311                             break;
1312                         }
1313                     }
1314                 }
1315 
1316                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1317                 {
1318                     return ERROR_DBP_MANAGER_T;
1319                 }
1320 
1321                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1322                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1323                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1324                 i2_pred_view_order_id = i4_mod_view_order_id;
1325             }
1326             else if(3 != pu1_modification_of_pic_nums_idc[0])
1327             {
1328                 return ERROR_REFIDX_ORDER_T;
1329             }
1330             else
1331             {
1332                 break;
1333             }
1334 
1335             pu1_modification_of_pic_nums_idc++;
1336             pi4_abs_diff_pic_num_minus1++;
1337             pi4_long_term_pic_num++;
1338             pi4_abs_diff_view_idx_minus1++;
1339         } while(true);
1340 
1341         imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au, i);
1342 
1343         imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified, i);
1344     }
1345 
1346     return OK;
1347 }
1348 
imvcd_dpb_insert_st_node(mvc_dpb_manager_t * ps_dpb_mgr,mvc_au_buffer_t * ps_au_buf)1349 WORD32 imvcd_dpb_insert_st_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_au_buf)
1350 {
1351     WORD32 i;
1352 
1353     mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
1354     UWORD8 u1_picture_type = ps_au_buf->u1_picturetype;
1355 
1356     for(i = 0; i < MVC_MAX_REF_PICS; i++)
1357     {
1358         if((ps_dpb_info[i].ps_au_buf == ps_au_buf) && ps_dpb_info[i].b_used_as_ref)
1359         {
1360             /* Can occur only for field bottom pictures */
1361             if(ps_dpb_info[i].ps_au_buf->u1_pic_type == FRM_PIC)
1362             {
1363                 return ERROR_DBP_MANAGER_T;
1364             }
1365             else
1366             {
1367                 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1368 
1369                 return OK;
1370             }
1371         }
1372 
1373         if(!ps_dpb_info[i].b_used_as_ref &&
1374            (ps_dpb_info[i].s_top_field.u1_reference_info == UNUSED_FOR_REF) &&
1375            (ps_dpb_info[i].s_bot_field.u1_reference_info == UNUSED_FOR_REF))
1376         {
1377             break;
1378         }
1379     }
1380 
1381     if(i == MVC_MAX_REF_PICS)
1382     {
1383         return ERROR_DBP_MANAGER_T;
1384     }
1385 
1386     ps_dpb_info[i].ps_au_buf = ps_au_buf;
1387     ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
1388     ps_dpb_info[i].b_used_as_ref = true;
1389 
1390     ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
1391 
1392     ps_dpb_mgr->u1_num_st_ref_bufs++;
1393 
1394     ps_au_buf->b_is_short_term_ref = true;
1395 
1396     if((u1_picture_type & 0x03) == FRM_PIC)
1397     {
1398         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
1399         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1400     }
1401     else if((u1_picture_type & 0x03) == TOP_FLD)
1402     {
1403         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
1404     }
1405     else if((u1_picture_type & 0x03) == BOT_FLD)
1406     {
1407         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1408     }
1409 
1410     return OK;
1411 }
1412 
imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_frame_num,UWORD8 * pu1_del_node)1413 static WORD32 imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_frame_num,
1414                                             UWORD8 *pu1_del_node)
1415 {
1416     WORD8 i, j;
1417     WORD32 *pi4_start, *pi4_end;
1418     WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_pic_num;
1419 
1420     /* find the least frame num from gaps and current DPB node    */
1421     /* Delete the gaps                                            */
1422     *pu1_del_node = 1;
1423     pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
1424     pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
1425     i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
1426 
1427     if(0 == ps_dpb_mgr->u1_num_gaps)
1428     {
1429         return OK;
1430     }
1431 
1432     if(i4_frame_num < 0)
1433     {
1434         i4_frame_num += i4_max_pic_num;
1435     }
1436 
1437     for(i = 0; i < MAX_FRAMES; i++)
1438     {
1439         i4_start_frm_num = pi4_start[i];
1440 
1441         if(i4_start_frm_num < 0)
1442         {
1443             i4_start_frm_num += i4_max_pic_num;
1444         }
1445 
1446         if(INVALID_FRAME_NUM != i4_start_frm_num)
1447         {
1448             i4_end_frm_num = pi4_end[i];
1449 
1450             if(i4_end_frm_num < 0)
1451             {
1452                 i4_end_frm_num += i4_max_pic_num;
1453             }
1454 
1455             if((i4_frame_num >= i4_start_frm_num) && (i4_frame_num <= i4_end_frm_num))
1456             {
1457                 break;
1458             }
1459             else
1460             {
1461                 if(((i4_frame_num + i4_max_pic_num) >= i4_start_frm_num) &&
1462                    ((i4_frame_num + i4_max_pic_num) <= i4_end_frm_num))
1463                 {
1464                     return ERROR_DBP_MANAGER_T;
1465                 }
1466             }
1467         }
1468     }
1469 
1470     /* find frame_num index, in the poc_map which needs to be deleted */
1471     for(j = 0; j < MAX_FRAMES; j++)
1472     {
1473         if(i4_frame_num == ps_dpb_mgr->as_display_buf_info[j].i4_frame_num)
1474         {
1475             break;
1476         }
1477     }
1478 
1479     if(MAX_FRAMES != i)
1480     {
1481         if(j == MAX_FRAMES)
1482         {
1483             return ERROR_DBP_MANAGER_T;
1484         }
1485 
1486         ps_dpb_mgr->as_display_buf_info[j].i4_poc_buf_id = -1;
1487         ps_dpb_mgr->as_display_buf_info[j].i4_poc = 0x7fffffff;
1488         ps_dpb_mgr->as_display_buf_info[j].i4_frame_num = GAP_FRAME_NUM;
1489 
1490         ps_dpb_mgr->i1_gaps_deleted++;
1491         ps_dpb_mgr->ai1_gaps_per_seq[i]--;
1492         ps_dpb_mgr->u1_num_gaps--;
1493         *pu1_del_node = 0;
1494 
1495         if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
1496         {
1497             ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
1498             ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
1499         }
1500     }
1501     else
1502     {
1503         return ERROR_DBP_MANAGER_T;
1504     }
1505 
1506     return OK;
1507 }
1508 
imvcd_dpb_insert_lt_node(mvc_dpb_manager_t * ps_dpb_mgr,mvc_dpb_info_t * ps_new_node,UWORD32 u4_lt_idx)1509 static WORD32 imvcd_dpb_insert_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_dpb_info_t *ps_new_node,
1510                                        UWORD32 u4_lt_idx)
1511 {
1512     ps_new_node->s_top_field.u1_reference_info = IS_LONG_TERM;
1513     ps_new_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
1514     ps_new_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
1515     ps_new_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
1516     ps_new_node->ps_au_buf->u1_long_term_frm_idx = u4_lt_idx;
1517     ps_new_node->b_used_as_ref = true;
1518 
1519     if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
1520     {
1521         WORD32 i;
1522 
1523         mvc_dpb_info_t **pps_next_node = &ps_dpb_mgr->ps_dpb_lt_head;
1524 
1525         for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
1526         {
1527             if((*pps_next_node)->ps_au_buf->u1_long_term_frm_idx > u4_lt_idx)
1528             {
1529                 ps_new_node->ps_prev_long = *pps_next_node;
1530                 *pps_next_node = ps_new_node;
1531 
1532                 break;
1533             }
1534             else if(NULL == (*pps_next_node)->ps_prev_long)
1535             {
1536                 (*pps_next_node)->ps_prev_long = ps_new_node;
1537                 ps_new_node->ps_prev_long = NULL;
1538 
1539                 break;
1540             }
1541 
1542             pps_next_node = &(*pps_next_node)->ps_prev_long;
1543         }
1544     }
1545     else
1546     {
1547         ps_dpb_mgr->ps_dpb_lt_head = ps_new_node;
1548         ps_new_node->ps_prev_long = NULL;
1549     }
1550 
1551     ps_new_node->ps_au_buf->b_is_short_term_ref = false;
1552 
1553     ps_dpb_mgr->u1_num_lt_ref_bufs++;
1554 
1555     return OK;
1556 }
1557 
imvcd_dpb_delete_lt_node(mvc_dpb_manager_t * ps_dpb_mgr,UWORD32 u4_lt_idx)1558 static WORD32 imvcd_dpb_delete_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, UWORD32 u4_lt_idx)
1559 {
1560     mvc_dpb_info_t *ps_next_dpb;
1561     mvc_dpb_info_t *ps_unmark_node;
1562 
1563     WORD32 i;
1564 
1565     if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
1566     {
1567         ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
1568 
1569         if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
1570         {
1571             ps_unmark_node = ps_next_dpb;
1572         }
1573         else
1574         {
1575             for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
1576             {
1577                 if(ps_next_dpb->ps_prev_long->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
1578                 {
1579                     break;
1580                 }
1581 
1582                 ps_next_dpb = ps_next_dpb->ps_prev_long;
1583             }
1584 
1585             if(i < ps_dpb_mgr->u1_num_lt_ref_bufs)
1586             {
1587                 ps_unmark_node = ps_next_dpb->ps_prev_long;
1588             }
1589             else
1590             {
1591                 return OK;
1592             }
1593         }
1594 
1595         ps_unmark_node->b_used_as_ref = false;
1596 
1597         if(ps_unmark_node == ps_dpb_mgr->ps_dpb_lt_head)
1598         {
1599             ps_dpb_mgr->ps_dpb_lt_head = ps_next_dpb->ps_prev_long;
1600         }
1601 
1602         ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1603         ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1604 
1605         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr, ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1606                             ps_unmark_node->ps_au_buf->i4_pic_buf_id);
1607 
1608         ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long;
1609         ps_unmark_node->ps_prev_long = NULL;
1610         ps_dpb_mgr->u1_num_lt_ref_bufs--;
1611     }
1612 
1613     return OK;
1614 }
1615 
imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_pic_num,UWORD32 u4_lt_idx)1616 WORD32 imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
1617                                            UWORD32 u4_lt_idx)
1618 {
1619     WORD32 i4_error_code;
1620 
1621     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1622     mvc_dpb_info_t *ps_unmark_node = NULL;
1623 
1624     UWORD8 u1_del_node = 0, u1_del_st = 0;
1625     WORD32 i = 0;
1626 
1627     if(ps_next_dpb->ps_au_buf->i4_pic_num == i4_pic_num)
1628     {
1629         ps_unmark_node = ps_next_dpb;
1630     }
1631     else
1632     {
1633         for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
1634         {
1635             if(ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num == i4_pic_num)
1636             {
1637                 ps_unmark_node = ps_next_dpb->ps_prev_short;
1638 
1639                 break;
1640             }
1641 
1642             ps_next_dpb = ps_next_dpb->ps_prev_short;
1643         }
1644     }
1645 
1646     if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
1647     {
1648         if(ps_dpb_mgr->u1_num_gaps)
1649         {
1650             i4_error_code = imvcd_dpb_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_del_st);
1651 
1652             if(i4_error_code != OK)
1653             {
1654                 return i4_error_code;
1655             }
1656         }
1657         else
1658         {
1659             return ERROR_DBP_MANAGER_T;
1660         }
1661 
1662         if(u1_del_st)
1663         {
1664             return ERROR_DBP_MANAGER_T;
1665         }
1666         else
1667         {
1668             return 0;
1669         }
1670     }
1671 
1672     ps_unmark_node->b_used_as_ref = false;
1673     ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1674     ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1675 
1676     if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
1677     {
1678         ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
1679     }
1680     else
1681     {
1682         ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short;
1683     }
1684 
1685     ps_dpb_mgr->u1_num_st_ref_bufs--;
1686     u1_del_node = 1;
1687 
1688     if(u4_lt_idx == (MAX_REF_BUFS + 1))
1689     {
1690         if(u1_del_node)
1691         {
1692             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1693                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1694                                 ps_unmark_node->ps_au_buf->i4_pic_buf_id);
1695 
1696             ps_unmark_node->ps_prev_short = NULL;
1697         }
1698     }
1699     else
1700     {
1701         i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
1702 
1703         if(i4_error_code != OK)
1704         {
1705             return i4_error_code;
1706         }
1707 
1708         i4_error_code = imvcd_dpb_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx);
1709 
1710         if(i4_error_code != OK)
1711         {
1712             return i4_error_code;
1713         }
1714     }
1715 
1716     return OK;
1717 }
1718 
imvcd_dpb_do_mmco(dpb_commands_t * ps_dpb_cmds,mvc_dpb_manager_t * ps_dpb_mgr,mvc_au_buffer_t * ps_cur_au,UWORD8 u1_max_num_ref_frames,UWORD8 u1_curr_pic_in_err)1719 WORD32 imvcd_dpb_do_mmco(dpb_commands_t *ps_dpb_cmds, mvc_dpb_manager_t *ps_dpb_mgr,
1720                          mvc_au_buffer_t *ps_cur_au, UWORD8 u1_max_num_ref_frames,
1721                          UWORD8 u1_curr_pic_in_err)
1722 {
1723     mvc_dpb_info_t *ps_next_dpb;
1724 
1725     WORD32 i, j;
1726     UWORD8 u1_buf_mode, u1_marked_lt;
1727     UWORD8 u1_num_gaps;
1728     WORD32 i4_error_code;
1729 
1730     UWORD8 u1_del_node = 1;
1731     UWORD8 u1_insert_st_pic = 1;
1732 
1733     // 0 - sliding window; 1 - Adaptive
1734     u1_buf_mode = ps_dpb_cmds->u1_buf_mode;
1735     u1_marked_lt = 0;
1736     u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1737 
1738     if(!u1_buf_mode)
1739     {
1740         // Sliding window - implements 8.2.5.3
1741         if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) ==
1742            u1_max_num_ref_frames)
1743         {
1744             UWORD8 u1_new_node_flag = 1;
1745 
1746             if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1747             {
1748                 return ERROR_DBP_MANAGER_T;
1749             }
1750 
1751             // Chase the links to reach the last but one picNum, if available
1752             ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1753 
1754             if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1755             {
1756                 if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1757                 {
1758                     return ERROR_DBP_MANAGER_T;
1759                 }
1760 
1761                 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1762                 {
1763                     if(ps_next_dpb == NULL)
1764                     {
1765                         return ERROR_DBP_MANAGER_T;
1766                     }
1767 
1768                     if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1769                     {
1770                         return ERROR_DBP_MANAGER_T;
1771                     }
1772 
1773                     ps_next_dpb = ps_next_dpb->ps_prev_short;
1774                 }
1775 
1776                 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1777                 {
1778                     return ERROR_DBP_MANAGER_T;
1779                 }
1780 
1781                 if(u1_new_node_flag)
1782                 {
1783                     if(u1_num_gaps)
1784                     {
1785                         i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
1786                             ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
1787                             &u1_del_node);
1788 
1789                         if(i4_error_code != OK)
1790                         {
1791                             return i4_error_code;
1792                         }
1793                     }
1794 
1795                     if(u1_del_node)
1796                     {
1797                         ps_dpb_mgr->u1_num_st_ref_bufs--;
1798                         ps_next_dpb->ps_prev_short->b_used_as_ref = false;
1799                         ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1800                         ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1801 
1802                         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1803                                             ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1804                                             ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);
1805 
1806                         ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
1807                         ps_next_dpb->ps_prev_short = NULL;
1808                     }
1809                 }
1810             }
1811             else
1812             {
1813                 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1814                 {
1815                     i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
1816                         ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);
1817 
1818                     if(i4_error_code != OK)
1819                     {
1820                         return i4_error_code;
1821                     }
1822 
1823                     if((ps_next_dpb->ps_au_buf->i4_pic_num != ps_cur_au->i4_pic_num) && u1_del_node)
1824                     {
1825                         ps_dpb_mgr->u1_num_st_ref_bufs--;
1826                         ps_next_dpb->b_used_as_ref = false;
1827                         ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1828                         ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1829 
1830                         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1831                                             ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1832                                             ps_next_dpb->ps_au_buf->i4_pic_buf_id);
1833 
1834                         ps_next_dpb->ps_au_buf = NULL;
1835                         ps_next_dpb->ps_prev_short = NULL;
1836                         ps_dpb_mgr->ps_dpb_st_head = NULL;
1837                         ps_next_dpb = NULL;
1838                     }
1839                     else if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1840                     {
1841                         if(u1_curr_pic_in_err)
1842                         {
1843                             u1_insert_st_pic = 0;
1844                         }
1845                         else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1846                         {
1847                             ps_dpb_mgr->u1_num_st_ref_bufs--;
1848                             ps_next_dpb->b_used_as_ref = false;
1849                             ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1850                             ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1851 
1852                             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1853                                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1854                                                 ps_next_dpb->ps_au_buf->i4_pic_buf_id);
1855 
1856                             ps_next_dpb->ps_au_buf = NULL;
1857                             ps_next_dpb = NULL;
1858                         }
1859                     }
1860                 }
1861                 else
1862                 {
1863                     i4_error_code = imvcd_dpb_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM,
1864                                                                      &u1_del_node);
1865 
1866                     if(i4_error_code != OK)
1867                     {
1868                         return i4_error_code;
1869                     }
1870 
1871                     if(u1_del_node)
1872                     {
1873                         return ERROR_DBP_MANAGER_T;
1874                     }
1875                 }
1876             }
1877         }
1878     }
1879     else
1880     {
1881         // Adaptive memory control - implements 8.2.5.4
1882         struct MMCParams *ps_mmc_params;
1883 
1884         UWORD32 u4_mmco;
1885         UWORD32 u4_diff_pic_num;
1886         UWORD32 u4_lt_idx;
1887 
1888         UWORD32 au4_num_mmco_cmds[NUM_MMCO_CMD_IDS] = {0};
1889 
1890         for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
1891         {
1892             ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
1893             u4_mmco = ps_mmc_params->u4_mmco;
1894 
1895             switch(u4_mmco)
1896             {
1897                 case MARK_ST_PICNUM_AS_NONREF:
1898                 {
1899                     WORD64 i8_pic_num;
1900 
1901                     u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
1902                     i8_pic_num =
1903                         ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
1904 
1905                     if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1906                     {
1907                         return ERROR_DBP_MANAGER_T;
1908                     }
1909 
1910                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1911                     {
1912                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
1913                             ps_dpb_mgr, (WORD32) i8_pic_num, MAX_REF_BUFS + 1);
1914 
1915                         if(i4_error_code != OK)
1916                         {
1917                             return i4_error_code;
1918                         }
1919                     }
1920                     else
1921                     {
1922                         UWORD8 u1_dummy;
1923 
1924                         i4_error_code = imvcd_dpb_delete_gap_frm_mmco(
1925                             ps_dpb_mgr, (WORD32) i8_pic_num, &u1_dummy);
1926 
1927                         if(i4_error_code != OK)
1928                         {
1929                             return i4_error_code;
1930                         }
1931                     }
1932 
1933                     break;
1934                 }
1935                 case MARK_LT_INDEX_AS_NONREF:
1936                 {
1937                     u4_lt_idx = ps_mmc_params->u4_lt_idx;
1938 
1939                     i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
1940 
1941                     if(i4_error_code != OK)
1942                     {
1943                         return i4_error_code;
1944                     }
1945 
1946                     break;
1947                 }
1948                 case MARK_ST_PICNUM_AS_LT_INDEX:
1949                 {
1950                     WORD64 i8_pic_num;
1951 
1952                     u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
1953 
1954                     i8_pic_num =
1955                         ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
1956 
1957                     if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1958                     {
1959                         return ERROR_DBP_MANAGER_T;
1960                     }
1961 
1962                     u4_lt_idx = ps_mmc_params->u4_lt_idx;
1963 
1964                     if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1965                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1966                     {
1967                         return ERROR_DBP_MANAGER_T;
1968                     }
1969 
1970                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1971                     {
1972                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
1973                             ps_dpb_mgr, (WORD32) i8_pic_num, u4_lt_idx);
1974 
1975                         if(i4_error_code != OK)
1976                         {
1977                             return i4_error_code;
1978                         }
1979                     }
1980 
1981                     break;
1982                 }
1983                 case SET_MAX_LT_INDEX:
1984                 {
1985                     if(au4_num_mmco_cmds[SET_MAX_LT_INDEX] > 0)
1986                     {
1987                         return ERROR_DBP_MANAGER_T;
1988                     }
1989 
1990                     u4_lt_idx =
1991                         ps_mmc_params->u4_max_lt_idx_plus1;  // Get Max_long_term_index_plus1
1992 
1993                     if((u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx) &&
1994                        (ps_dpb_mgr->u1_num_lt_ref_bufs > 0))
1995                     {
1996                         mvc_dpb_info_t *ps_nxtDPB;
1997 
1998                         // Set all LT buffers with index >= u4_lt_idx to nonreference
1999                         ps_nxtDPB = ps_dpb_mgr->ps_dpb_lt_head;
2000                         ps_next_dpb = ps_nxtDPB->ps_prev_long;
2001 
2002                         if(ps_nxtDPB->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
2003                         {
2004                             i = 0;
2005                             ps_dpb_mgr->ps_dpb_lt_head = NULL;
2006                         }
2007                         else
2008                         {
2009                             for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2010                             {
2011                                 if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
2012                                 {
2013                                     break;
2014                                 }
2015 
2016                                 ps_nxtDPB = ps_next_dpb;
2017                                 ps_next_dpb = ps_next_dpb->ps_prev_long;
2018                             }
2019 
2020                             ps_nxtDPB->ps_prev_long = NULL;  // Terminate the link of the
2021                                                              // closest LTIndex that is <=Max
2022                         }
2023 
2024                         ps_dpb_mgr->u1_num_lt_ref_bufs = i;
2025 
2026                         if(i == 0)
2027                         {
2028                             ps_next_dpb = ps_nxtDPB;
2029                         }
2030 
2031                         for(; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2032                         {
2033                             ps_nxtDPB = ps_next_dpb;
2034                             ps_nxtDPB->b_used_as_ref = false;
2035                             ps_nxtDPB->s_top_field.u1_reference_info = UNUSED_FOR_REF;
2036                             ps_nxtDPB->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
2037 
2038                             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
2039                                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
2040                                                 ps_nxtDPB->ps_au_buf->i4_pic_buf_id);
2041 
2042                             ps_nxtDPB->ps_au_buf = NULL;
2043 
2044                             ps_next_dpb = ps_nxtDPB->ps_prev_long;
2045                             ps_nxtDPB->ps_prev_long = NULL;
2046                         }
2047                     }
2048 
2049                     if(u4_lt_idx == 0)
2050                     {
2051                         ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
2052                     }
2053                     else
2054                     {
2055                         ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
2056                     }
2057 
2058                     break;
2059                 }
2060                 case SET_LT_INDEX:
2061                 {
2062                     if(au4_num_mmco_cmds[SET_LT_INDEX] > 0)
2063                     {
2064                         return ERROR_DBP_MANAGER_T;
2065                     }
2066 
2067                     u4_lt_idx = ps_mmc_params->u4_lt_idx;  // Get long term index
2068 
2069                     if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
2070                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
2071                     {
2072                         return ERROR_DBP_MANAGER_T;
2073                     }
2074 
2075                     i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2076 
2077                     if(i4_error_code != OK)
2078                     {
2079                         return i4_error_code;
2080                     }
2081 
2082                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
2083                     {
2084                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
2085                             ps_dpb_mgr, ps_cur_au->i4_pic_num, u4_lt_idx);
2086 
2087                         if(i4_error_code != OK)
2088                         {
2089                             return i4_error_code;
2090                         }
2091                     }
2092                     else
2093                     {
2094                         return ERROR_DBP_MANAGER_T;
2095                     }
2096 
2097                     u1_marked_lt = 1;
2098 
2099                     break;
2100                 }
2101                 case RESET_REF_PICTURES:
2102                 {
2103                     if((au4_num_mmco_cmds[RESET_REF_PICTURES] > 0) ||
2104                        (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_NONREF] > 0) ||
2105                        (au4_num_mmco_cmds[MARK_LT_INDEX_AS_NONREF] > 0) ||
2106                        (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_LT_INDEX] > 0))
2107                     {
2108                         return ERROR_DBP_MANAGER_T;
2109                     }
2110 
2111                     if((j > 0) && (ps_dpb_cmds->as_mmc_params[j - 1].u4_mmco == SET_LT_INDEX))
2112                     {
2113                         return ERROR_DBP_MANAGER_T;
2114                     }
2115 
2116                     __attribute__((fallthrough));
2117                 }
2118                 case RESET_ALL_PICTURES:
2119                 {
2120                     WORD32 i4_pic_num = ps_cur_au->i4_frame_num;
2121 
2122                     imvcd_reset_dpb(ps_dpb_mgr);
2123 
2124                     ps_cur_au->i4_frame_num = 0;
2125 
2126                     if(!u1_marked_lt && u1_insert_st_pic)
2127                     {
2128                         i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2129 
2130                         if(i4_error_code != OK)
2131                         {
2132                             return i4_error_code;
2133                         }
2134                     }
2135 
2136                     ps_cur_au->i4_frame_num = i4_pic_num;
2137 
2138                     return OK;
2139                 }
2140                 default:
2141                 {
2142                     return ERROR_DBP_MANAGER_T;
2143                 }
2144             }
2145 
2146             au4_num_mmco_cmds[u4_mmco]++;
2147         }
2148     }
2149 
2150     if(!u1_marked_lt && u1_insert_st_pic)
2151     {
2152         i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2153 
2154         if(i4_error_code != OK)
2155         {
2156             return i4_error_code;
2157         }
2158     }
2159 
2160     return OK;
2161 }
2162 
imvcd_dpb_update_default_index_list(mvc_dpb_manager_t * ps_dpb_mgr)2163 WORD32 imvcd_dpb_update_default_index_list(mvc_dpb_manager_t *ps_dpb_mgr)
2164 {
2165     WORD32 i;
2166 
2167     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
2168 
2169     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
2170     {
2171         ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
2172         ps_next_dpb = ps_next_dpb->ps_prev_short;
2173     }
2174 
2175     ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
2176 
2177     for(; i < ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2178     {
2179         ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
2180         ps_next_dpb = ps_next_dpb->ps_prev_long;
2181     }
2182 
2183     return OK;
2184 }
2185 
imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_curr_poc)2186 bool imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_curr_poc)
2187 {
2188     WORD32 i;
2189 
2190     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
2191 
2192     /* Check in conformance with section 8.2.1 from spec */
2193     /* Particularly the statement - */
2194     /* 'The bitstream shall not contain data that result in values of DiffPicOrderCnt(picA, picB)
2195      * used in the decoding process that exceed the range of -2^15 to 2^15 - 1 inclusive' */
2196     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
2197     {
2198         if(((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) >= (1 << 15)) ||
2199            ((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) < -(1 << 15)))
2200         {
2201             return false;
2202         }
2203 
2204         ps_next_dpb = ps_next_dpb->ps_prev_short;
2205     }
2206 
2207     return true;
2208 }
2209