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