• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(!(u2_buf_mod_bitfield & (1 << i)))
1091         {
1092             ps_dpb_mgr->aps_mod_dpb[u1_pred_lx][u1_num_bufs_modified++] =
1093                 &ps_dpb_mgr->as_init_dpb[u1_pred_lx][i];
1094         }
1095     }
1096 }
1097 
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)1098 WORD32 imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
1099                                       nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
1100                                       mvc_au_buffer_t *ps_cur_au,
1101                                       ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
1102                                       UWORD16 u2_view_order_id)
1103 {
1104     WORD32 i, j;
1105 
1106     sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;
1107 
1108     UWORD8 u1_anchor_pic_flag = ps_cur_nalu_mvc_ext->u1_anchor_pic_flag;
1109     WORD32 i4_cur_pic_num = ps_cur_au->i4_pic_num;
1110     WORD32 i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
1111     bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
1112 
1113     for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
1114     {
1115         mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;
1116 
1117         UWORD16 u2_max_view_idx;
1118 
1119         WORD32 i4_pred_pic_num = i4_cur_pic_num;
1120         WORD16 i2_pred_view_order_id = 0;  // -1; Need to check spec and JMVM implementation match
1121         UWORD8 *pu1_modification_of_pic_nums_idc =
1122             ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i];
1123         WORD32 *pi4_abs_diff_pic_num_minus1 =
1124             ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i];
1125         WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i];
1126         WORD32 *pi4_abs_diff_view_idx_minus1 =
1127             ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i];
1128         UWORD8 u1_num_ref_bufs =
1129             ps_dpb_mgr->au1_num_active_st_refs[i] + ps_dpb_mgr->au1_num_active_lt_refs[i];
1130         UWORD16 u2_buf_mod_bitfield = 0;
1131         UWORD8 u1_num_bufs_modified = 0;
1132 
1133         if(!ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i] ||
1134            (3 == pu1_modification_of_pic_nums_idc[0]))
1135         {
1136             imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au,
1137                                                   i);
1138 
1139             imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified,
1140                                              i);
1141 
1142             continue;
1143         }
1144 
1145         ps_mvc_ivp_ref_data =
1146             (0 == u2_view_order_id)
1147                 ? NULL
1148                 : (u1_anchor_pic_flag
1149                        ? &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id]
1150                        : &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id]);
1151         u2_max_view_idx = (0 == u2_view_order_id) ? 0 : ps_mvc_ivp_ref_data->u1_num_refs;
1152 
1153         do
1154         {
1155             if((0 == pu1_modification_of_pic_nums_idc[0]) ||
1156                (1 == pu1_modification_of_pic_nums_idc[0]))
1157             {
1158                 WORD32 i4_mod_pic_num = pi4_abs_diff_pic_num_minus1[0];
1159 
1160                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1161 
1162                 /* According to section 7.4.3.1 from spec, */
1163                 /* this value is expected to be from the */
1164                 /* closed interval [0, i4_max_pic_num - 1] */
1165                 if((i4_mod_pic_num < 0) || (i4_mod_pic_num >= i4_max_pic_num))
1166                 {
1167                     return ERROR_DBP_MANAGER_T;
1168                 }
1169 
1170                 /* +1 not accounted during initialisation, */
1171                 /* mainly to preclude integer overflow */
1172                 i4_mod_pic_num++;
1173 
1174                 if(0 == pu1_modification_of_pic_nums_idc[0])
1175                 {
1176                     i4_mod_pic_num = i4_pred_pic_num - i4_mod_pic_num;
1177 
1178                     if(i4_mod_pic_num < 0)
1179                     {
1180                         i4_mod_pic_num += i4_max_pic_num;
1181                     }
1182                 }
1183                 else
1184                 {
1185                     i4_mod_pic_num = i4_pred_pic_num + i4_mod_pic_num;
1186 
1187                     if(i4_mod_pic_num >= i4_max_pic_num)
1188                     {
1189                         i4_mod_pic_num -= i4_max_pic_num;
1190                     }
1191                 }
1192 
1193                 if(i4_mod_pic_num > i4_cur_pic_num)
1194                 {
1195                     i4_mod_pic_num -= i4_max_pic_num;
1196                 }
1197 
1198                 for(j = 0; j < u1_num_ref_bufs; j++)
1199                 {
1200                     if(ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_mod_pic_num)
1201                     {
1202                         u1_mod_buf_idx = j;
1203 
1204                         break;
1205                     }
1206                 }
1207 
1208                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1209                 {
1210                     return ERROR_DBP_MANAGER_T;
1211                 }
1212 
1213                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1214                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1215 
1216                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1217                 i4_pred_pic_num = i4_mod_pic_num;
1218             }
1219             else if(2 == pu1_modification_of_pic_nums_idc[0])
1220             {
1221                 WORD32 i4_mod_lt_pic_num = pi4_long_term_pic_num[0];
1222                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1223 
1224                 if(pi4_long_term_pic_num[0] > (MAX_REF_BUFS + 1))
1225                 {
1226                     return ERROR_DBP_MANAGER_T;
1227                 }
1228 
1229                 for(j = 0; j < u1_num_ref_bufs; j++)
1230                 {
1231                     if(!ps_dpb_mgr->as_init_dpb[i][j].b_is_short_term_ref &&
1232                        (i4_mod_lt_pic_num == ps_dpb_mgr->as_init_dpb[i][j].u1_long_term_pic_num))
1233                     {
1234                         u1_mod_buf_idx = j;
1235 
1236                         break;
1237                     }
1238                 }
1239 
1240                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1241                 {
1242                     return ERROR_DBP_MANAGER_T;
1243                 }
1244 
1245                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1246                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1247 
1248                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1249             }
1250             else if((4 == pu1_modification_of_pic_nums_idc[0]) ||
1251                     (5 == pu1_modification_of_pic_nums_idc[0]))
1252             {
1253                 WORD32 i4_target_view_id;
1254 
1255                 WORD32 i4_mod_view_order_id = pi4_abs_diff_view_idx_minus1[0];
1256                 UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
1257 
1258                 /* According to section H.7.4.3.1.1 from spec, */
1259                 /* this value is expected to be from the */
1260                 /* closed interval [0, u2_max_view_idx - 1] */
1261                 if((i4_mod_view_order_id < 0) || (i4_mod_view_order_id >= u2_max_view_idx))
1262                 {
1263                     return ERROR_DBP_MANAGER_T;
1264                 }
1265 
1266                 /* +1 not accounted during initialisation, */
1267                 /* mainly to preclude integer overflow */
1268                 i4_mod_view_order_id++;
1269 
1270                 if(4 == pu1_modification_of_pic_nums_idc[0])
1271                 {
1272                     i4_mod_view_order_id = i2_pred_view_order_id - i4_mod_view_order_id;
1273 
1274                     if(i4_mod_view_order_id < 0)
1275                     {
1276                         i4_mod_view_order_id += u2_max_view_idx;
1277                     }
1278                 }
1279                 else
1280                 {
1281                     i4_mod_view_order_id = i2_pred_view_order_id + i4_mod_view_order_id;
1282 
1283                     if(i4_mod_view_order_id >= u2_max_view_idx)
1284                     {
1285                         i4_mod_view_order_id -= u2_max_view_idx;
1286                     }
1287                 }
1288 
1289                 if((0 == u2_view_order_id) || (NULL == ps_mvc_ivp_ref_data))
1290                 {
1291                     return ERROR_DBP_MANAGER_T;
1292                 }
1293 
1294                 i4_target_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[i4_mod_view_order_id];
1295 
1296                 for(j = 0; j < u1_num_ref_bufs; j++)
1297                 {
1298                     if(ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.b_is_ivp_ref)
1299                     {
1300                         if((ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_cur_pic_num) &&
1301                            (ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.u2_ref_view_id ==
1302                             i4_target_view_id))
1303                         {
1304                             u1_mod_buf_idx = j;
1305 
1306                             break;
1307                         }
1308                     }
1309                 }
1310 
1311                 if(u1_mod_buf_idx == u1_num_ref_bufs)
1312                 {
1313                     return ERROR_DBP_MANAGER_T;
1314                 }
1315 
1316                 u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
1317                 ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
1318                     &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
1319                 i2_pred_view_order_id = i4_mod_view_order_id;
1320             }
1321             else if(3 != pu1_modification_of_pic_nums_idc[0])
1322             {
1323                 return ERROR_REFIDX_ORDER_T;
1324             }
1325             else
1326             {
1327                 break;
1328             }
1329 
1330             pu1_modification_of_pic_nums_idc++;
1331             pi4_abs_diff_pic_num_minus1++;
1332             pi4_long_term_pic_num++;
1333             pi4_abs_diff_view_idx_minus1++;
1334         } while(true);
1335 
1336         imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au, i);
1337 
1338         imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified, i);
1339     }
1340 
1341     return OK;
1342 }
1343 
imvcd_dpb_insert_st_node(mvc_dpb_manager_t * ps_dpb_mgr,mvc_au_buffer_t * ps_au_buf)1344 WORD32 imvcd_dpb_insert_st_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_au_buf)
1345 {
1346     WORD32 i;
1347 
1348     mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
1349     UWORD8 u1_picture_type = ps_au_buf->u1_picturetype;
1350 
1351     for(i = 0; i < MVC_MAX_REF_PICS; i++)
1352     {
1353         if((ps_dpb_info[i].ps_au_buf == ps_au_buf) && ps_dpb_info[i].b_used_as_ref)
1354         {
1355             /* Can occur only for field bottom pictures */
1356             if(ps_dpb_info[i].ps_au_buf->u1_pic_type == FRM_PIC)
1357             {
1358                 return ERROR_DBP_MANAGER_T;
1359             }
1360             else
1361             {
1362                 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1363 
1364                 return OK;
1365             }
1366         }
1367 
1368         if(!ps_dpb_info[i].b_used_as_ref &&
1369            (ps_dpb_info[i].s_top_field.u1_reference_info == UNUSED_FOR_REF) &&
1370            (ps_dpb_info[i].s_bot_field.u1_reference_info == UNUSED_FOR_REF))
1371         {
1372             break;
1373         }
1374     }
1375 
1376     if(i == MVC_MAX_REF_PICS)
1377     {
1378         return ERROR_DBP_MANAGER_T;
1379     }
1380 
1381     ps_dpb_info[i].ps_au_buf = ps_au_buf;
1382     ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
1383     ps_dpb_info[i].b_used_as_ref = true;
1384 
1385     ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
1386 
1387     ps_dpb_mgr->u1_num_st_ref_bufs++;
1388 
1389     ps_au_buf->b_is_short_term_ref = true;
1390 
1391     if((u1_picture_type & 0x03) == FRM_PIC)
1392     {
1393         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
1394         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1395     }
1396     else if((u1_picture_type & 0x03) == TOP_FLD)
1397     {
1398         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
1399     }
1400     else if((u1_picture_type & 0x03) == BOT_FLD)
1401     {
1402         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
1403     }
1404 
1405     return OK;
1406 }
1407 
imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_frame_num,UWORD8 * pu1_del_node)1408 static WORD32 imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_frame_num,
1409                                             UWORD8 *pu1_del_node)
1410 {
1411     WORD8 i, j;
1412     WORD32 *pi4_start, *pi4_end;
1413     WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_pic_num;
1414 
1415     /* find the least frame num from gaps and current DPB node    */
1416     /* Delete the gaps                                            */
1417     *pu1_del_node = 1;
1418     pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
1419     pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
1420     i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
1421 
1422     if(0 == ps_dpb_mgr->u1_num_gaps)
1423     {
1424         return OK;
1425     }
1426 
1427     if(i4_frame_num < 0)
1428     {
1429         i4_frame_num += i4_max_pic_num;
1430     }
1431 
1432     for(i = 0; i < MAX_FRAMES; i++)
1433     {
1434         i4_start_frm_num = pi4_start[i];
1435 
1436         if(i4_start_frm_num < 0)
1437         {
1438             i4_start_frm_num += i4_max_pic_num;
1439         }
1440 
1441         if(INVALID_FRAME_NUM != i4_start_frm_num)
1442         {
1443             i4_end_frm_num = pi4_end[i];
1444 
1445             if(i4_end_frm_num < 0)
1446             {
1447                 i4_end_frm_num += i4_max_pic_num;
1448             }
1449 
1450             if((i4_frame_num >= i4_start_frm_num) && (i4_frame_num <= i4_end_frm_num))
1451             {
1452                 break;
1453             }
1454             else
1455             {
1456                 if(((i4_frame_num + i4_max_pic_num) >= i4_start_frm_num) &&
1457                    ((i4_frame_num + i4_max_pic_num) <= i4_end_frm_num))
1458                 {
1459                     return ERROR_DBP_MANAGER_T;
1460                 }
1461             }
1462         }
1463     }
1464 
1465     /* find frame_num index, in the poc_map which needs to be deleted */
1466     for(j = 0; j < MAX_FRAMES; j++)
1467     {
1468         if(i4_frame_num == ps_dpb_mgr->as_display_buf_info[j].i4_frame_num)
1469         {
1470             break;
1471         }
1472     }
1473 
1474     if(MAX_FRAMES != i)
1475     {
1476         if(j == MAX_FRAMES)
1477         {
1478             return ERROR_DBP_MANAGER_T;
1479         }
1480 
1481         ps_dpb_mgr->as_display_buf_info[j].i4_poc_buf_id = -1;
1482         ps_dpb_mgr->as_display_buf_info[j].i4_poc = 0x7fffffff;
1483         ps_dpb_mgr->as_display_buf_info[j].i4_frame_num = GAP_FRAME_NUM;
1484 
1485         ps_dpb_mgr->i1_gaps_deleted++;
1486         ps_dpb_mgr->ai1_gaps_per_seq[i]--;
1487         ps_dpb_mgr->u1_num_gaps--;
1488         *pu1_del_node = 0;
1489 
1490         if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
1491         {
1492             ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
1493             ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
1494         }
1495     }
1496     else
1497     {
1498         return ERROR_DBP_MANAGER_T;
1499     }
1500 
1501     return OK;
1502 }
1503 
imvcd_dpb_insert_lt_node(mvc_dpb_manager_t * ps_dpb_mgr,mvc_dpb_info_t * ps_new_node,UWORD32 u4_lt_idx)1504 static WORD32 imvcd_dpb_insert_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_dpb_info_t *ps_new_node,
1505                                        UWORD32 u4_lt_idx)
1506 {
1507     ps_new_node->s_top_field.u1_reference_info = IS_LONG_TERM;
1508     ps_new_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
1509     ps_new_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
1510     ps_new_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
1511     ps_new_node->ps_au_buf->u1_long_term_frm_idx = u4_lt_idx;
1512     ps_new_node->b_used_as_ref = true;
1513 
1514     if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
1515     {
1516         WORD32 i;
1517 
1518         mvc_dpb_info_t **pps_next_node = &ps_dpb_mgr->ps_dpb_lt_head;
1519 
1520         for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
1521         {
1522             if((*pps_next_node)->ps_au_buf->u1_long_term_frm_idx > u4_lt_idx)
1523             {
1524                 ps_new_node->ps_prev_long = *pps_next_node;
1525                 *pps_next_node = ps_new_node;
1526 
1527                 break;
1528             }
1529             else if(NULL == (*pps_next_node)->ps_prev_long)
1530             {
1531                 (*pps_next_node)->ps_prev_long = ps_new_node;
1532                 ps_new_node->ps_prev_long = NULL;
1533 
1534                 break;
1535             }
1536 
1537             pps_next_node = &(*pps_next_node)->ps_prev_long;
1538         }
1539     }
1540     else
1541     {
1542         ps_dpb_mgr->ps_dpb_lt_head = ps_new_node;
1543         ps_new_node->ps_prev_long = NULL;
1544     }
1545 
1546     ps_new_node->ps_au_buf->b_is_short_term_ref = false;
1547 
1548     ps_dpb_mgr->u1_num_lt_ref_bufs++;
1549 
1550     return OK;
1551 }
1552 
imvcd_dpb_delete_lt_node(mvc_dpb_manager_t * ps_dpb_mgr,UWORD32 u4_lt_idx)1553 static WORD32 imvcd_dpb_delete_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, UWORD32 u4_lt_idx)
1554 {
1555     mvc_dpb_info_t *ps_next_dpb;
1556     mvc_dpb_info_t *ps_unmark_node;
1557 
1558     WORD32 i;
1559 
1560     if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
1561     {
1562         ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
1563 
1564         if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
1565         {
1566             ps_unmark_node = ps_next_dpb;
1567         }
1568         else
1569         {
1570             for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
1571             {
1572                 if(ps_next_dpb->ps_prev_long->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
1573                 {
1574                     break;
1575                 }
1576 
1577                 ps_next_dpb = ps_next_dpb->ps_prev_long;
1578             }
1579 
1580             if(i < ps_dpb_mgr->u1_num_lt_ref_bufs)
1581             {
1582                 ps_unmark_node = ps_next_dpb->ps_prev_long;
1583             }
1584             else
1585             {
1586                 return OK;
1587             }
1588         }
1589 
1590         ps_unmark_node->b_used_as_ref = false;
1591 
1592         if(ps_unmark_node == ps_dpb_mgr->ps_dpb_lt_head)
1593         {
1594             ps_dpb_mgr->ps_dpb_lt_head = ps_next_dpb->ps_prev_long;
1595         }
1596 
1597         ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1598         ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1599 
1600         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr, ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1601                             ps_unmark_node->ps_au_buf->i4_pic_buf_id);
1602 
1603         ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long;
1604         ps_unmark_node->ps_prev_long = NULL;
1605         ps_dpb_mgr->u1_num_lt_ref_bufs--;
1606     }
1607 
1608     return OK;
1609 }
1610 
imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_pic_num,UWORD32 u4_lt_idx)1611 WORD32 imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
1612                                            UWORD32 u4_lt_idx)
1613 {
1614     WORD32 i4_error_code;
1615 
1616     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1617     mvc_dpb_info_t *ps_unmark_node = NULL;
1618 
1619     UWORD8 u1_del_node = 0, u1_del_st = 0;
1620     WORD32 i = 0;
1621 
1622     if(ps_next_dpb->ps_au_buf->i4_pic_num == i4_pic_num)
1623     {
1624         ps_unmark_node = ps_next_dpb;
1625     }
1626     else
1627     {
1628         for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
1629         {
1630             if(ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num == i4_pic_num)
1631             {
1632                 ps_unmark_node = ps_next_dpb->ps_prev_short;
1633 
1634                 break;
1635             }
1636 
1637             ps_next_dpb = ps_next_dpb->ps_prev_short;
1638         }
1639     }
1640 
1641     if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
1642     {
1643         if(ps_dpb_mgr->u1_num_gaps)
1644         {
1645             i4_error_code = imvcd_dpb_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_del_st);
1646 
1647             if(i4_error_code != OK)
1648             {
1649                 return i4_error_code;
1650             }
1651         }
1652         else
1653         {
1654             return ERROR_DBP_MANAGER_T;
1655         }
1656 
1657         if(u1_del_st)
1658         {
1659             return ERROR_DBP_MANAGER_T;
1660         }
1661         else
1662         {
1663             return 0;
1664         }
1665     }
1666 
1667     ps_unmark_node->b_used_as_ref = false;
1668     ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1669     ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1670 
1671     if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
1672     {
1673         ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
1674     }
1675     else
1676     {
1677         ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short;
1678     }
1679 
1680     ps_dpb_mgr->u1_num_st_ref_bufs--;
1681     u1_del_node = 1;
1682 
1683     if(u4_lt_idx == (MAX_REF_BUFS + 1))
1684     {
1685         if(u1_del_node)
1686         {
1687             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1688                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1689                                 ps_unmark_node->ps_au_buf->i4_pic_buf_id);
1690 
1691             ps_unmark_node->ps_prev_short = NULL;
1692         }
1693     }
1694     else
1695     {
1696         i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
1697 
1698         if(i4_error_code != OK)
1699         {
1700             return i4_error_code;
1701         }
1702 
1703         i4_error_code = imvcd_dpb_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx);
1704 
1705         if(i4_error_code != OK)
1706         {
1707             return i4_error_code;
1708         }
1709     }
1710 
1711     return OK;
1712 }
1713 
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)1714 WORD32 imvcd_dpb_do_mmco(dpb_commands_t *ps_dpb_cmds, mvc_dpb_manager_t *ps_dpb_mgr,
1715                          mvc_au_buffer_t *ps_cur_au, UWORD8 u1_max_num_ref_frames,
1716                          UWORD8 u1_curr_pic_in_err)
1717 {
1718     mvc_dpb_info_t *ps_next_dpb;
1719 
1720     WORD32 i, j;
1721     UWORD8 u1_buf_mode, u1_marked_lt;
1722     UWORD8 u1_num_gaps;
1723     WORD32 i4_error_code;
1724 
1725     UWORD8 u1_del_node = 1;
1726     UWORD8 u1_insert_st_pic = 1;
1727 
1728     // 0 - sliding window; 1 - Adaptive
1729     u1_buf_mode = ps_dpb_cmds->u1_buf_mode;
1730     u1_marked_lt = 0;
1731     u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1732 
1733     if(!u1_buf_mode)
1734     {
1735         // Sliding window - implements 8.2.5.3
1736         if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) ==
1737            u1_max_num_ref_frames)
1738         {
1739             UWORD8 u1_new_node_flag = 1;
1740 
1741             if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1742             {
1743                 return ERROR_DBP_MANAGER_T;
1744             }
1745 
1746             // Chase the links to reach the last but one picNum, if available
1747             ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1748 
1749             if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1750             {
1751                 if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1752                 {
1753                     return ERROR_DBP_MANAGER_T;
1754                 }
1755 
1756                 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1757                 {
1758                     if(ps_next_dpb == NULL)
1759                     {
1760                         return ERROR_DBP_MANAGER_T;
1761                     }
1762 
1763                     if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1764                     {
1765                         return ERROR_DBP_MANAGER_T;
1766                     }
1767 
1768                     ps_next_dpb = ps_next_dpb->ps_prev_short;
1769                 }
1770 
1771                 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1772                 {
1773                     return ERROR_DBP_MANAGER_T;
1774                 }
1775 
1776                 if(u1_new_node_flag)
1777                 {
1778                     if(u1_num_gaps)
1779                     {
1780                         i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
1781                             ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
1782                             &u1_del_node);
1783 
1784                         if(i4_error_code != OK)
1785                         {
1786                             return i4_error_code;
1787                         }
1788                     }
1789 
1790                     if(u1_del_node)
1791                     {
1792                         ps_dpb_mgr->u1_num_st_ref_bufs--;
1793                         ps_next_dpb->ps_prev_short->b_used_as_ref = false;
1794                         ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1795                         ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1796 
1797                         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1798                                             ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1799                                             ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);
1800 
1801                         ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
1802                         ps_next_dpb->ps_prev_short = NULL;
1803                     }
1804                 }
1805             }
1806             else
1807             {
1808                 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1809                 {
1810                     i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
1811                         ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);
1812 
1813                     if(i4_error_code != OK)
1814                     {
1815                         return i4_error_code;
1816                     }
1817 
1818                     if((ps_next_dpb->ps_au_buf->i4_pic_num != ps_cur_au->i4_pic_num) && u1_del_node)
1819                     {
1820                         ps_dpb_mgr->u1_num_st_ref_bufs--;
1821                         ps_next_dpb->b_used_as_ref = false;
1822                         ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1823                         ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1824 
1825                         imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1826                                             ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1827                                             ps_next_dpb->ps_au_buf->i4_pic_buf_id);
1828 
1829                         ps_next_dpb->ps_au_buf = NULL;
1830                         ps_next_dpb->ps_prev_short = NULL;
1831                         ps_dpb_mgr->ps_dpb_st_head = NULL;
1832                         ps_next_dpb = NULL;
1833                     }
1834                     else if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
1835                     {
1836                         if(u1_curr_pic_in_err)
1837                         {
1838                             u1_insert_st_pic = 0;
1839                         }
1840                         else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1841                         {
1842                             ps_dpb_mgr->u1_num_st_ref_bufs--;
1843                             ps_next_dpb->b_used_as_ref = false;
1844                             ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1845                             ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1846 
1847                             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
1848                                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
1849                                                 ps_next_dpb->ps_au_buf->i4_pic_buf_id);
1850 
1851                             ps_next_dpb->ps_au_buf = NULL;
1852                             ps_next_dpb = NULL;
1853                         }
1854                     }
1855                 }
1856                 else
1857                 {
1858                     i4_error_code = imvcd_dpb_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM,
1859                                                                      &u1_del_node);
1860 
1861                     if(i4_error_code != OK)
1862                     {
1863                         return i4_error_code;
1864                     }
1865 
1866                     if(u1_del_node)
1867                     {
1868                         return ERROR_DBP_MANAGER_T;
1869                     }
1870                 }
1871             }
1872         }
1873     }
1874     else
1875     {
1876         // Adaptive memory control - implements 8.2.5.4
1877         struct MMCParams *ps_mmc_params;
1878 
1879         UWORD32 u4_mmco;
1880         UWORD32 u4_diff_pic_num;
1881         UWORD32 u4_lt_idx;
1882 
1883         UWORD32 au4_num_mmco_cmds[NUM_MMCO_CMD_IDS] = {0};
1884 
1885         for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
1886         {
1887             ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
1888             u4_mmco = ps_mmc_params->u4_mmco;
1889 
1890             switch(u4_mmco)
1891             {
1892                 case MARK_ST_PICNUM_AS_NONREF:
1893                 {
1894                     WORD64 i8_pic_num;
1895 
1896                     u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
1897                     i8_pic_num =
1898                         ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
1899 
1900                     if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1901                     {
1902                         return ERROR_DBP_MANAGER_T;
1903                     }
1904 
1905                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1906                     {
1907                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
1908                             ps_dpb_mgr, (WORD32) i8_pic_num, MAX_REF_BUFS + 1);
1909 
1910                         if(i4_error_code != OK)
1911                         {
1912                             return i4_error_code;
1913                         }
1914                     }
1915                     else
1916                     {
1917                         UWORD8 u1_dummy;
1918 
1919                         i4_error_code = imvcd_dpb_delete_gap_frm_mmco(
1920                             ps_dpb_mgr, (WORD32) i8_pic_num, &u1_dummy);
1921 
1922                         if(i4_error_code != OK)
1923                         {
1924                             return i4_error_code;
1925                         }
1926                     }
1927 
1928                     break;
1929                 }
1930                 case MARK_LT_INDEX_AS_NONREF:
1931                 {
1932                     u4_lt_idx = ps_mmc_params->u4_lt_idx;
1933 
1934                     i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
1935 
1936                     if(i4_error_code != OK)
1937                     {
1938                         return i4_error_code;
1939                     }
1940 
1941                     break;
1942                 }
1943                 case MARK_ST_PICNUM_AS_LT_INDEX:
1944                 {
1945                     WORD64 i8_pic_num;
1946 
1947                     u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
1948 
1949                     i8_pic_num =
1950                         ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
1951 
1952                     if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1953                     {
1954                         return ERROR_DBP_MANAGER_T;
1955                     }
1956 
1957                     u4_lt_idx = ps_mmc_params->u4_lt_idx;
1958 
1959                     if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1960                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1961                     {
1962                         return ERROR_DBP_MANAGER_T;
1963                     }
1964 
1965                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1966                     {
1967                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
1968                             ps_dpb_mgr, (WORD32) i8_pic_num, u4_lt_idx);
1969 
1970                         if(i4_error_code != OK)
1971                         {
1972                             return i4_error_code;
1973                         }
1974                     }
1975 
1976                     break;
1977                 }
1978                 case SET_MAX_LT_INDEX:
1979                 {
1980                     if(au4_num_mmco_cmds[SET_MAX_LT_INDEX] > 0)
1981                     {
1982                         return ERROR_DBP_MANAGER_T;
1983                     }
1984 
1985                     u4_lt_idx =
1986                         ps_mmc_params->u4_max_lt_idx_plus1;  // Get Max_long_term_index_plus1
1987 
1988                     if((u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx) &&
1989                        (ps_dpb_mgr->u1_num_lt_ref_bufs > 0))
1990                     {
1991                         mvc_dpb_info_t *ps_nxtDPB;
1992 
1993                         // Set all LT buffers with index >= u4_lt_idx to nonreference
1994                         ps_nxtDPB = ps_dpb_mgr->ps_dpb_lt_head;
1995                         ps_next_dpb = ps_nxtDPB->ps_prev_long;
1996 
1997                         if(ps_nxtDPB->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
1998                         {
1999                             i = 0;
2000                             ps_dpb_mgr->ps_dpb_lt_head = NULL;
2001                         }
2002                         else
2003                         {
2004                             for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2005                             {
2006                                 if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
2007                                 {
2008                                     break;
2009                                 }
2010 
2011                                 ps_nxtDPB = ps_next_dpb;
2012                                 ps_next_dpb = ps_next_dpb->ps_prev_long;
2013                             }
2014 
2015                             ps_nxtDPB->ps_prev_long = NULL;  // Terminate the link of the
2016                                                              // closest LTIndex that is <=Max
2017                         }
2018 
2019                         ps_dpb_mgr->u1_num_lt_ref_bufs = i;
2020 
2021                         if(i == 0)
2022                         {
2023                             ps_next_dpb = ps_nxtDPB;
2024                         }
2025 
2026                         for(; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2027                         {
2028                             ps_nxtDPB = ps_next_dpb;
2029                             ps_nxtDPB->b_used_as_ref = false;
2030                             ps_nxtDPB->s_top_field.u1_reference_info = UNUSED_FOR_REF;
2031                             ps_nxtDPB->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
2032 
2033                             imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
2034                                                 ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
2035                                                 ps_nxtDPB->ps_au_buf->i4_pic_buf_id);
2036 
2037                             ps_nxtDPB->ps_au_buf = NULL;
2038 
2039                             ps_next_dpb = ps_nxtDPB->ps_prev_long;
2040                             ps_nxtDPB->ps_prev_long = NULL;
2041                         }
2042                     }
2043 
2044                     if(u4_lt_idx == 0)
2045                     {
2046                         ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
2047                     }
2048                     else
2049                     {
2050                         ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
2051                     }
2052 
2053                     break;
2054                 }
2055                 case SET_LT_INDEX:
2056                 {
2057                     if(au4_num_mmco_cmds[SET_LT_INDEX] > 0)
2058                     {
2059                         return ERROR_DBP_MANAGER_T;
2060                     }
2061 
2062                     u4_lt_idx = ps_mmc_params->u4_lt_idx;  // Get long term index
2063 
2064                     if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
2065                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
2066                     {
2067                         return ERROR_DBP_MANAGER_T;
2068                     }
2069 
2070                     i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2071 
2072                     if(i4_error_code != OK)
2073                     {
2074                         return i4_error_code;
2075                     }
2076 
2077                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
2078                     {
2079                         i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
2080                             ps_dpb_mgr, ps_cur_au->i4_pic_num, u4_lt_idx);
2081 
2082                         if(i4_error_code != OK)
2083                         {
2084                             return i4_error_code;
2085                         }
2086                     }
2087                     else
2088                     {
2089                         return ERROR_DBP_MANAGER_T;
2090                     }
2091 
2092                     u1_marked_lt = 1;
2093 
2094                     break;
2095                 }
2096                 case RESET_REF_PICTURES:
2097                 {
2098                     if((au4_num_mmco_cmds[RESET_REF_PICTURES] > 0) ||
2099                        (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_NONREF] > 0) ||
2100                        (au4_num_mmco_cmds[MARK_LT_INDEX_AS_NONREF] > 0) ||
2101                        (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_LT_INDEX] > 0))
2102                     {
2103                         return ERROR_DBP_MANAGER_T;
2104                     }
2105 
2106                     if((j > 0) && (ps_dpb_cmds->as_mmc_params[j - 1].u4_mmco == SET_LT_INDEX))
2107                     {
2108                         return ERROR_DBP_MANAGER_T;
2109                     }
2110 
2111                     __attribute__((fallthrough));
2112                 }
2113                 case RESET_ALL_PICTURES:
2114                 {
2115                     WORD32 i4_pic_num = ps_cur_au->i4_frame_num;
2116 
2117                     imvcd_reset_dpb(ps_dpb_mgr);
2118 
2119                     ps_cur_au->i4_frame_num = 0;
2120 
2121                     if(!u1_marked_lt && u1_insert_st_pic)
2122                     {
2123                         i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2124 
2125                         if(i4_error_code != OK)
2126                         {
2127                             return i4_error_code;
2128                         }
2129                     }
2130 
2131                     ps_cur_au->i4_frame_num = i4_pic_num;
2132 
2133                     return OK;
2134                 }
2135                 default:
2136                 {
2137                     return ERROR_DBP_MANAGER_T;
2138                 }
2139             }
2140 
2141             au4_num_mmco_cmds[u4_mmco]++;
2142         }
2143     }
2144 
2145     if(!u1_marked_lt && u1_insert_st_pic)
2146     {
2147         i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
2148 
2149         if(i4_error_code != OK)
2150         {
2151             return i4_error_code;
2152         }
2153     }
2154 
2155     return OK;
2156 }
2157 
imvcd_dpb_update_default_index_list(mvc_dpb_manager_t * ps_dpb_mgr)2158 WORD32 imvcd_dpb_update_default_index_list(mvc_dpb_manager_t *ps_dpb_mgr)
2159 {
2160     WORD32 i;
2161 
2162     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
2163 
2164     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
2165     {
2166         ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
2167         ps_next_dpb = ps_next_dpb->ps_prev_short;
2168     }
2169 
2170     ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
2171 
2172     for(; i < ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
2173     {
2174         ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
2175         ps_next_dpb = ps_next_dpb->ps_prev_long;
2176     }
2177 
2178     return OK;
2179 }
2180 
imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t * ps_dpb_mgr,WORD32 i4_curr_poc)2181 bool imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_curr_poc)
2182 {
2183     WORD32 i;
2184 
2185     mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
2186 
2187     /* Check in conformance with section 8.2.1 from spec */
2188     /* Particularly the statement - */
2189     /* 'The bitstream shall not contain data that result in values of DiffPicOrderCnt(picA, picB)
2190      * used in the decoding process that exceed the range of -2^15 to 2^15 - 1 inclusive' */
2191     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
2192     {
2193         if(((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) >= (1 << 15)) ||
2194            ((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) < -(1 << 15)))
2195         {
2196             return false;
2197         }
2198 
2199         ps_next_dpb = ps_next_dpb->ps_prev_short;
2200     }
2201 
2202     return true;
2203 }
2204