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