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