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