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