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