1 /******************************************************************************
2 *
3 * Copyright (C) 2015 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 #include "ih264_typedefs.h"
21 #include "ih264_macros.h"
22 #include "ih264_platform_macros.h"
23 #include "iv.h"
24 #include "ih264d_dpb_manager.h"
25 #include "ih264d_bitstrm.h"
26 #include "ih264d_parse_cavlc.h"
27 #include "ih264d_defs.h"
28 #include "ih264d_structs.h"
29 #include "ih264d_process_bslice.h"
30 #include "ih264d_debug.h"
31 #include "ih264d_tables.h"
32 #include "ih264d_error_handler.h"
33 #include "string.h"
34 #include "ih264d_defs.h"
35 #include "ih264_error.h"
36 #include "ih264_buf_mgr.h"
37 #include "assert.h"
38
39 /*!
40 ***************************************************************************
41 * \file ih264d_dpb_mgr.c
42 *
43 * \brief
44 * Functions for managing the decoded picture buffer
45 *
46 * Detailed_description
47 *
48 * \date
49 * 19-12-2002
50 *
51 * \author Sriram Sethuraman
52 ***************************************************************************
53 */
54
55 /*!
56 **************************************************************************
57 * \if Function name : ih264d_init_ref_bufs \endif
58 *
59 * \brief
60 * Called at the start for initialization.
61 *
62 * \return
63 * none
64 **************************************************************************
65 */
ih264d_init_ref_bufs(dpb_manager_t * ps_dpb_mgr)66 void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr)
67 {
68 UWORD32 i;
69 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
70 for(i = 0; i < MAX_REF_BUFS; i++)
71 {
72 ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
73 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
74 ps_dpb_info[i].ps_prev_short = NULL;
75 ps_dpb_info[i].ps_prev_long = NULL;
76 ps_dpb_info[i].ps_pic_buf = NULL;
77 ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
78 ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
79 ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
80 ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
81
82 }
83 ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
84 ps_dpb_mgr->ps_dpb_st_head = NULL;
85 ps_dpb_mgr->ps_dpb_ht_head = NULL;
86 ps_dpb_mgr->i1_gaps_deleted = 0;
87 ps_dpb_mgr->i1_poc_buf_id_entries = 0;
88
89 ps_dpb_mgr->u1_num_gaps = 0;
90 for(i = 0; i < MAX_FRAMES; i++)
91 {
92 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
93 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
94 ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
95 ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1;
96 ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff;
97 ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0;
98 }
99
100 }
101
ih264d_free_ref_pic_mv_bufs(void * pv_dec,UWORD8 pic_buf_id)102 void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id)
103 {
104 dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
105
106 if((pic_buf_id == ps_dec->u1_pic_buf_id) &&
107 ps_dec->ps_cur_slice->u1_field_pic_flag &&
108 (ps_dec->u1_top_bottom_decoded == 0))
109 {
110 return;
111 }
112
113 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
114 pic_buf_id,
115 BUF_MGR_REF);
116 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
117 ps_dec->au1_pic_buf_id_mv_buf_id_map[pic_buf_id],
118 BUF_MGR_REF);
119 }
120 /*!
121 **************************************************************************
122 * \if Function name : ih264d_delete_lt_node \endif
123 *
124 * \brief
125 * Delete a buffer with a long term index from the LT linked list
126 *
127 * \return
128 * none
129 **************************************************************************
130 */
ih264d_delete_lt_node(dpb_manager_t * ps_dpb_mgr,UWORD32 u4_lt_idx,UWORD8 u1_fld_pic_flag,struct dpb_info_t * ps_lt_node_to_insert,WORD32 * pi4_status)131 WORD32 ih264d_delete_lt_node(dpb_manager_t *ps_dpb_mgr,
132 UWORD32 u4_lt_idx,
133 UWORD8 u1_fld_pic_flag,
134 struct dpb_info_t *ps_lt_node_to_insert,
135 WORD32 *pi4_status)
136 {
137 *pi4_status = 0;
138 if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
139 {
140 WORD32 i;
141 struct dpb_info_t *ps_next_dpb;
142 /* ps_unmark_node points to the node to be removed */
143 /* from long term list. */
144 struct dpb_info_t *ps_unmark_node;
145 //Find the node with matching LTIndex
146 ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
147 if(ps_next_dpb->u1_lt_idx == u4_lt_idx)
148 {
149 ps_unmark_node = ps_next_dpb;
150 }
151 else
152 {
153 for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
154 {
155 if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx)
156 break;
157 ps_next_dpb = ps_next_dpb->ps_prev_long;
158 }
159 if(i == ps_dpb_mgr->u1_num_lt_ref_bufs)
160 *pi4_status = 1;
161 else
162 ps_unmark_node = ps_next_dpb->ps_prev_long;
163 }
164
165 if(*pi4_status == 0)
166 {
167 if(u1_fld_pic_flag)
168 {
169 if(ps_lt_node_to_insert != ps_unmark_node)
170 {
171 UWORD8 u1_deleted = 0;
172 /* for the ps_unmark_node mark the corresponding field */
173 /* field as unused for reference */
174
175 if(ps_unmark_node->s_top_field.u1_long_term_frame_idx
176 == u4_lt_idx)
177 {
178 ps_unmark_node->s_top_field.u1_reference_info =
179 UNUSED_FOR_REF;
180 ps_unmark_node->s_top_field.u1_long_term_frame_idx =
181 MAX_REF_BUFS + 1;
182 u1_deleted = 1;
183 }
184 if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx
185 == u4_lt_idx)
186 {
187 ps_unmark_node->s_bot_field.u1_reference_info =
188 UNUSED_FOR_REF;
189 ps_unmark_node->s_bot_field.u1_long_term_frame_idx =
190 MAX_REF_BUFS + 1;
191 u1_deleted = 1;
192 }
193
194 if(!u1_deleted)
195 {
196
197 UWORD32 i4_error_code;
198 i4_error_code = ERROR_DBP_MANAGER_T;
199
200 return i4_error_code;
201 }
202 }
203
204 ps_unmark_node->u1_used_as_ref =
205 ps_unmark_node->s_top_field.u1_reference_info
206 | ps_unmark_node->s_bot_field.u1_reference_info;
207 }
208 else
209 ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
210
211 if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref)
212 {
213 if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head)
214 ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long;
215
216 ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1;
217 ps_unmark_node->s_top_field.u1_reference_info =
218 UNUSED_FOR_REF;
219 ps_unmark_node->s_bot_field.u1_reference_info =
220 UNUSED_FOR_REF;
221 // Release the physical buffer
222 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
223 ps_unmark_node->u1_buf_id);
224 ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link
225 ps_unmark_node->ps_prev_long = NULL;
226 ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count
227 }
228 }
229 }
230 return OK;
231 }
232
233 /*!
234 **************************************************************************
235 * \if Function name : ih264d_insert_lt_node \endif
236 *
237 * \brief
238 * Insert a buffer into the LT linked list at a given LT index
239 *
240 * \return
241 * none
242 **************************************************************************
243 */
ih264d_insert_lt_node(dpb_manager_t * ps_dpb_mgr,struct dpb_info_t * ps_mov_node,UWORD32 u4_lt_idx,UWORD8 u1_fld_pic_flag)244 WORD32 ih264d_insert_lt_node(dpb_manager_t *ps_dpb_mgr,
245 struct dpb_info_t *ps_mov_node,
246 UWORD32 u4_lt_idx,
247 UWORD8 u1_fld_pic_flag)
248 {
249 UWORD8 u1_mark_top_field_long_term = 0;
250 UWORD8 u1_mark_bot_field_long_term = 0;
251
252 {
253 if(u1_fld_pic_flag)
254 {
255 /* Assign corresponding field (top or bottom) long_term_frame_idx */
256
257 if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
258 && (ps_mov_node->s_bot_field.u1_reference_info
259 == IS_LONG_TERM))
260 {
261 if(ps_mov_node->u1_lt_idx == u4_lt_idx)
262 u1_mark_bot_field_long_term = 1;
263 else
264 {
265
266 UWORD32 i4_error_code;
267 i4_error_code = ERROR_DBP_MANAGER_T;
268
269 return i4_error_code;
270
271 }
272 }
273 else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
274 {
275 u1_mark_top_field_long_term = 1;
276 }
277
278 if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term))
279 {
280 UWORD32 i4_error_code;
281 i4_error_code = ERROR_DBP_MANAGER_T;
282 return i4_error_code;
283 }
284 }
285 else
286 {
287 ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM;
288 ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
289 ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
290 ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
291 }
292
293 ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node
294 ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx;
295 ps_mov_node->u1_used_as_ref = IS_LONG_TERM;
296
297 /* Insert the new long term in the LT list with u4_lt_idx */
298 /* in ascending order. */
299 if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
300 {
301 struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
302 if(u4_lt_idx < ps_next_dpb->u1_lt_idx)
303 {
304 //LTIndex to be inserted is the smallest LT index
305 //Update head and point prev to the next higher index
306 ps_mov_node->ps_prev_long = ps_next_dpb;
307 ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
308 }
309 else
310 {
311 WORD32 i;
312 struct dpb_info_t *ps_nxtDPB = ps_next_dpb;
313 ps_next_dpb = ps_next_dpb->ps_prev_long;
314 for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
315 {
316 if(ps_next_dpb->u1_lt_idx > u4_lt_idx)
317 break;
318 ps_nxtDPB = ps_next_dpb;
319 ps_next_dpb = ps_next_dpb->ps_prev_long;
320 }
321
322 ps_nxtDPB->ps_prev_long = ps_mov_node;
323 ps_mov_node->ps_prev_long = ps_next_dpb;
324 }
325 }
326 else
327 {
328 ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
329 ps_mov_node->ps_prev_long = NULL;
330 }
331 /* Identify the picture buffer as a long term picture buffer */
332 ps_mov_node->ps_pic_buf->u1_is_short = 0;
333
334 /* Increment LT buf count only if new LT node inserted */
335 /* If Increment during top_field is done, don't increment */
336 /* for bottom field, as both them are part of same pic. */
337 if(!u1_mark_bot_field_long_term)
338 ps_dpb_mgr->u1_num_lt_ref_bufs++;
339
340 }
341 return OK;
342 }
343
344 /*!
345 **************************************************************************
346 * \if Function name : ih264d_insert_st_node \endif
347 *
348 * \brief
349 * Adds a short term reference picture into the ST linked list
350 *
351 * \return
352 * None
353 *
354 * \note
355 * Called only for a new coded picture with nal_ref_idc!=0
356 **************************************************************************
357 */
ih264d_insert_st_node(dpb_manager_t * ps_dpb_mgr,struct pic_buffer_t * ps_pic_buf,UWORD8 u1_buf_id,UWORD32 u4_cur_pic_num)358 WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr,
359 struct pic_buffer_t *ps_pic_buf,
360 UWORD8 u1_buf_id,
361 UWORD32 u4_cur_pic_num)
362 {
363 WORD32 i;
364 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
365 UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype;
366 /* Find an unused dpb location */
367 for(i = 0; i < MAX_REF_BUFS; i++)
368 {
369 if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
370 && ps_dpb_info[i].u1_used_as_ref)
371 {
372 /* Can occur only for field bottom pictures */
373 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
374 return 0;
375 }
376
377 if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF)
378 && (ps_dpb_info[i].s_top_field.u1_reference_info
379 == UNUSED_FOR_REF)
380 && (ps_dpb_info[i].s_bot_field.u1_reference_info
381 == UNUSED_FOR_REF))
382 break;
383 }
384 if(i == MAX_REF_BUFS)
385 {
386 UWORD32 i4_error_code;
387 i4_error_code = ERROR_DBP_MANAGER_T;
388 return i4_error_code;
389 }
390
391 /* Create dpb info */
392 ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
393 ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
394 ps_dpb_info[i].u1_buf_id = u1_buf_id;
395 ps_dpb_info[i].u1_used_as_ref = TRUE;
396 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
397 ps_dpb_info[i].i4_frame_num = u4_cur_pic_num;
398 ps_dpb_info[i].ps_pic_buf->i4_frame_num = u4_cur_pic_num;
399
400 /* update the head node of linked list to point to the cur Pic */
401 ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
402
403 // Increment Short term bufCount
404 ps_dpb_mgr->u1_num_st_ref_bufs++;
405 /* Identify the picture as a short term picture buffer */
406 ps_pic_buf->u1_is_short = IS_SHORT_TERM;
407
408 if((u1_picture_type & 0x03) == FRM_PIC)
409 {
410 ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM;
411 ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
412 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
413 }
414
415 if((u1_picture_type & 0x03) == TOP_FLD)
416 ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
417
418 if((u1_picture_type & 0x03) == BOT_FLD)
419 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
420
421 return OK;
422 }
423
424 /*!
425 **************************************************************************
426 * \if Function name : ih264d_delete_st_node_or_make_lt \endif
427 *
428 * \brief
429 * Delete short term ref with a given picNum from the ST linked list or
430 * make it an LT node
431 *
432 * \return
433 * 0 - if successful; -1 - otherwise
434 *
435 * \note
436 * Common parts to MMCO==1 and MMCO==3 have been combined here
437 **************************************************************************
438 */
ih264d_delete_st_node_or_make_lt(dpb_manager_t * ps_dpb_mgr,WORD32 i4_pic_num,UWORD32 u4_lt_idx,UWORD8 u1_fld_pic_flag)439 WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr,
440 WORD32 i4_pic_num,
441 UWORD32 u4_lt_idx,
442 UWORD8 u1_fld_pic_flag)
443 {
444 WORD32 i;
445 struct dpb_info_t *ps_next_dpb;
446 WORD32 i4_frame_num = i4_pic_num;
447 struct dpb_info_t *ps_unmark_node = NULL;
448 UWORD8 u1_del_node = 0, u1_del_st = 0;
449 UWORD8 u1_reference_type = UNUSED_FOR_REF;
450 WORD32 ret;
451
452 if(u1_fld_pic_flag)
453 {
454 i4_frame_num = i4_frame_num >> 1;
455
456 if(u4_lt_idx == (MAX_REF_BUFS + 1))
457 u1_reference_type = UNUSED_FOR_REF;
458 else
459 u1_reference_type = IS_LONG_TERM;
460 }
461
462 //Find the node with matching picNum
463 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
464 if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num)
465 {
466 ps_unmark_node = ps_next_dpb;
467 }
468 else
469 {
470 for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
471 {
472 if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num)
473 break;
474 ps_next_dpb = ps_next_dpb->ps_prev_short;
475 }
476
477 if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
478 {
479 if(ps_dpb_mgr->u1_num_gaps)
480 {
481 ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st);
482 if(ret != OK)
483 return ret;
484 }
485 else
486 {
487 UWORD32 i4_error_code;
488 i4_error_code = ERROR_DBP_MANAGER_T;
489
490 return i4_error_code;
491 }
492
493 if(u1_del_st)
494 {
495 UWORD32 i4_error_code;
496 i4_error_code = ERROR_DBP_MANAGER_T;
497 return i4_error_code;
498 }
499 else
500 {
501 return 0;
502 }
503 }
504 else
505 ps_unmark_node = ps_next_dpb->ps_prev_short;
506 }
507
508 if(u1_fld_pic_flag)
509 {
510 /* Mark the corresponding field ( top or bot) as */
511 /* UNUSED_FOR_REF or IS_LONG_TERM depending on */
512 /* u1_reference_type. */
513 if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num)
514 {
515 ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type;
516 ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
517 {
518 UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
519 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
520 * ps_dpb_mgr->u2_pic_ht) >> 5);
521 /* memset the colocated zero u4_flag buffer */
522 memset(pu1_src, 0, i4_size);
523 }
524 }
525
526 else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num)
527 {
528
529 ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type;
530 ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
531 {
532 UWORD8 *pu1_src =
533 ps_unmark_node->ps_pic_buf->pu1_col_zero_flag
534 + ((ps_dpb_mgr->u2_pic_wd
535 * ps_dpb_mgr->u2_pic_ht)
536 >> 5);
537 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
538 * ps_dpb_mgr->u2_pic_ht) >> 5);
539 /* memset the colocated zero u4_flag buffer */
540 memset(pu1_src, 0, i4_size);
541 }
542 }
543 ps_unmark_node->u1_used_as_ref =
544 ps_unmark_node->s_top_field.u1_reference_info
545 | ps_unmark_node->s_bot_field.u1_reference_info;
546 }
547 else
548 {
549 ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
550 ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
551 ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
552
553 {
554 UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
555
556 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
557 * ps_dpb_mgr->u2_pic_ht) >> 4);
558 /* memset the colocated zero u4_flag buffer */
559 memset(pu1_src, 0, i4_size);
560 }
561 }
562
563 if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM))
564 {
565 if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
566 ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
567 else
568 ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link
569 ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count
570 u1_del_node = 1;
571 }
572
573 if(u4_lt_idx == MAX_REF_BUFS + 1)
574 {
575 if(u1_del_node)
576 {
577 // Release the physical buffer
578 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
579 ps_unmark_node->u1_buf_id);
580 ps_unmark_node->ps_prev_short = NULL;
581 }
582 }
583 else
584 {
585 WORD32 i4_status;
586 //If another node has the same LT index, delete that node
587 ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx,
588 u1_fld_pic_flag, ps_unmark_node, &i4_status);
589 if(ret != OK)
590 return ret;
591 // Now insert the short term node as a long term node
592 ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx,
593 u1_fld_pic_flag);
594 if(ret != OK)
595 return ret;
596 }
597 return OK;
598 }
599 /*!
600 **************************************************************************
601 * \if Function name : ih264d_reset_ref_bufs \endif
602 *
603 * \brief
604 * Called if MMCO==5/7 or on the first slice of an IDR picture
605 *
606 * \return
607 * none
608 **************************************************************************
609 */
ih264d_reset_ref_bufs(dpb_manager_t * ps_dpb_mgr)610 void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr)
611 {
612 WORD32 i;
613 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
614
615 for(i = 0; i < MAX_REF_BUFS; i++)
616 {
617 if(ps_dpb_info[i].u1_used_as_ref)
618 {
619 ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
620 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
621 ps_dpb_info[i].ps_prev_short = NULL;
622 ps_dpb_info[i].ps_prev_long = NULL;
623 ps_dpb_info[i].ps_pic_buf = NULL;
624 ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
625 ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
626 ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
627 ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
628
629 //Release physical buffer
630 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
631 ps_dpb_info[i].u1_buf_id);
632 }
633 }
634 ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
635 ps_dpb_mgr->ps_dpb_st_head = NULL;
636 ps_dpb_mgr->ps_dpb_ht_head = NULL;
637
638 /* release all gaps */
639 ps_dpb_mgr->u1_num_gaps = 0;
640 for(i = 0; i < MAX_FRAMES; i++)
641 {
642 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
643 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
644 ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
645 }
646 }
647
648 /*!
649 **************************************************************************
650 * \if Function name : Name \endif
651 *
652 * \brief
653 * create the default index list after an MMCO
654 *
655 * \return
656 * 0 - if no_error; -1 - error
657 *
658 **************************************************************************
659 */
ih264d_update_default_index_list(dpb_manager_t * ps_dpb_mgr)660 WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr)
661 {
662 WORD32 i;
663 struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
664
665 for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
666 {
667 ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
668 ps_next_dpb = ps_next_dpb->ps_prev_short;
669 }
670
671 ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
672 for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
673 {
674 ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
675 ps_next_dpb = ps_next_dpb->ps_prev_long;
676 }
677 return 0;
678 }
679
680 /*!
681 **************************************************************************
682 * \if Function name : ref_idx_reordering \endif
683 *
684 * \brief
685 * Parse the bitstream and reorder indices for the current slice
686 *
687 * \return
688 * 0 - if no_error; -1 - error
689 *
690 * \note
691 * Called only if ref_idx_reordering_flag_l0 is decoded as 1
692 * Remove error checking for unmatching picNum or LTIndex later (if not needed)
693 * \para
694 * This section implements 7.3.3.1 and 8.2.6.4
695 * Uses the default index list as the starting point and
696 * remaps the picNums sent to the next higher index in the
697 * modified list. The unmodified ones are copied from the
698 * default to modified list retaining their order in the default list.
699 *
700 **************************************************************************
701 */
ih264d_ref_idx_reordering(dec_struct_t * ps_dec,UWORD8 uc_lx)702 WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx)
703 {
704 dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr;
705 UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num;
706 /*< Maximum Picture Number Minus 1 */
707 UWORD16 ui_max_frame_num =
708 ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
709
710 WORD32 i;
711 UWORD32 ui_remapIdc, ui_nextUev;
712 WORD16 u2_pred_frame_num = u4_cur_pic_num;
713 WORD32 i_temp;
714 UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */
715 UWORD8 modCount = 0;
716 UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
717 UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
718 dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
719 UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
720
721 if(u1_field_pic_flag)
722 {
723 u4_cur_pic_num = u4_cur_pic_num * 2 + 1;
724 ui_max_frame_num = ui_max_frame_num * 2;
725 }
726
727 u2_pred_frame_num = u4_cur_pic_num;
728
729 ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
730
731 while(ui_remapIdc != 3)
732 {
733 ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
734 if(ui_remapIdc != 2)
735 {
736 ui_nextUev = ui_nextUev + 1;
737 if(ui_remapIdc == 0)
738 {
739 // diffPicNum is -ve
740 i_temp = u2_pred_frame_num - ui_nextUev;
741 if(i_temp < 0)
742 i_temp += ui_max_frame_num;
743 }
744 else
745 {
746 // diffPicNum is +ve
747 i_temp = u2_pred_frame_num + ui_nextUev;
748 if(i_temp >= ui_max_frame_num)
749 i_temp -= ui_max_frame_num;
750 }
751 /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */
752
753 if(i_temp > u4_cur_pic_num)
754 i_temp = i_temp - ui_max_frame_num;
755
756 for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
757 {
758 if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp)
759 break;
760 }
761 if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
762 {
763 UWORD32 i4_error_code;
764 i4_error_code = ERROR_DBP_MANAGER_T;
765 return i4_error_code;
766 }
767
768 u2_def_mod_flag |= (1 << i);
769 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
770 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
771 u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained
772 }
773 else //2
774 {
775 UWORD8 u1_lt_idx = (UWORD8)ui_nextUev;
776
777 for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
778 {
779 if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short)
780 {
781 if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num
782 == u1_lt_idx)
783 break;
784 }
785 }
786 if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
787 {
788 UWORD32 i4_error_code;
789 i4_error_code = ERROR_DBP_MANAGER_T;
790 return i4_error_code;
791 }
792
793 u2_def_mod_flag |= (1 << i);
794 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
795 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
796 }
797
798 ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
799 /* Get the remapping_idc - 0/1/2/3 */
800 }
801
802 //Handle the ref indices that were not remapped
803 for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++)
804 {
805 if(!(u2_def_mod_flag & (1 << i)))
806 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
807 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
808 }
809 return OK;
810 }
811 /*!
812 **************************************************************************
813 * \if Function name : ih264d_read_mmco_commands \endif
814 *
815 * \brief
816 * Parses MMCO commands and stores them in a structure for later use.
817 *
818 * \return
819 * 0 - No error; -1 - Error
820 *
821 * \note
822 * This function stores MMCO commands in structure only for the first time.
823 * In case of MMCO commands being issued for same Picture Number, they are
824 * just parsed and not stored them in the structure.
825 *
826 **************************************************************************
827 */
ih264d_read_mmco_commands(struct _DecStruct * ps_dec)828 WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
829 {
830 dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
831 dpb_commands_t *ps_dpb_cmds = ps_dec->ps_dpb_cmds;
832 dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
833 WORD32 j;
834 UWORD8 u1_buf_mode;
835 struct MMCParams *ps_mmc_params;
836 UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
837 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
838 UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst;
839
840 ps_slice->u1_mmco_equalto5 = 0;
841 {
842 if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL)
843 {
844 ps_slice->u1_no_output_of_prior_pics_flag =
845 ih264d_get_bit_h264(ps_bitstrm);
846 COPYTHECONTEXT("SH: no_output_of_prior_pics_flag",
847 ps_slice->u1_no_output_of_prior_pics_flag);
848 ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264(
849 ps_bitstrm);
850 COPYTHECONTEXT("SH: long_term_reference_flag",
851 ps_slice->u1_long_term_reference_flag);
852 ps_dpb_cmds->u1_idr_pic = 1;
853 ps_dpb_cmds->u1_no_output_of_prior_pics_flag =
854 ps_slice->u1_no_output_of_prior_pics_flag;
855 ps_dpb_cmds->u1_long_term_reference_flag =
856 ps_slice->u1_long_term_reference_flag;
857 }
858 else
859 {
860 u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary
861 COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode);
862 ps_dpb_cmds->u1_buf_mode = u1_buf_mode;
863 j = 0;
864
865 if(u1_buf_mode == 1)
866 {
867 UWORD32 u4_mmco;
868 UWORD32 u4_diff_pic_num;
869 UWORD32 u4_lt_idx, u4_max_lt_idx;
870
871 u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
872 pu4_bitstrm_buf);
873 while(u4_mmco != END_OF_MMCO)
874 {
875 ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
876 ps_mmc_params->u4_mmco = u4_mmco;
877 switch(u4_mmco)
878 {
879 case MARK_ST_PICNUM_AS_NONREF:
880 u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
881 pu4_bitstrm_buf);
882 //Get absDiffPicnumMinus1
883 ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
884 break;
885
886 case MARK_LT_INDEX_AS_NONREF:
887 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
888 pu4_bitstrm_buf);
889 ps_mmc_params->u4_lt_idx = u4_lt_idx;
890 break;
891
892 case MARK_ST_PICNUM_AS_LT_INDEX:
893 u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
894 pu4_bitstrm_buf);
895 ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
896 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
897 pu4_bitstrm_buf);
898 ps_mmc_params->u4_lt_idx = u4_lt_idx;
899 break;
900
901 case SET_MAX_LT_INDEX:
902 {
903 u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
904 pu4_bitstrm_buf);
905 ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx;
906 break;
907 }
908 case RESET_REF_PICTURES:
909 {
910 ps_slice->u1_mmco_equalto5 = 1;
911 break;
912 }
913
914 case SET_LT_INDEX:
915 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
916 pu4_bitstrm_buf);
917 ps_mmc_params->u4_lt_idx = u4_lt_idx;
918 break;
919
920 default:
921 break;
922 }
923 u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
924 pu4_bitstrm_buf);
925
926 j++;
927 }
928 ps_dpb_cmds->u1_num_of_commands = j;
929
930 }
931 }
932 ps_dpb_cmds->u1_dpb_commands_read = 1;
933 ps_dpb_cmds->u1_dpb_commands_read_slc = 1;
934
935 }
936 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst;
937 return u4_bit_ofst;
938 }
939
940 /*!
941 **************************************************************************
942 * \if Function name : ih264d_do_mmco_buffer \endif
943 *
944 * \brief
945 * Perform decoded picture buffer memory management control operations
946 *
947 * \return
948 * 0 - No error; -1 - Error
949 *
950 * \note
951 * Bitstream is also parsed here to get the MMCOs
952 *
953 **************************************************************************
954 */
ih264d_do_mmco_buffer(dpb_commands_t * ps_dpb_cmds,dpb_manager_t * ps_dpb_mgr,UWORD8 u1_numRef_frames_for_seq,UWORD32 u4_cur_pic_num,UWORD32 u2_u4_max_pic_num_minus1,UWORD8 u1_nal_unit_type,struct pic_buffer_t * ps_pic_buf,UWORD8 u1_buf_id,UWORD8 u1_fld_pic_flag,UWORD8 u1_curr_pic_in_err)955 WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
956 dpb_manager_t *ps_dpb_mgr,
957 UWORD8 u1_numRef_frames_for_seq, /*!< num_ref_frames from active SeqParSet*/
958 UWORD32 u4_cur_pic_num,
959 UWORD32 u2_u4_max_pic_num_minus1,
960 UWORD8 u1_nal_unit_type,
961 struct pic_buffer_t *ps_pic_buf,
962 UWORD8 u1_buf_id,
963 UWORD8 u1_fld_pic_flag,
964 UWORD8 u1_curr_pic_in_err)
965 {
966 WORD32 i;
967 UWORD8 u1_buf_mode, u1_marked_lt;
968 struct dpb_info_t *ps_next_dpb;
969 UWORD8 u1_num_gaps;
970 UWORD8 u1_del_node = 1;
971 UWORD8 u1_insert_st_pic = 1;
972 WORD32 ret;
973 UNUSED(u1_nal_unit_type);
974 UNUSED(u2_u4_max_pic_num_minus1);
975 u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive
976 u1_marked_lt = 0;
977 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
978
979 if(!u1_buf_mode)
980 {
981 //Sliding window - implements 8.2.5.3
982 if((ps_dpb_mgr->u1_num_st_ref_bufs
983 + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps)
984 == u1_numRef_frames_for_seq)
985 {
986 UWORD8 u1_new_node_flag = 1;
987 if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
988 {
989 UWORD32 i4_error_code;
990 i4_error_code = ERROR_DBP_MANAGER_T;
991 return i4_error_code;
992 }
993
994 // Chase the links to reach the last but one picNum, if available
995 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
996
997 if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
998 {
999 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1000 {
1001 /* Incase of filed pictures top_field has been allocated */
1002 /* picture buffer and complementary bottom field pair comes */
1003 /* then the sliding window mechanism should not allocate a */
1004 /* new node */
1005 u1_new_node_flag = 0;
1006 }
1007
1008 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1009 {
1010 if(ps_next_dpb == NULL)
1011 {
1012 UWORD32 i4_error_code;
1013 i4_error_code = ERROR_DBP_MANAGER_T;
1014 return i4_error_code;
1015 }
1016 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1017 {
1018 /* Incase of field pictures top_field has been allocated */
1019 /* picture buffer and complementary bottom field pair comes */
1020 /* then the sliding window mechanism should not allocate a */
1021 /* new node */
1022 u1_new_node_flag = 0;
1023 }
1024 ps_next_dpb = ps_next_dpb->ps_prev_short;
1025 }
1026
1027 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1028 {
1029 UWORD32 i4_error_code;
1030 i4_error_code = ERROR_DBP_MANAGER_T;
1031 return i4_error_code;
1032 }
1033
1034 if(u1_new_node_flag)
1035 {
1036 if(u1_num_gaps)
1037 {
1038 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1039 ps_next_dpb->ps_prev_short->i4_frame_num,
1040 &u1_del_node);
1041 if(ret != OK)
1042 return ret;
1043 }
1044
1045 if(u1_del_node)
1046 {
1047 ps_dpb_mgr->u1_num_st_ref_bufs--;
1048 ps_next_dpb->ps_prev_short->u1_used_as_ref =
1049 UNUSED_FOR_REF;
1050 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1051 UNUSED_FOR_REF;
1052 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1053 UNUSED_FOR_REF;
1054 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1055 ps_next_dpb->ps_prev_short->u1_buf_id);
1056 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1057 ps_next_dpb->ps_prev_short = NULL;
1058 }
1059 }
1060 }
1061 else
1062 {
1063 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1064 {
1065 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1066 ps_next_dpb->i4_frame_num,
1067 &u1_del_node);
1068 if(ret != OK)
1069 return ret;
1070 if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1071 && u1_del_node)
1072 {
1073 ps_dpb_mgr->u1_num_st_ref_bufs--;
1074 ps_next_dpb->u1_used_as_ref = FALSE;
1075 ps_next_dpb->s_top_field.u1_reference_info =
1076 UNUSED_FOR_REF;
1077 ps_next_dpb->s_bot_field.u1_reference_info =
1078 UNUSED_FOR_REF;
1079 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1080 ps_next_dpb->u1_buf_id);
1081 ps_next_dpb->ps_pic_buf = NULL;
1082 ps_next_dpb->ps_prev_short = NULL;
1083 ps_dpb_mgr->ps_dpb_st_head = NULL;
1084 ps_next_dpb = NULL;
1085 }
1086 else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1087 {
1088 if(u1_curr_pic_in_err)
1089 {
1090 u1_insert_st_pic = 0;
1091 }
1092 else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1093 {
1094 ps_dpb_mgr->u1_num_st_ref_bufs--;
1095 ps_next_dpb->u1_used_as_ref = FALSE;
1096 ps_next_dpb->s_top_field.u1_reference_info =
1097 UNUSED_FOR_REF;
1098 ps_next_dpb->s_bot_field.u1_reference_info =
1099 UNUSED_FOR_REF;
1100 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1101 ps_next_dpb->u1_buf_id);
1102 ps_next_dpb->ps_pic_buf = NULL;
1103 ps_next_dpb = NULL;
1104 }
1105 }
1106 }
1107 else
1108 {
1109 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1110 INVALID_FRAME_NUM,
1111 &u1_del_node);
1112 if(ret != OK)
1113 return ret;
1114 if(u1_del_node)
1115 {
1116 UWORD32 i4_error_code;
1117 i4_error_code = ERROR_DBP_MANAGER_T;
1118 return i4_error_code;
1119 }
1120 }
1121 }
1122 }
1123 }
1124 else
1125 {
1126 //Adaptive memory control - implements 8.2.5.4
1127 UWORD32 u4_mmco;
1128 UWORD32 u4_diff_pic_num;
1129 WORD32 i4_pic_num;
1130 UWORD32 u4_lt_idx;
1131 WORD32 j;
1132 struct MMCParams *ps_mmc_params;
1133
1134 for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
1135 {
1136 ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
1137 u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO
1138
1139 switch(u4_mmco)
1140 {
1141 case MARK_ST_PICNUM_AS_NONREF:
1142 {
1143
1144 {
1145 UWORD32 i4_cur_pic_num = u4_cur_pic_num;
1146 u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1147 if(u1_fld_pic_flag)
1148 i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
1149 i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1);
1150 }
1151
1152 if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1153 {
1154 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1155 i4_pic_num,
1156 MAX_REF_BUFS + 1,
1157 u1_fld_pic_flag);
1158 if(ret != OK)
1159 return ret;
1160 }
1161 else
1162 {
1163 UWORD8 u1_dummy;
1164 ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy);
1165 if(ret != OK)
1166 return ret;
1167 }
1168 break;
1169 }
1170 case MARK_LT_INDEX_AS_NONREF:
1171 {
1172 WORD32 i4_status;
1173 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1174 ret = ih264d_delete_lt_node(ps_dpb_mgr,
1175 u4_lt_idx,
1176 u1_fld_pic_flag,
1177 0, &i4_status);
1178 if(ret != OK)
1179 return ret;
1180 if(i4_status)
1181 {
1182 UWORD32 i4_error_code;
1183 i4_error_code = ERROR_DBP_MANAGER_T;
1184 return i4_error_code;
1185 }
1186 break;
1187 }
1188
1189 case MARK_ST_PICNUM_AS_LT_INDEX:
1190 {
1191 {
1192 UWORD32 i4_cur_pic_num = u4_cur_pic_num;
1193 u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1194 if(u1_fld_pic_flag)
1195 i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
1196
1197 i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1);
1198 }
1199
1200 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1201 if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1202 {
1203 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1204 i4_pic_num, u4_lt_idx,
1205 u1_fld_pic_flag);
1206 if(ret != OK)
1207 return ret;
1208 }
1209 break;
1210 }
1211 case SET_MAX_LT_INDEX:
1212 {
1213 UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
1214 u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
1215 if(u4_lt_idx < ps_dpb_mgr->u1_max_lt_pic_idx_plus1
1216 && uc_numLT > 0)
1217 {
1218 struct dpb_info_t *ps_nxtDPB;
1219 //Set all LT buffers with index >= u4_lt_idx to nonreference
1220 ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head;
1221 ps_next_dpb = ps_nxtDPB->ps_prev_long;
1222 if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx)
1223 {
1224 i = 0;
1225 ps_dpb_mgr->ps_dpb_ht_head = NULL;
1226 }
1227 else
1228 {
1229 for(i = 1; i < uc_numLT; i++)
1230 {
1231 if(ps_next_dpb->u1_lt_idx >= u4_lt_idx)
1232 break;
1233 ps_nxtDPB = ps_next_dpb;
1234 ps_next_dpb = ps_next_dpb->ps_prev_long;
1235 }
1236 ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max
1237 }
1238 ps_dpb_mgr->u1_num_lt_ref_bufs = i;
1239 if(i == 0)
1240 ps_next_dpb = ps_nxtDPB;
1241
1242 for(; i < uc_numLT; i++)
1243 {
1244 ps_nxtDPB = ps_next_dpb;
1245 ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1;
1246 ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF;
1247 ps_nxtDPB->s_top_field.u1_reference_info =
1248 UNUSED_FOR_REF;
1249 ps_nxtDPB->s_bot_field.u1_reference_info =
1250 UNUSED_FOR_REF;
1251
1252 ps_nxtDPB->ps_pic_buf = NULL;
1253 //Release buffer
1254 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1255 ps_nxtDPB->u1_buf_id);
1256 ps_next_dpb = ps_nxtDPB->ps_prev_long;
1257 ps_nxtDPB->ps_prev_long = NULL;
1258 }
1259 }
1260 ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx;
1261
1262 break;
1263 }
1264 case SET_LT_INDEX:
1265 {
1266 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1267 ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1268 u4_cur_pic_num);
1269 if(ret != OK)
1270 return ret;
1271 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1272 u4_cur_pic_num, u4_lt_idx,
1273 u1_fld_pic_flag);
1274 if(ret != OK)
1275 return ret;
1276 u1_marked_lt = 1;
1277 break;
1278 }
1279
1280 default:
1281 break;
1282 }
1283 if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES)
1284 {
1285 ih264d_reset_ref_bufs(ps_dpb_mgr);
1286 u4_cur_pic_num = 0;
1287 }
1288 }
1289 }
1290 if(!u1_marked_lt && u1_insert_st_pic)
1291 {
1292 ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1293 u4_cur_pic_num);
1294 if(ret != OK)
1295 return ret;
1296 }
1297 return OK;
1298 }
1299
1300 /*****************************************************************************/
1301 /* */
1302 /* Function Name : ih264d_release_pics_in_dpb */
1303 /* */
1304 /* Description : This function deletes all pictures from DPB */
1305 /* */
1306 /* Inputs : h_pic_buf_api: pointer to picture buffer API */
1307 /* u1_disp_bufs: number pictures ready for display */
1308 /* */
1309 /* Globals : None */
1310 /* Outputs : None */
1311 /* Returns : None */
1312 /* */
1313 /* Issues : None */
1314 /* */
1315 /* Revision History: */
1316 /* */
1317 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1318 /* 22 06 2005 NS Draft */
1319 /* */
1320 /*****************************************************************************/
ih264d_release_pics_in_dpb(void * pv_dec,UWORD8 u1_disp_bufs)1321 void ih264d_release_pics_in_dpb(void *pv_dec,
1322 UWORD8 u1_disp_bufs)
1323 {
1324 WORD8 i;
1325 dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
1326
1327 for(i = 0; i < u1_disp_bufs; i++)
1328 {
1329 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
1330 i,
1331 BUF_MGR_REF);
1332 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
1333 ps_dec->au1_pic_buf_id_mv_buf_id_map[i],
1334 BUF_MGR_REF);
1335 }
1336 }
1337
1338 /*****************************************************************************/
1339 /* */
1340 /* Function Name : ih264d_delete_gap_frm_sliding */
1341 /* */
1342 /* Description : This function deletes a picture from the list of gaps, */
1343 /* if the frame number of gap frame is lesser than the one */
1344 /* to be deleted by sliding window */
1345 /* Inputs : ps_dpb_mgr: pointer to dpb manager */
1346 /* i4_frame_num: frame number of picture that's going to */
1347 /* be deleted by sliding window */
1348 /* pu1_del_node: holds 0 if a gap is deleted else 1 */
1349 /* Globals : None */
1350 /* Processing : Function searches for frame number lesser than */
1351 /* i4_frame_num in the gaps list */
1352 /* Outputs : None */
1353 /* Returns : None */
1354 /* */
1355 /* Issues : None */
1356 /* */
1357 /* Revision History: */
1358 /* */
1359 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1360 /* 22 06 2005 NS Draft */
1361 /* */
1362 /*****************************************************************************/
ih264d_delete_gap_frm_sliding(dpb_manager_t * ps_dpb_mgr,WORD32 i4_frame_num,UWORD8 * pu1_del_node)1363 WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr,
1364 WORD32 i4_frame_num,
1365 UWORD8 *pu1_del_node)
1366 {
1367 WORD8 i1_gap_idx, i, j, j_min;
1368 WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
1369 WORD32 i4_start_frm_num, i4_end_frm_num;
1370 WORD32 i4_max_frm_num;
1371 WORD32 i4_frm_num, i4_gap_frm_num_min;
1372
1373 /* find the least frame num from gaps and current DPB node */
1374 /* Delete the least one */
1375 *pu1_del_node = 1;
1376 if(0 == ps_dpb_mgr->u1_num_gaps)
1377 return OK;
1378 pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
1379 pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
1380 i4_gap_frame_num = INVALID_FRAME_NUM;
1381 i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1382
1383 i1_gap_idx = -1;
1384 if(INVALID_FRAME_NUM != i4_frame_num)
1385 {
1386 i4_gap_frame_num = i4_frame_num;
1387 for(i = 0; i < MAX_FRAMES; i++)
1388 {
1389 i4_start_frm_num = pi4_gaps_start_frm_num[i];
1390 if(INVALID_FRAME_NUM != i4_start_frm_num)
1391 {
1392 i4_end_frm_num = pi4_gaps_end_frm_num[i];
1393 if(i4_end_frm_num < i4_max_frm_num)
1394 {
1395 if(i4_start_frm_num <= i4_gap_frame_num)
1396 {
1397 i4_gap_frame_num = i4_start_frm_num;
1398 i1_gap_idx = i;
1399 }
1400 }
1401 else
1402 {
1403 if(((i4_start_frm_num <= i4_gap_frame_num)
1404 && (i4_gap_frame_num <= i4_max_frm_num))
1405 || ((i4_start_frm_num >= i4_gap_frame_num)
1406 && ((i4_gap_frame_num
1407 + i4_max_frm_num)
1408 >= i4_end_frm_num)))
1409 {
1410 i4_gap_frame_num = i4_start_frm_num;
1411 i1_gap_idx = i;
1412 }
1413 }
1414 }
1415 }
1416 }
1417 else
1418 {
1419 /* no valid short term buffers, delete one gap from the least start */
1420 /* of gap sequence */
1421 i4_gap_frame_num = pi4_gaps_start_frm_num[0];
1422 i1_gap_idx = 0;
1423 for(i = 1; i < MAX_FRAMES; i++)
1424 {
1425 if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
1426 {
1427 if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
1428 {
1429 i4_gap_frame_num = pi4_gaps_start_frm_num[i];
1430 i1_gap_idx = i;
1431 }
1432 }
1433 }
1434 if(INVALID_FRAME_NUM == i4_gap_frame_num)
1435 {
1436 UWORD32 i4_error_code;
1437 i4_error_code = ERROR_DBP_MANAGER_T;
1438 return i4_error_code;
1439 }
1440 }
1441
1442 if(-1 != i1_gap_idx)
1443 {
1444 /* find least frame_num in the poc_map, which is in this range */
1445 i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
1446 if(i4_start_frm_num < 0)
1447 i4_start_frm_num += i4_max_frm_num;
1448 i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
1449 if(i4_end_frm_num < 0)
1450 i4_end_frm_num += i4_max_frm_num;
1451
1452 i4_gap_frm_num_min = 0xfffffff;
1453 j_min = MAX_FRAMES;
1454 for(j = 0; j < MAX_FRAMES; j++)
1455 {
1456 i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2];
1457 if((i4_start_frm_num <= i4_frm_num)
1458 && (i4_end_frm_num >= i4_frm_num))
1459 {
1460 if(i4_frm_num < i4_gap_frm_num_min)
1461 {
1462 j_min = j;
1463 i4_gap_frm_num_min = i4_frm_num;
1464 }
1465 }
1466 }
1467
1468 if(j_min != MAX_FRAMES)
1469 {
1470
1471 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1;
1472 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff;
1473 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM;
1474 ps_dpb_mgr->i1_gaps_deleted++;
1475
1476 ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
1477 ps_dpb_mgr->u1_num_gaps--;
1478 *pu1_del_node = 0;
1479 if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
1480 {
1481 ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] =
1482 INVALID_FRAME_NUM;
1483 ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
1484 }
1485 }
1486 }
1487
1488 return OK;
1489 }
1490
1491 /*****************************************************************************/
1492 /* */
1493 /* Function Name : ih264d_delete_gap_frm_mmco */
1494 /* */
1495 /* Description : This function deletes a picture from the list of gaps, */
1496 /* if the frame number (specified by mmco commands) to be */
1497 /* deleted is in the range by gap sequence. */
1498 /* */
1499 /* Inputs : ps_dpb_mgr: pointer to dpb manager */
1500 /* i4_frame_num: frame number of picture that's going to */
1501 /* be deleted by mmco */
1502 /* pu1_del_node: holds 0 if a gap is deleted else 1 */
1503 /* Globals : None */
1504 /* Processing : Function searches for frame number lesser in the range */
1505 /* specified by gap sequence */
1506 /* Outputs : None */
1507 /* Returns : None */
1508 /* */
1509 /* Issues : None */
1510 /* */
1511 /* Revision History: */
1512 /* */
1513 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1514 /* 22 06 2005 NS Draft */
1515 /* */
1516 /*****************************************************************************/
ih264d_delete_gap_frm_mmco(dpb_manager_t * ps_dpb_mgr,WORD32 i4_frame_num,UWORD8 * pu1_del_node)1517 WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr,
1518 WORD32 i4_frame_num,
1519 UWORD8 *pu1_del_node)
1520 {
1521 WORD8 i, j;
1522 WORD32 *pi4_start, *pi4_end;
1523 WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_frm_num;
1524
1525 /* find the least frame num from gaps and current DPB node */
1526 /* Delete the gaps */
1527 *pu1_del_node = 1;
1528 pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
1529 pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
1530 i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1531
1532 if(0 == ps_dpb_mgr->u1_num_gaps)
1533 return OK;
1534
1535 if(i4_frame_num < 0)
1536 i4_frame_num += i4_max_frm_num;
1537 for(i = 0; i < MAX_FRAMES; i++)
1538 {
1539 i4_start_frm_num = pi4_start[i];
1540 if(i4_start_frm_num < 0)
1541 i4_start_frm_num += i4_max_frm_num;
1542 if(INVALID_FRAME_NUM != i4_start_frm_num)
1543 {
1544 i4_end_frm_num = pi4_end[i];
1545 if(i4_end_frm_num < 0)
1546 i4_end_frm_num += i4_max_frm_num;
1547
1548 if((i4_frame_num >= i4_start_frm_num)
1549 && (i4_frame_num <= i4_end_frm_num))
1550 {
1551 break;
1552 }
1553 else
1554 {
1555 if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num)
1556 && ((i4_frame_num + i4_max_frm_num)
1557 <= i4_end_frm_num))
1558 {
1559 UWORD32 i4_error_code;
1560 i4_error_code = ERROR_DBP_MANAGER_T;
1561 return i4_error_code;
1562 }
1563 }
1564 }
1565 }
1566
1567 /* find frame_num index, in the poc_map which needs to be deleted */
1568 for(j = 0; j < MAX_FRAMES; j++)
1569 {
1570 if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2])
1571 break;
1572 }
1573
1574 if(MAX_FRAMES != i)
1575 {
1576 if(j == MAX_FRAMES)
1577 {
1578 UWORD32 i4_error_code;
1579 i4_error_code = ERROR_DBP_MANAGER_T;
1580 return i4_error_code;
1581 }
1582
1583 ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1;
1584 ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff;
1585 ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM;
1586 ps_dpb_mgr->i1_gaps_deleted++;
1587
1588 ps_dpb_mgr->ai1_gaps_per_seq[i]--;
1589 ps_dpb_mgr->u1_num_gaps--;
1590 *pu1_del_node = 0;
1591 if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
1592 {
1593 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
1594 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
1595 }
1596 }
1597 else
1598 {
1599 UWORD32 i4_error_code;
1600 i4_error_code = ERROR_DBP_MANAGER_T;
1601 return i4_error_code;
1602 }
1603
1604 return OK;
1605 }
1606
1607 /*!
1608 **************************************************************************
1609 * \if Function name : ih264d_do_mmco_for_gaps \endif
1610 *
1611 * \brief
1612 * Perform decoded picture buffer memory management control operations
1613 *
1614 * \return
1615 * 0 - No error; -1 - Error
1616 *
1617 * \note
1618 * Bitstream is also parsed here to get the MMCOs
1619 *
1620 **************************************************************************
1621 */
ih264d_do_mmco_for_gaps(dpb_manager_t * ps_dpb_mgr,UWORD8 u1_num_ref_frames)1622 WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr,
1623 UWORD8 u1_num_ref_frames /*!< num_ref_frames from active SeqParSet*/
1624 )
1625 {
1626 struct dpb_info_t *ps_next_dpb;
1627 UWORD8 u1_num_gaps;
1628 UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node;
1629 WORD8 i;
1630 WORD32 i4_frame_gaps = 1;
1631 WORD32 ret;
1632
1633 //Sliding window - implements 8.2.5.3, flush out buffers
1634 u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
1635 u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
1636
1637 while(1)
1638 {
1639 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1640 if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps)
1641 > u1_num_ref_frames)
1642 {
1643 if(0 == (u1_st_ref_bufs + u1_num_gaps))
1644 {
1645 i4_frame_gaps = 0;
1646 ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames
1647 - u1_lt_ref_bufs);
1648 }
1649 else
1650 {
1651 u1_del_node = 1;
1652 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1653
1654 if(u1_st_ref_bufs > 1)
1655 {
1656 for(i = 1; i < (u1_st_ref_bufs - 1); i++)
1657 {
1658 if(ps_next_dpb == NULL)
1659 {
1660 UWORD32 i4_error_code;
1661 i4_error_code = ERROR_DBP_MANAGER_T;
1662 return i4_error_code;
1663 }
1664 ps_next_dpb = ps_next_dpb->ps_prev_short;
1665 }
1666
1667 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1668 {
1669 return ERROR_DBP_MANAGER_T;
1670 }
1671
1672 if(u1_num_gaps)
1673 {
1674 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1675 ps_next_dpb->ps_prev_short->i4_frame_num,
1676 &u1_del_node);
1677 if(ret != OK)
1678 return ret;
1679 }
1680
1681 if(u1_del_node)
1682 {
1683 u1_st_ref_bufs--;
1684 ps_next_dpb->ps_prev_short->u1_used_as_ref =
1685 UNUSED_FOR_REF;
1686 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1687 UNUSED_FOR_REF;
1688 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1689 UNUSED_FOR_REF;
1690 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1691 ps_next_dpb->ps_prev_short->u1_buf_id);
1692 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1693 ps_next_dpb->ps_prev_short = NULL;
1694 }
1695 }
1696 else
1697 {
1698 if(u1_st_ref_bufs)
1699 {
1700 if(u1_num_gaps)
1701 {
1702 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1703 ps_next_dpb->i4_frame_num,
1704 &u1_del_node);
1705 if(ret != OK)
1706 return ret;
1707 }
1708
1709 if(u1_del_node)
1710 {
1711 u1_st_ref_bufs--;
1712 ps_next_dpb->u1_used_as_ref = FALSE;
1713 ps_next_dpb->s_top_field.u1_reference_info =
1714 UNUSED_FOR_REF;
1715 ps_next_dpb->s_bot_field.u1_reference_info =
1716 UNUSED_FOR_REF;
1717 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1718 ps_next_dpb->u1_buf_id);
1719 ps_next_dpb->ps_pic_buf = NULL;
1720 ps_next_dpb = NULL;
1721 ps_dpb_mgr->ps_dpb_st_head = NULL;
1722 ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1723 }
1724 }
1725 else
1726 {
1727 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1728 INVALID_FRAME_NUM,
1729 &u1_del_node);
1730 if(ret != OK)
1731 return ret;
1732 if(u1_del_node)
1733 {
1734 return ERROR_DBP_MANAGER_T;
1735 }
1736 }
1737 }
1738 }
1739 }
1740 else
1741 {
1742 ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
1743 break;
1744 }
1745 }
1746
1747 ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1748
1749 return OK;
1750 }
1751 /****************************************************************************/
1752 /* */
1753 /* Function Name : ih264d_free_node_from_dpb */
1754 /* */
1755 /* Description : */
1756 /* */
1757 /* Inputs : */
1758 /* */
1759 /* Globals : */
1760 /* */
1761 /* Processing : */
1762 /* */
1763 /* Outputs : */
1764 /* */
1765 /* Returns : */
1766 /* */
1767 /* Known Issues : */
1768 /* */
1769 /* Revision History */
1770 /* */
1771 /* DD MM YY Author Changes */
1772 /* Sarat */
1773 /****************************************************************************/
1774 /**** Function Added for Error Resilience *****/
ih264d_free_node_from_dpb(dpb_manager_t * ps_dpb_mgr,UWORD32 u4_cur_pic_num,UWORD8 u1_numRef_frames_for_seq)1775 WORD32 ih264d_free_node_from_dpb(dpb_manager_t *ps_dpb_mgr,
1776 UWORD32 u4_cur_pic_num,
1777 UWORD8 u1_numRef_frames_for_seq)
1778 {
1779 WORD32 i;
1780 UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1781 struct dpb_info_t *ps_next_dpb;
1782 UWORD8 u1_del_node = 1;
1783 WORD32 ret;
1784
1785 //Sliding window - implements 8.2.5.3
1786 if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs
1787 + u1_num_gaps) == u1_numRef_frames_for_seq)
1788 {
1789 UWORD8 u1_new_node_flag = 1;
1790 if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1791 {
1792 return ERROR_DBP_MANAGER_T;
1793 }
1794
1795 // Chase the links to reach the last but one picNum, if available
1796 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1797
1798 if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1799 {
1800 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1801 {
1802 /* Incase of filed pictures top_field has been allocated */
1803 /* picture buffer and complementary bottom field pair comes */
1804 /* then the sliding window mechanism should not allocate a */
1805 /* new node */
1806 u1_new_node_flag = 0;
1807 }
1808
1809 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1810 {
1811 if(ps_next_dpb == NULL)
1812 return ERROR_DBP_MANAGER_T;
1813
1814 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1815 {
1816 /* Incase of field pictures top_field has been allocated */
1817 /* picture buffer and complementary bottom field pair comes */
1818 /* then the sliding window mechanism should not allocate a */
1819 /* new node */
1820 u1_new_node_flag = 0;
1821 }
1822 ps_next_dpb = ps_next_dpb->ps_prev_short;
1823 }
1824
1825 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1826 return ERROR_DBP_MANAGER_T;
1827
1828 if(u1_new_node_flag)
1829 {
1830 if(u1_num_gaps)
1831 {
1832 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1833 ps_next_dpb->ps_prev_short->i4_frame_num,
1834 &u1_del_node);
1835 if(ret != OK)
1836 return ret;
1837 }
1838
1839 if(u1_del_node)
1840 {
1841 ps_dpb_mgr->u1_num_st_ref_bufs--;
1842 ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF;
1843 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1844 UNUSED_FOR_REF;
1845 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1846 UNUSED_FOR_REF;
1847 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1848 ps_next_dpb->ps_prev_short->u1_buf_id);
1849 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1850 ps_next_dpb->ps_prev_short = NULL;
1851 }
1852 }
1853 }
1854 else
1855 {
1856 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1857 {
1858 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1859 ps_next_dpb->i4_frame_num,
1860 &u1_del_node);
1861 if(ret != OK)
1862 return ret;
1863 if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1864 && u1_del_node)
1865 {
1866 ps_dpb_mgr->u1_num_st_ref_bufs--;
1867 ps_next_dpb->u1_used_as_ref = FALSE;
1868 ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1869 ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1870 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1871 ps_next_dpb->u1_buf_id);
1872 ps_next_dpb->ps_pic_buf = NULL;
1873 ps_next_dpb = NULL;
1874 }
1875 }
1876 else
1877 {
1878 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
1879 if(ret != OK)
1880 return ret;
1881 if(u1_del_node)
1882 return ERROR_DBP_MANAGER_T;
1883 }
1884 }
1885 }
1886 return OK;
1887 }
1888 /*****************************************************************************/
1889 /* */
1890 /* Function Name : ih264d_delete_nonref_nondisplay_pics */
1891 /* */
1892 /* Description : */
1893 /* */
1894 /* */
1895 /* Inputs : */
1896 /* Globals : */
1897 /* Processing : */
1898 /* */
1899 /* Outputs : */
1900 /* Returns : */
1901 /* */
1902 /* Issues : */
1903 /* */
1904 /* Revision History: */
1905 /* */
1906 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1907 /* 05 06 2007 Varun Draft */
1908 /* */
1909 /*****************************************************************************/
1910
ih264d_delete_nonref_nondisplay_pics(dpb_manager_t * ps_dpb_mgr)1911 void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr)
1912 {
1913 WORD8 i;
1914 WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
1915
1916 /* remove all gaps marked as unused for ref */
1917 for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
1918 {
1919 if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
1920 {
1921 ps_dpb_mgr->i1_gaps_deleted--;
1922 ps_dpb_mgr->i1_poc_buf_id_entries--;
1923 i4_poc_buf_id_map[i][0] = -1;
1924 i4_poc_buf_id_map[i][1] = 0x7fffffff;
1925 i4_poc_buf_id_map[i][2] = 0;
1926 }
1927 }
1928 }
1929 /*****************************************************************************/
1930 /* */
1931 /* Function Name : ih264d_insert_pic_in_display_list */
1932 /* */
1933 /* Description : */
1934 /* */
1935 /* */
1936 /* Inputs : */
1937 /* Globals : */
1938 /* Processing : */
1939 /* */
1940 /* Outputs : */
1941 /* Returns : */
1942 /* */
1943 /* Issues : */
1944 /* */
1945 /* Revision History: */
1946 /* */
1947 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1948 /* 05 06 2007 Varun Draft */
1949 /* */
1950 /*****************************************************************************/
1951
ih264d_insert_pic_in_display_list(dpb_manager_t * ps_dpb_mgr,UWORD8 u1_buf_id,WORD32 i4_display_poc,UWORD32 u4_frame_num)1952 WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr,
1953 UWORD8 u1_buf_id,
1954 WORD32 i4_display_poc,
1955 UWORD32 u4_frame_num)
1956 {
1957 WORD8 i;
1958 WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
1959
1960 for(i = 0; i < MAX_FRAMES; i++)
1961 {
1962 /* Find an empty slot */
1963 if(i4_poc_buf_id_map[i][0] == -1)
1964 {
1965 if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
1966 ps_dpb_mgr->i1_gaps_deleted--;
1967 else
1968 ps_dpb_mgr->i1_poc_buf_id_entries++;
1969
1970 i4_poc_buf_id_map[i][0] = u1_buf_id;
1971 i4_poc_buf_id_map[i][1] = i4_display_poc;
1972 i4_poc_buf_id_map[i][2] = u4_frame_num;
1973
1974 break;
1975 }
1976 }
1977
1978 if(MAX_FRAMES == i)
1979 {
1980
1981 UWORD32 i4_error_code;
1982 i4_error_code = ERROR_GAPS_IN_FRM_NUM;
1983 return i4_error_code;
1984 }
1985 return OK;
1986 }
1987
1988