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