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