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