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