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