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