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