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