1 2 /*! 3 *********************************************************************** 4 * \file: h264_dpb_ctl.c 5 * 6 *********************************************************************** 7 */ 8 9 #include "viddec_fw_debug.h" 10 #include "viddec_parser_ops.h" 11 12 #include "viddec_fw_workload.h" 13 #include "viddec_pm.h" 14 #include "viddec_h264_parse.h" 15 16 17 18 //#include <limits.h> 19 #include "h264parse.h" 20 #include "h264parse_dpb.h" 21 //#include "h264_debug.h" 22 23 #ifndef NULL 24 #define NULL 0 25 #endif 26 //#ifndef USER_MODE 27 //#define NULL 0 28 //#endif 29 30 ////////////////////////// Declare Globals/////////////////////////////// 31 frame_store *active_fs; 32 33 /* ------------------------------------------------------------------------------------------ */ 34 /* ------------------------------------------------------------------------------------------ */ 35 /* ------------------------------------------------------------------------------------------ */ 36 ///////////////////////// DPB init ////////////////////////////////////////// 37 ////////////////////////////////////////////////////////////////////////////// 38 // Init DPB 39 // Description: init dpb, which should be called while open 40 // 41 ////////////////////////////////////////////////////////////////////////////// 42 43 void h264_init_dpb(h264_DecodedPictureBuffer * p_dpb) 44 { 45 int32_t i; 46 47 //// Init DPB to zero 48 //h264_memset(p_dpb, 0x0, sizeof(h264_DecodedPictureBuffer) ); 49 50 51 for(i=0;i<NUM_DPB_FRAME_STORES;i++) 52 { 53 p_dpb->fs[i].fs_idc = MPD_DPB_FS_NULL_IDC; 54 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC; 55 } 56 p_dpb->used_size = 0; 57 p_dpb->fs_dec_idc = MPD_DPB_FS_NULL_IDC; 58 p_dpb->fs_non_exist_idc = MPD_DPB_FS_NULL_IDC; 59 60 return; 61 } 62 63 64 ///////////////////////// Reference list management ////////////////////////// 65 66 /* ------------------------------------------------------------------------------------------ */ 67 /* ------------------------------------------------------------------------------------------ */ 68 /* ------------------------------------------------------------------------------------------ */ 69 ////////////////////////////////////////////////////////////////////////////// 70 // h264_dpb_add_ref_list () 71 // 72 // Adds an idc to the long term reference list 73 ////////////////////////////////////////////////////////////////////////////// 74 void h264_dpb_add_ref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc) 75 { 76 p_dpb->fs_ref_idc[p_dpb->ref_frames_in_buffer] = ref_idc; 77 p_dpb->ref_frames_in_buffer++; 78 } 79 /* ------------------------------------------------------------------------------------------ */ 80 /* ------------------------------------------------------------------------------------------ */ 81 /* ------------------------------------------------------------------------------------------ */ 82 ////////////////////////////////////////////////////////////////////////////// 83 // h264_dpb_add_ltref_list () 84 // 85 // Adds an idc to the long term reference list 86 ////////////////////////////////////////////////////////////////////////////// 87 void h264_dpb_add_ltref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc) 88 { 89 p_dpb->fs_ltref_idc[p_dpb->ltref_frames_in_buffer] = ref_idc; 90 p_dpb->ltref_frames_in_buffer++; 91 } 92 /* ------------------------------------------------------------------------------------------ */ 93 /* ------------------------------------------------------------------------------------------ */ 94 /* ------------------------------------------------------------------------------------------ */ 95 ////////////////////////////////////////////////////////////////////////////// 96 // h264_dpb_update_all_ref_lists (h264_DecodedPictureBuffer * p_dpb,int32_t NonExisting) 97 // 98 // Decide whether the current picture needs to be added to the reference lists 99 // active_fs should be set-up prior to calling this function 100 // 101 // Check if we need to search the lists here 102 // or can we go straight to adding to ref lists.. 103 ////////////////////////////////////////////////////////////////////////////// 104 105 void h264_dpb_insert_ref_lists(h264_DecodedPictureBuffer * p_dpb, int32_t NonExisting) 106 { 107 if(NonExisting) 108 h264_dpb_set_active_fs(p_dpb,p_dpb->fs_non_exist_idc); 109 else 110 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 111 112 //if(active_fs->is_reference) 113 if(active_fs->frame.used_for_reference) 114 { 115 if(viddec_h264_get_is_long_term(active_fs)) 116 { 117 if(viddec_h264_get_dec_structure(active_fs) == FRAME) 118 h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc); 119 else 120 { 121 uint32_t found_in_list = 0, i = 0; 122 for (i = 0; (i < p_dpb->ltref_frames_in_buffer) && (found_in_list == 0); i++) { 123 if(p_dpb->fs_ltref_idc[i] == active_fs->fs_idc) found_in_list = 1; 124 } 125 126 if(found_in_list == 0) h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc); 127 } 128 } 129 else 130 { 131 if(viddec_h264_get_dec_structure(active_fs) == FRAME) { 132 h264_dpb_add_ref_list(p_dpb, active_fs->fs_idc); 133 } else 134 { 135 uint32_t found_in_list = 0, i = 0; 136 137 for (i = 0; (i < p_dpb->ref_frames_in_buffer) && (found_in_list == 0); i++) 138 { 139 if(p_dpb->fs_ref_idc[i] == active_fs->fs_idc) found_in_list = 1; 140 } 141 142 if(found_in_list == 0) h264_dpb_add_ref_list(p_dpb, active_fs->fs_idc); 143 } 144 } 145 } 146 147 return; 148 149 } 150 151 /* ------------------------------------------------------------------------------------------ */ 152 /* ------------------------------------------------------------------------------------------ */ 153 /* ------------------------------------------------------------------------------------------ */ 154 ////////////////////////////////////////////////////////////////////////////// 155 // Set active fs 156 ////////////////////////////////////////////////////////////////////////////// 157 158 void h264_dpb_set_active_fs(h264_DecodedPictureBuffer * p_dpb, int32_t index) 159 { 160 active_fs = &p_dpb->fs[index]; 161 } 162 /* ------------------------------------------------------------------------------------------ */ 163 /* ------------------------------------------------------------------------------------------ */ 164 /* ------------------------------------------------------------------------------------------ */ 165 ////////////////////////////////////////////////////////////////////////////// 166 // Sort reference list 167 ////////////////////////////////////////////////////////////////////////////// 168 169 void h264_list_sort(uint8_t *list, int32_t *sort_indices, int32_t size, int32_t desc) 170 { 171 int32_t j, k, temp, idc; 172 173 // Dodgy looking for embedded code here... 174 if(size > 1) 175 { 176 for (j = 0; j < size-1; j = j + 1) { 177 for (k = j + 1; k < size; k = k + 1) { 178 if ((desc & (sort_indices[j] < sort_indices[k]))| 179 (~desc & (sort_indices[j] > sort_indices[k])) ) 180 { 181 temp = sort_indices[k]; 182 sort_indices[k] = sort_indices[j]; 183 sort_indices[j] = temp; 184 idc = list[k]; 185 list[k] = list[j]; 186 list[j] = idc; 187 } 188 } 189 } 190 } 191 } 192 193 /* ------------------------------------------------------------------------------------------ */ 194 /* ------------------------------------------------------------------------------------------ */ 195 /* ------------------------------------------------------------------------------------------ */ 196 ////////////////////////////////////////////////////////////////////////////// 197 // h264_dpb_pic_is_bottom_field_ref () 198 // 199 // Used to sort a list based on a corresponding sort indices 200 ////////////////////////////////////////////////////////////////////////////// 201 202 int32_t h264_dpb_pic_is_bottom_field_ref(int32_t long_term) 203 { 204 int32_t temp; 205 if(long_term) temp = ((active_fs->bottom_field.used_for_reference) && (active_fs->bottom_field.is_long_term)) ? 1 : 0; 206 else temp = ((active_fs->bottom_field.used_for_reference) && !(active_fs->bottom_field.is_long_term)) ? 1 : 0; 207 208 return temp; 209 } 210 /* ------------------------------------------------------------------------------------------ */ 211 /* ------------------------------------------------------------------------------------------ */ 212 /* ------------------------------------------------------------------------------------------ */ 213 ////////////////////////////////////////////////////////////////////////////// 214 // h264_dpb_pic_is_top_field_ref () 215 // 216 // Used to sort a list based on a corresponding sort indices 217 ////////////////////////////////////////////////////////////////////////////// 218 219 int32_t h264_dpb_pic_is_top_field_ref(int32_t long_term) 220 { 221 int32_t temp; 222 if(long_term) 223 temp = ((active_fs->top_field.used_for_reference) && (active_fs->top_field.is_long_term)) ? 1 : 0; 224 else 225 temp = ((active_fs->top_field.used_for_reference) && !(active_fs->top_field.is_long_term)) ? 1 : 0; 226 227 return temp; 228 } 229 230 231 /* ------------------------------------------------------------------------------------------ */ 232 /* ------------------------------------------------------------------------------------------ */ 233 /* ------------------------------------------------------------------------------------------ */ 234 ////////////////////////////////////////////////////////////////////////////// 235 // h264_dpb_gen_pic_list_from_frame_list () 236 // 237 // Used to sort a list based on a corresponding sort indices 238 ////////////////////////////////////////////////////////////////////////////// 239 240 int32_t h264_dpb_gen_pic_list_from_frame_list(h264_DecodedPictureBuffer *p_dpb, uint8_t *pic_list, uint8_t *frame_list, int32_t currPicStructure, int32_t list_size, int32_t long_term) 241 { 242 int32_t top_idx, bot_idx, got_pic, list_idx; 243 int32_t lterm; 244 245 list_idx = 0; 246 lterm = (long_term)? 1:0; 247 248 if(list_size){ 249 250 251 top_idx = 0; 252 bot_idx = 0; 253 254 if (currPicStructure == TOP_FIELD) { 255 while ((top_idx < list_size)||(bot_idx < list_size)) 256 { 257 /////////////////////////////////////////// ref Top Field 258 got_pic = 0; 259 while ((top_idx < list_size) & ~got_pic) 260 { 261 h264_dpb_set_active_fs(p_dpb, frame_list[top_idx]); 262 if ((viddec_h264_get_is_used(active_fs))&0x1) 263 { 264 if(h264_dpb_pic_is_top_field_ref(long_term)) 265 { 266 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[top_idx] + PUT_LIST_INDEX_FIELD_BIT(0); // top_field 267 list_idx++; 268 got_pic = 1; 269 } 270 } 271 top_idx++; 272 } 273 274 /////////////////////////////////////////// ref Bottom Field 275 got_pic = 0; 276 while ((bot_idx < list_size) & ~got_pic) 277 { 278 h264_dpb_set_active_fs(p_dpb, frame_list[bot_idx]); 279 if ((viddec_h264_get_is_used(active_fs))&0x2) 280 { 281 if(h264_dpb_pic_is_bottom_field_ref(long_term)) 282 { 283 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[bot_idx] + PUT_LIST_INDEX_FIELD_BIT(1); // bottom_field 284 list_idx++; 285 got_pic = 1; 286 } 287 } 288 bot_idx++; 289 } 290 } 291 } 292 293 /////////////////////////////////////////////// current Bottom Field 294 if (currPicStructure == BOTTOM_FIELD) { 295 while ((top_idx < list_size)||(bot_idx < list_size)) 296 { 297 /////////////////////////////////////////// ref Top Field 298 got_pic = 0; 299 while ((bot_idx < list_size) && (!(got_pic))) 300 { 301 h264_dpb_set_active_fs(p_dpb, frame_list[bot_idx]); 302 if ((viddec_h264_get_is_used(active_fs))&0x2) { 303 if(h264_dpb_pic_is_bottom_field_ref(long_term)) { 304 // short term ref pic 305 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[bot_idx] + PUT_LIST_INDEX_FIELD_BIT(1); // bottom_field 306 list_idx++; 307 got_pic = 1; 308 } 309 } 310 bot_idx++; 311 } 312 313 /////////////////////////////////////////// ref Bottom Field 314 got_pic = 0; 315 while ((top_idx < list_size) && (!(got_pic))) 316 { 317 h264_dpb_set_active_fs(p_dpb, frame_list[top_idx]); 318 if ((viddec_h264_get_is_used(active_fs))&0x1) { 319 if(h264_dpb_pic_is_top_field_ref(long_term)){ 320 // short term ref pic 321 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[top_idx] + PUT_LIST_INDEX_FIELD_BIT(0); // top_field 322 list_idx++; 323 got_pic = 1; 324 } 325 } 326 top_idx++; 327 } 328 } 329 } 330 } 331 332 return list_idx; 333 } 334 335 /* ------------------------------------------------------------------------------------------ */ 336 /* ------------------------------------------------------------------------------------------ */ 337 /* ------------------------------------------------------------------------------------------ */ 338 ////////////////////////////////////////////////////////////////////////////// 339 // h264_dpb_remove_ref_list () 340 // 341 // Removes an idc from the refernce list and updates list after 342 // 343 344 void h264_dpb_remove_ref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc) 345 { 346 uint8_t idx = 0; 347 int32_t Found = 0; 348 349 while ((idx < p_dpb->ref_frames_in_buffer) && (!(Found))) 350 { 351 if (p_dpb->fs_ref_idc[idx] == ref_idc) 352 Found = 1; 353 else 354 idx++; 355 } 356 357 if (Found) 358 { 359 // Move the remainder of the list up one 360 while(idx < p_dpb->ref_frames_in_buffer - 1) { 361 p_dpb->fs_ref_idc[idx] = p_dpb->fs_ref_idc[idx + 1]; 362 idx ++; 363 } 364 365 p_dpb->fs_ref_idc[idx] = MPD_DPB_FS_NULL_IDC; // Clear the last one 366 p_dpb->ref_frames_in_buffer--; 367 } 368 369 return; 370 } 371 /* ------------------------------------------------------------------------------------------ */ 372 /* ------------------------------------------------------------------------------------------ */ 373 /* ------------------------------------------------------------------------------------------ */ 374 ////////////////////////////////////////////////////////////////////////////// 375 // h264_dpb_remove_ltref_list () 376 // 377 // Removes an idc from the long term reference list and updates list after 378 ////////////////////////////////////////////////////////////////////////////// 379 380 void h264_dpb_remove_ltref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc) 381 { 382 uint8_t idx = 0; 383 int32_t Found = 0; 384 385 while ((idx < p_dpb->ltref_frames_in_buffer) && (!(Found))) 386 { 387 if (p_dpb->fs_ltref_idc[idx] == ref_idc) Found = 1; 388 else idx++; 389 } 390 391 if (Found) 392 { 393 // Move the remainder of the list up one 394 while(idx <(uint8_t)(p_dpb->ltref_frames_in_buffer - 1)) 395 { 396 p_dpb->fs_ltref_idc[idx] = p_dpb->fs_ltref_idc[idx + 1]; 397 idx ++; 398 } 399 p_dpb->fs_ltref_idc[idx] = MPD_DPB_FS_NULL_IDC; // Clear the last one 400 401 p_dpb->ltref_frames_in_buffer--; 402 } 403 404 return; 405 } 406 407 408 /* ------------------------------------------------------------------------------------------ */ 409 /* ------------------------------------------------------------------------------------------ */ 410 /* ------------------------------------------------------------------------------------------ */ 411 ////////////////////////////////////////////////////////////////////////////// 412 // h264_dpb_init_lists () 413 // 414 // Used to initialise the reference lists 415 // Also assigns picture numbers and long term picture numbers if P OR B slice 416 ////////////////////////////////////////////////////////////////////////////// 417 void h264_dpb_update_ref_lists(h264_Info * pInfo) 418 { 419 h264_DecodedPictureBuffer * p_dpb = &pInfo->dpb; 420 421 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4); 422 423 uint8_t list0idx, list0idx_1, listltidx; 424 uint8_t idx; 425 426 uint8_t add_top, add_bottom, diff; 427 uint8_t list_idc; 428 uint8_t check_non_existing, skip_picture; 429 430 431 uint8_t gen_pic_fs_list0[16]; 432 uint8_t gen_pic_fs_list1[16]; 433 uint8_t gen_pic_fs_listlt[16]; 434 uint8_t gen_pic_pic_list[32]; // check out these sizes... 435 436 uint8_t sort_fs_idc[16]; 437 int32_t list_sort_number[16]; 438 439 #ifdef DUMP_HEADER_INFO 440 static int cc1 = 0; 441 //OS_INFO("-------------cc1= %d\n",cc1); /////// DEBUG info 442 if(cc1 == 255) 443 idx = 0; 444 #endif 445 446 list0idx = list0idx_1 = listltidx = 0; 447 448 if (pInfo->SliceHeader.structure == FRAME) 449 { 450 ////////////////////////////////////////////////// short term handling 451 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 452 { 453 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 454 455 if((viddec_h264_get_is_used(active_fs) == 3)&&(active_fs->frame.used_for_reference == 3)) 456 { 457 if (active_fs->frame_num > pInfo->img.frame_num) 458 active_fs->frame_num_wrap = active_fs->frame_num - MaxFrameNum; 459 else 460 active_fs->frame_num_wrap = active_fs->frame_num; 461 462 active_fs->frame.pic_num = active_fs->frame_num_wrap; 463 464 // Use this opportunity to sort list for a p-frame 465 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 466 { 467 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx]; 468 list_sort_number[list0idx] = active_fs->frame.pic_num; 469 list0idx++; 470 } 471 } 472 } 473 474 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 475 { 476 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1); 477 for (idx = 0; idx < list0idx; idx++) 478 p_dpb->listX_0[idx] = (sort_fs_idc[idx]); // frame 479 480 p_dpb->listXsize[0] = list0idx; 481 } 482 483 ////////////////////////////////////////////////// long term handling 484 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 485 { 486 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 487 if ((viddec_h264_get_is_used(active_fs) == 3) && (viddec_h264_get_is_long_term(active_fs) == 3) && (active_fs->frame.used_for_reference == 3)) 488 { 489 active_fs->frame.long_term_pic_num = active_fs->frame.long_term_frame_idx; 490 491 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 492 { 493 sort_fs_idc[list0idx-p_dpb->listXsize[0]] = p_dpb->fs_ltref_idc[idx]; 494 list_sort_number[list0idx-p_dpb->listXsize[0]] = active_fs->frame.long_term_pic_num; 495 list0idx++; 496 } 497 } 498 } 499 500 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 501 { 502 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-p_dpb->listXsize[0], 0); 503 for (idx = p_dpb->listXsize[0]; idx < list0idx; idx++) { 504 p_dpb->listX_0[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]]; 505 } 506 p_dpb->listXsize[0] = list0idx; 507 } 508 } 509 else /// Field base 510 { 511 if (pInfo->SliceHeader.structure == TOP_FIELD) 512 { 513 add_top = 1; 514 add_bottom = 0; 515 } 516 else 517 { 518 add_top = 0; 519 add_bottom = 1; 520 } 521 522 ////////////////////////////////////////////P0: Short term handling 523 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 524 { 525 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 526 if (active_fs->frame.used_for_reference) 527 { 528 if(active_fs->frame_num > pInfo->SliceHeader.frame_num) { 529 active_fs->frame_num_wrap = active_fs->frame_num - MaxFrameNum; 530 } else { 531 active_fs->frame_num_wrap = active_fs->frame_num; 532 } 533 534 if ((active_fs->frame.used_for_reference)&0x1) { 535 active_fs->top_field.pic_num = (active_fs->frame_num_wrap << 1) + add_top; 536 } 537 538 if ((active_fs->frame.used_for_reference)&0x2) { 539 active_fs->bottom_field.pic_num = (active_fs->frame_num_wrap << 1) + add_bottom; 540 } 541 542 if(pInfo->SliceHeader.slice_type == h264_PtypeP) { 543 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx]; 544 list_sort_number[list0idx] = active_fs->frame_num_wrap; 545 list0idx++; 546 } 547 } 548 } 549 550 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 551 { 552 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1); 553 for (idx = 0; idx < list0idx; idx++) { 554 gen_pic_fs_list0[idx] = sort_fs_idc[idx]; 555 } 556 557 p_dpb->listXsize[0] = 0; 558 p_dpb->listXsize[0] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list0, pInfo->img.structure, list0idx, 0); 559 560 for (idx = 0; idx < p_dpb->listXsize[0]; idx++) 561 { 562 p_dpb->listX_0[idx] = gen_pic_pic_list[idx]; 563 } 564 } 565 566 ////////////////////////////////////////////P0: long term handling 567 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 568 { 569 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 570 571 if (viddec_h264_get_is_long_term(active_fs)&0x1) { 572 active_fs->top_field.long_term_pic_num = (active_fs->top_field.long_term_frame_idx << 1) + add_top; 573 } 574 575 if (viddec_h264_get_is_long_term(active_fs)&0x2) { 576 active_fs->bottom_field.long_term_pic_num = (active_fs->bottom_field.long_term_frame_idx << 1) + add_bottom; 577 } 578 579 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 580 { 581 sort_fs_idc[listltidx] = p_dpb->fs_ltref_idc[idx]; 582 list_sort_number[listltidx] = active_fs->long_term_frame_idx; 583 listltidx++; 584 } 585 } 586 587 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 588 { 589 h264_list_sort(sort_fs_idc, list_sort_number, listltidx, 0); 590 for (idx = 0; idx < listltidx; idx++) { 591 gen_pic_fs_listlt[idx] = sort_fs_idc[idx]; 592 } 593 list0idx_1 = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_listlt, pInfo->img.structure, listltidx, 1); 594 595 for (idx = 0; idx < list0idx_1; idx++) { 596 p_dpb->listX_0[p_dpb->listXsize[0]+idx] = gen_pic_pic_list[idx]; 597 } 598 p_dpb->listXsize[0] += list0idx_1; 599 } 600 } 601 602 603 if (pInfo->SliceHeader.slice_type == h264_PtypeI) 604 { 605 p_dpb->listXsize[0] = 0; 606 p_dpb->listXsize[1] = 0; 607 return; 608 } 609 610 if(pInfo->SliceHeader.slice_type == h264_PtypeP) 611 { 612 //// Forward done above 613 p_dpb->listXsize[1] = 0; 614 } 615 616 617 // B-Slice 618 // Do not include non-existing frames for B-pictures when cnt_type is zero 619 620 if(pInfo->SliceHeader.slice_type == h264_PtypeB) 621 { 622 list0idx = list0idx_1 = listltidx = 0; 623 skip_picture = 0; 624 625 if(pInfo->active_SPS.pic_order_cnt_type == 0) 626 check_non_existing = 1; 627 else 628 check_non_existing = 0; 629 630 if (pInfo->SliceHeader.structure == FRAME) 631 { 632 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 633 { 634 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 635 if (viddec_h264_get_is_used(active_fs) == 3) 636 { 637 if(check_non_existing) 638 { 639 if(viddec_h264_get_is_non_existent(active_fs)) skip_picture = 1; 640 else skip_picture = 0; 641 } 642 643 if(skip_picture == 0) 644 { 645 if ((active_fs->frame.used_for_reference==3) && (!(active_fs->frame.is_long_term))) 646 { 647 if (pInfo->img.framepoc >= active_fs->frame.poc) 648 { 649 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx]; 650 list_sort_number[list0idx] = active_fs->frame.poc; 651 list0idx++; 652 } 653 } 654 } 655 } 656 } 657 658 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1); 659 for (idx = 0; idx < list0idx; idx++) { 660 p_dpb->listX_0[idx] = sort_fs_idc[idx]; 661 } 662 663 list0idx_1 = list0idx; 664 665 /////////////////////////////////////////B0: Short term handling 666 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 667 { 668 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 669 670 if (viddec_h264_get_is_used(active_fs) == 3) 671 { 672 if(check_non_existing) 673 { 674 if(viddec_h264_get_is_non_existent(active_fs)) skip_picture = 1; 675 else skip_picture = 0; 676 } 677 678 if(skip_picture == 0) 679 { 680 if ((active_fs->frame.used_for_reference) && (!(active_fs->frame.is_long_term))) 681 { 682 if (pInfo->img.framepoc < active_fs->frame.poc) 683 { 684 sort_fs_idc[list0idx-list0idx_1] = p_dpb->fs_ref_idc[idx]; 685 list_sort_number[list0idx-list0idx_1] = active_fs->frame.poc; 686 list0idx++; 687 } 688 } 689 } 690 } 691 } 692 693 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-list0idx_1, 0); 694 for (idx = list0idx_1; idx < list0idx; idx++) { 695 p_dpb->listX_0[idx] = sort_fs_idc[idx-list0idx_1]; 696 } 697 698 for (idx = 0; idx < list0idx_1; idx++) { 699 p_dpb->listX_1[list0idx-list0idx_1+idx] = p_dpb->listX_0[idx]; 700 } 701 702 for (idx = list0idx_1; idx < list0idx; idx++) { 703 p_dpb->listX_1[idx-list0idx_1] = p_dpb->listX_0[idx]; 704 } 705 706 p_dpb->listXsize[0] = list0idx; 707 p_dpb->listXsize[1] = list0idx; 708 709 /////////////////////////////////////////B0: long term handling 710 list0idx = 0; 711 712 // Can non-existent pics be set as long term?? 713 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 714 { 715 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 716 717 if ((viddec_h264_get_is_used(active_fs) == 3) && (viddec_h264_get_is_long_term(active_fs) == 3)) 718 { 719 // if we have two fields, both must be long-term 720 sort_fs_idc[list0idx] = p_dpb->fs_ltref_idc[idx]; 721 list_sort_number[list0idx] = active_fs->frame.long_term_pic_num; 722 list0idx++; 723 } 724 } 725 726 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 0); 727 for (idx = p_dpb->listXsize[0]; idx < (p_dpb->listXsize[0]+list0idx); idx = idx + 1) 728 { 729 p_dpb->listX_0[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]]; 730 p_dpb->listX_1[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]]; 731 } 732 733 p_dpb->listXsize[0] += list0idx; 734 p_dpb->listXsize[1] += list0idx; 735 } 736 else // Field 737 { 738 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 739 { 740 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 741 742 if (viddec_h264_get_is_used(active_fs)) { 743 if(check_non_existing) { 744 if(viddec_h264_get_is_non_existent(active_fs)) 745 skip_picture = 1; 746 else 747 skip_picture = 0; 748 } 749 750 if(skip_picture == 0) { 751 if (pInfo->img.ThisPOC >= active_fs->frame.poc) { 752 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx]; 753 list_sort_number[list0idx] = active_fs->frame.poc; 754 list0idx++; 755 } 756 } 757 } 758 } 759 760 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1); 761 for (idx = 0; idx < list0idx; idx = idx + 1) { 762 gen_pic_fs_list0[idx] = sort_fs_idc[idx]; 763 } 764 765 list0idx_1 = list0idx; 766 767 ///////////////////////////////////////////// B1: Short term handling 768 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 769 { 770 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 771 if (viddec_h264_get_is_used(active_fs)) 772 { 773 if(check_non_existing) { 774 if(viddec_h264_get_is_non_existent(active_fs)) 775 skip_picture = 1; 776 else 777 skip_picture = 0; 778 } 779 780 if(skip_picture == 0) { 781 if (pInfo->img.ThisPOC < active_fs->frame.poc) { 782 sort_fs_idc[list0idx-list0idx_1] = p_dpb->fs_ref_idc[idx]; 783 list_sort_number[list0idx-list0idx_1] = active_fs->frame.poc; 784 list0idx++; 785 } 786 } 787 } 788 } 789 790 ///// Generate frame list from sorted fs 791 ///// 792 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-list0idx_1, 0); 793 for (idx = list0idx_1; idx < list0idx; idx++) 794 gen_pic_fs_list0[idx] = sort_fs_idc[idx-list0idx_1]; 795 796 for (idx = 0; idx < list0idx_1; idx++) 797 gen_pic_fs_list1[list0idx-list0idx_1+idx] = gen_pic_fs_list0[idx]; 798 799 for (idx = list0idx_1; idx < list0idx; idx++) 800 gen_pic_fs_list1[idx-list0idx_1] = gen_pic_fs_list0[idx]; 801 802 ///// Generate List_X0 803 ///// 804 p_dpb->listXsize[0] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list0, pInfo->img.structure, list0idx, 0); 805 806 for (idx = 0; idx < p_dpb->listXsize[0]; idx++) 807 p_dpb->listX_0[idx] = gen_pic_pic_list[idx]; 808 809 //// Generate List X1 810 //// 811 p_dpb->listXsize[1] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list1, pInfo->img.structure, list0idx, 0); 812 813 for (idx = 0; idx < p_dpb->listXsize[1]; idx++) 814 p_dpb->listX_1[idx] = gen_pic_pic_list[idx]; 815 816 ///////////////////////////////////////////// B1: long term handling 817 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 818 { 819 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 820 sort_fs_idc[listltidx] = p_dpb->fs_ltref_idc[idx]; 821 list_sort_number[listltidx] = active_fs->long_term_frame_idx; 822 listltidx++; 823 } 824 825 h264_list_sort(sort_fs_idc, list_sort_number, listltidx, 0); 826 for (idx = 0; idx < listltidx; idx++) 827 gen_pic_fs_listlt[idx] = sort_fs_idc[idx]; 828 829 list0idx_1 = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_listlt, pInfo->img.structure, listltidx, 1); 830 831 for (idx = 0; idx < list0idx_1; idx++) 832 { 833 p_dpb->listX_0[p_dpb->listXsize[0]+idx] = gen_pic_pic_list[idx]; 834 p_dpb->listX_1[p_dpb->listXsize[1]+idx] = gen_pic_pic_list[idx]; 835 } 836 837 p_dpb->listXsize[0] += list0idx_1; 838 p_dpb->listXsize[1] += list0idx_1; 839 } 840 } 841 842 // Setup initial list sizes at this point 843 p_dpb->nInitListSize[0] = p_dpb->listXsize[0]; 844 p_dpb->nInitListSize[1] = p_dpb->listXsize[1]; 845 if(pInfo->SliceHeader.slice_type != h264_PtypeI) 846 { 847 if ((p_dpb->listXsize[0]==p_dpb->listXsize[1]) && (p_dpb->listXsize[0] > 1)) 848 { 849 // check if lists are identical, if yes swap first two elements of listX[1] 850 diff = 0; 851 for (idx = 0; idx < p_dpb->listXsize[0]; idx = idx + 1) 852 { 853 if (p_dpb->listX_0[idx] != p_dpb->listX_1[idx]) diff = 1; 854 } 855 856 857 if (!(diff)) 858 { 859 list_idc = p_dpb->listX_1[0]; 860 p_dpb->listX_1[0] = p_dpb->listX_1[1]; 861 p_dpb->listX_1[1] = list_idc; 862 } 863 } 864 865 // set max size 866 if (p_dpb->listXsize[0] > pInfo->SliceHeader.num_ref_idx_l0_active) 867 { 868 p_dpb->listXsize[0] = pInfo->SliceHeader.num_ref_idx_l0_active; 869 } 870 871 872 if (p_dpb->listXsize[1] > pInfo->SliceHeader.num_ref_idx_l1_active) 873 { 874 p_dpb->listXsize[1] = pInfo->SliceHeader.num_ref_idx_l1_active; 875 } 876 877 878 879 } 880 881 882 883 /// DPB reorder list 884 h264_dpb_reorder_lists(pInfo); 885 886 return; 887 } //// End of init_dpb_list 888 889 890 /* ------------------------------------------------------------------------------------------ */ 891 /* ------------------------------------------------------------------------------------------ */ 892 /* ------------------------------------------------------------------------------------------ */ 893 ////////////////////////////////////////////////////////////////////////////// 894 // h264_dpb_get_short_term_pic () 895 // 896 // Sets active_fs to point to frame store containing picture with given picNum 897 // Sets field_flag, bottom_field and err_flag based on the picture and whether 898 // it is available or not... 899 // 900 static frame_param_ptr h264_dpb_get_short_term_pic(h264_Info * pInfo,int32_t pic_num, int32_t *bottom_field_bit) 901 { 902 register uint32_t idx; 903 register frame_param_ptr temp_fs; 904 905 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 906 907 *bottom_field_bit = 0; 908 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++) 909 { 910 temp_fs = &p_dpb->fs[p_dpb->fs_ref_idc[idx]]; 911 if (pInfo->SliceHeader.structure == FRAME) 912 { 913 if(temp_fs->frame.used_for_reference == 3) 914 if (!(temp_fs->frame.is_long_term)) 915 if (temp_fs->frame.pic_num == pic_num) return temp_fs; 916 } 917 else // current picture is a field 918 { 919 if (temp_fs->frame.used_for_reference&0x1) 920 if (!(temp_fs->top_field.is_long_term)) 921 if (temp_fs->top_field.pic_num == pic_num) 922 { 923 return temp_fs; 924 } 925 926 if (temp_fs->frame.used_for_reference&0x2) 927 if (!(temp_fs->bottom_field.is_long_term)) 928 if (temp_fs->bottom_field.pic_num == pic_num) 929 { 930 *bottom_field_bit = PUT_LIST_INDEX_FIELD_BIT(1); 931 return temp_fs; 932 } 933 } 934 } 935 return NULL; 936 } 937 938 /* ------------------------------------------------------------------------------------------ */ 939 /* ------------------------------------------------------------------------------------------ */ 940 /* ------------------------------------------------------------------------------------------ */ 941 ////////////////////////////////////////////////////////////////////////////// 942 // h264_dpb_get_long_term_pic () 943 // 944 // Sets active_fs to point to frame store containing picture with given picNum 945 // 946 947 static frame_param_ptr h264_dpb_get_long_term_pic(h264_Info * pInfo,int32_t long_term_pic_num, int32_t *bottom_field_bit) 948 { 949 register uint32_t idx; 950 register frame_param_ptr temp_fs; 951 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 952 953 *bottom_field_bit = 0; 954 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 955 { 956 temp_fs = &p_dpb->fs[p_dpb->fs_ltref_idc[idx]]; 957 if (pInfo->SliceHeader.structure == FRAME) 958 { 959 if (temp_fs->frame.used_for_reference == 3) 960 if (temp_fs->frame.is_long_term) 961 if (temp_fs->frame.long_term_pic_num == long_term_pic_num) 962 return temp_fs; 963 } 964 else 965 { 966 if (temp_fs->frame.used_for_reference&0x1) 967 if (temp_fs->top_field.is_long_term) 968 if (temp_fs->top_field.long_term_pic_num == long_term_pic_num) 969 return temp_fs; 970 971 if (temp_fs->frame.used_for_reference&0x2) 972 if (temp_fs->bottom_field.is_long_term) 973 if (temp_fs->bottom_field.long_term_pic_num == long_term_pic_num) 974 { 975 *bottom_field_bit = PUT_LIST_INDEX_FIELD_BIT(1); 976 return temp_fs; 977 } 978 } 979 } 980 return NULL; 981 } 982 983 /* ------------------------------------------------------------------------------------------ */ 984 /* ------------------------------------------------------------------------------------------ */ 985 /* ------------------------------------------------------------------------------------------ */ 986 ////////////////////////////////////////////////////////////////////////////// 987 // h264_dpb_reorder_ref_pic_list () 988 // 989 // Used to sort a list based on a corresponding sort indices 990 // 991 992 struct list_value_t 993 { 994 int32_t value; 995 struct list_value_t *next; 996 }; 997 998 struct linked_list_t 999 { 1000 struct list_value_t *begin; 1001 struct list_value_t *end; 1002 struct list_value_t *entry; 1003 struct list_value_t *prev_entry; 1004 struct list_value_t list[32]; 1005 }; 1006 1007 static void linked_list_initialize (struct linked_list_t *lp, uint8_t *vp, int32_t size) 1008 { 1009 struct list_value_t *lvp; 1010 1011 lvp = lp->list; 1012 lp->begin = lvp; 1013 lp->entry = lvp; 1014 lp->end = lvp + (size-1); 1015 lp->prev_entry = NULL; 1016 1017 while (lvp <= lp->end) 1018 { 1019 lvp->value = *(vp++); 1020 lvp->next = lvp + 1; 1021 lvp++; 1022 } 1023 lp->end->next = NULL; 1024 return; 1025 } 1026 /* ------------------------------------------------------------------------------------------ */ 1027 /* ------------------------------------------------------------------------------------------ */ 1028 /* ------------------------------------------------------------------------------------------ */ 1029 static void linked_list_reorder (struct linked_list_t *lp, int32_t list_value) 1030 { 1031 register struct list_value_t *lvp = lp->entry; 1032 register struct list_value_t *lvp_prev; 1033 1034 if (lvp == NULL) { 1035 lp->end->value = list_value; // replace the end entry 1036 } else if ((lp->begin==lp->end)||(lvp==lp->end)) // replece the begin/end entry and set the entry to NULL 1037 { 1038 lp->entry->value = list_value; 1039 lp->prev_entry = lp->entry; 1040 lp->entry = NULL; 1041 } 1042 else if (lvp->value==list_value) // the entry point matches 1043 { 1044 lp->prev_entry = lvp; 1045 lp->entry = lvp->next; 1046 } 1047 else if (lvp->next == lp->end) // the entry is just before the end 1048 { 1049 // replace the end and swap the end and entry points 1050 // lvp 1051 // prev_entry => entry => old_end 1052 // old_end & new_prev_entry => new_end & entry 1053 lp->end->value = list_value; 1054 1055 if (lp->prev_entry) 1056 lp->prev_entry->next = lp->end; 1057 else 1058 lp->begin = lp->end; 1059 1060 lp->prev_entry = lp->end; 1061 lp->end->next = lvp; 1062 lp->end = lvp; 1063 lvp->next = NULL; 1064 } 1065 else 1066 { 1067 lvp_prev = NULL; 1068 while (lvp->next) // do not check the end but we'll be in the loop at least once 1069 { 1070 if (lvp->value == list_value) break; 1071 lvp_prev = lvp; 1072 lvp = lvp->next; 1073 } 1074 lvp->value = list_value; // force end matches 1075 1076 // remove lvp from the list 1077 lvp_prev->next = lvp->next; 1078 if (lvp==lp->end) lp->end = lvp_prev; 1079 1080 // insert lvp in front of lp->entry 1081 if (lp->entry==lp->begin) 1082 { 1083 lvp->next = lp->begin; 1084 lp->begin = lvp; 1085 } 1086 else 1087 { 1088 lvp->next = lp->entry; 1089 lp->prev_entry->next = lvp; 1090 } 1091 lp->prev_entry = lvp; 1092 } 1093 return; 1094 } 1095 /* ------------------------------------------------------------------------------------------ */ 1096 /* ------------------------------------------------------------------------------------------ */ 1097 /* ------------------------------------------------------------------------------------------ */ 1098 static void linked_list_output (struct linked_list_t *lp, int32_t *vp) 1099 { 1100 register int32_t *ip1; 1101 register struct list_value_t *lvp; 1102 1103 lvp = lp->begin; 1104 ip1 = vp; 1105 while (lvp) 1106 { 1107 *(ip1++) = lvp->value; 1108 lvp = lvp->next; 1109 } 1110 return; 1111 } 1112 /* ------------------------------------------------------------------------------------------ */ 1113 /* ------------------------------------------------------------------------------------------ */ 1114 /* ------------------------------------------------------------------------------------------ */ 1115 int32_t h264_dpb_reorder_ref_pic_list(h264_Info * pInfo,int32_t list_num, int32_t num_ref_idx_active) 1116 { 1117 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1118 uint8_t *remapping_of_pic_nums_idc; 1119 list_reordering_num_t *list_reordering_num; 1120 int32_t bottom_field_bit; 1121 1122 int32_t maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, pic_num; 1123 int32_t refIdxLX; 1124 int32_t i; 1125 1126 int32_t PicList[32] = {0}; 1127 struct linked_list_t ll; 1128 struct linked_list_t *lp = ≪ // should consider use the scratch space 1129 1130 // declare these below as registers gave me 23 cy/MB for the worst frames in Allegro_Combined_CABAC_07_HD, YHu 1131 register frame_param_ptr temp_fs; 1132 register int32_t temp; 1133 register uint8_t *ip1; 1134 1135 maxPicNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4); 1136 1137 1138 if (list_num == 0) // i.e list 0 1139 { 1140 ip1 = p_dpb->listX_0; 1141 remapping_of_pic_nums_idc = pInfo->SliceHeader.sh_refpic_l0.reordering_of_pic_nums_idc; 1142 list_reordering_num = pInfo->SliceHeader.sh_refpic_l0.list_reordering_num; 1143 } 1144 else 1145 { 1146 ip1 = p_dpb->listX_1; 1147 remapping_of_pic_nums_idc = pInfo->SliceHeader.sh_refpic_l1.reordering_of_pic_nums_idc; 1148 list_reordering_num = pInfo->SliceHeader.sh_refpic_l1.list_reordering_num; 1149 } 1150 1151 1152 linked_list_initialize (lp, ip1, num_ref_idx_active); 1153 1154 currPicNum = pInfo->SliceHeader.frame_num; 1155 if (pInfo->SliceHeader.structure != FRAME) 1156 { 1157 1158 /* The reason it is + 1 I think, is because the list is based on polarity 1159 expand later... 1160 */ 1161 maxPicNum <<= 1; 1162 currPicNum <<= 1; 1163 currPicNum++; 1164 } 1165 1166 picNumLXPred = currPicNum; 1167 refIdxLX = 0; 1168 1169 for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++) 1170 { 1171 if(i > MAX_NUM_REF_FRAMES) 1172 { 1173 break; 1174 } 1175 1176 if (remapping_of_pic_nums_idc[i] < 2) // - short-term re-ordering 1177 { 1178 temp = (list_reordering_num[i].abs_diff_pic_num_minus1 + 1); 1179 if (remapping_of_pic_nums_idc[i] == 0) 1180 { 1181 temp = picNumLXPred - temp; 1182 if (temp < 0 ) picNumLXNoWrap = temp + maxPicNum; 1183 else picNumLXNoWrap = temp; 1184 } 1185 else // (remapping_of_pic_nums_idc[i] == 1) 1186 { 1187 temp += picNumLXPred; 1188 if (temp >= maxPicNum) picNumLXNoWrap = temp - maxPicNum; 1189 else picNumLXNoWrap = temp; 1190 } 1191 1192 // Updates for next iteration of the loop 1193 picNumLXPred = picNumLXNoWrap; 1194 1195 if (picNumLXNoWrap > currPicNum ) pic_num = picNumLXNoWrap - maxPicNum; 1196 else pic_num = picNumLXNoWrap; 1197 1198 temp_fs = h264_dpb_get_short_term_pic(pInfo, pic_num, &bottom_field_bit); 1199 if (temp_fs) 1200 { 1201 temp = bottom_field_bit + PUT_FS_IDC_BITS(temp_fs->fs_idc); 1202 linked_list_reorder (lp, temp); 1203 } 1204 } 1205 else //(remapping_of_pic_nums_idc[i] == 2) long-term re-ordering 1206 { 1207 pic_num = list_reordering_num[i].long_term_pic_num; 1208 1209 temp_fs = h264_dpb_get_long_term_pic(pInfo, pic_num, &bottom_field_bit); 1210 if (temp_fs) 1211 { 1212 temp = PUT_LIST_LONG_TERM_BITS(1) + bottom_field_bit + PUT_FS_IDC_BITS(temp_fs->fs_idc); 1213 linked_list_reorder (lp, temp); 1214 } 1215 } 1216 } 1217 1218 linked_list_output (lp, PicList); 1219 1220 if(0 == list_num ) 1221 { 1222 for(i=0; i<num_ref_idx_active; i++) 1223 { 1224 pInfo->slice_ref_list0[i]=(uint8_t)PicList[i]; 1225 } 1226 } 1227 else 1228 { 1229 for(i=0; i<num_ref_idx_active; i++) 1230 { 1231 pInfo->slice_ref_list1[i]=(uint8_t)PicList[i]; 1232 } 1233 } 1234 1235 1236 // Instead of updating the now reordered list here, just write it down... 1237 // This way, we can continue to hold the initialised list in p_dpb->listX_0 1238 // and therefore not need to update it every slice 1239 1240 //h264_dpb_write_list(list_num, PicList, num_ref_idx_active); 1241 1242 return num_ref_idx_active; 1243 } 1244 1245 /* ------------------------------------------------------------------------------------------ */ 1246 /* ------------------------------------------------------------------------------------------ */ 1247 /* ------------------------------------------------------------------------------------------ */ 1248 1249 1250 void h264_dpb_RP_check_list (h264_Info * pInfo) 1251 { 1252 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1253 uint8_t *p_list = pInfo->slice_ref_list0; 1254 1255 // 1256 // If the decoding start from RP and without exact point, all B frames belong to previous GOP should be throw away! 1257 // 1258 1259 if((pInfo->SliceHeader.slice_type == h264_PtypeB)&&(pInfo->sei_b_state_ready ==0) && pInfo->sei_rp_received) { 1260 pInfo->wl_err_curr |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 1261 pInfo->wl_err_curr |= (FRAME << FIELD_ERR_OFFSET); 1262 } 1263 1264 1265 // 1266 // Repare Ref list if it damaged with RP recovery only 1267 // 1268 if((pInfo->SliceHeader.slice_type == h264_PtypeP) && pInfo->sei_rp_received) 1269 { 1270 1271 int32_t idx, rp_found = 0; 1272 1273 if(pInfo->SliceHeader.num_ref_idx_l0_active == 1) 1274 { 1275 if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag) 1276 { 1277 p_list = pInfo->slice_ref_list0; 1278 } 1279 else 1280 { 1281 p_list = pInfo->dpb.listX_0; 1282 //pInfo->sei_rp_received = 0; 1283 //return; 1284 } 1285 1286 1287 for(idx = 0; idx < p_dpb->used_size; idx++) { 1288 if(p_dpb->fs_dpb_idc[idx] == pInfo->last_I_frame_idc) { 1289 rp_found = 1; 1290 break; 1291 } 1292 } 1293 if(rp_found) { 1294 #if 0 1295 int32_t poc; 1296 1297 ///// Clear long-term ref list 1298 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++) 1299 { 1300 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ltref_idc[0]); 1301 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[0]); 1302 } 1303 1304 ///// Clear short-term ref list 1305 //while(p_dpb->used_size>1) 1306 for(idx = 0; idx < p_dpb->used_size; idx++) 1307 { 1308 int32_t idx_pos; 1309 //// find smallest non-output POC 1310 h264_dpb_get_smallest_poc(p_dpb, &poc, &idx_pos); 1311 1312 //// Remove all frames in previous GOP 1313 if ((idx_pos != MPD_DPB_FS_NULL_IDC) && (p_dpb->fs_dpb_idc[idx_pos] != pInfo->last_I_frame_idc)) 1314 { 1315 // Remove from ref-list 1316 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_dpb_idc[idx_pos]); 1317 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_dpb_idc[idx_pos]); 1318 1319 // Output from DPB 1320 //h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 1321 //if((active_fs->is_output == 0) && (active_fs->is_non_existent == 0)) 1322 { 1323 //int32_t existing; 1324 //h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[idx], 0, &existing); 1325 //p_dpb->last_output_poc = poc; 1326 } 1327 //h264_dpb_remove_frame_from_dpb(p_dpb, idx); // Remove dpb.fs_dpb_idc[pos] 1328 1329 } 1330 } 1331 #endif 1332 ///// Set the reference to last I frame 1333 if( (pInfo->last_I_frame_idc!=255)&&(pInfo->last_I_frame_idc!=p_list[0])) 1334 { 1335 /// Repaire the reference list now 1336 h264_dpb_unmark_for_reference(p_dpb, p_list[0]); 1337 h264_dpb_remove_ref_list(p_dpb, p_list[0]); 1338 p_list[0] = pInfo->last_I_frame_idc; 1339 } 1340 1341 } 1342 } 1343 1344 pInfo->sei_rp_received = 0; 1345 pInfo->sei_b_state_ready = 1; 1346 1347 } 1348 1349 1350 return; 1351 } 1352 1353 1354 /* ------------------------------------------------------------------------------------------ */ 1355 /* ------------------------------------------------------------------------------------------ */ 1356 /* ------------------------------------------------------------------------------------------ */ 1357 ////////////////////////////////////////////////////////////////////////////// 1358 // h264_dpb_reorder_lists () 1359 // 1360 // Used to sort a list based on a corresponding sort indices 1361 // 1362 1363 void h264_dpb_reorder_lists(h264_Info * pInfo) 1364 { 1365 int32_t currSliceType = pInfo->SliceHeader.slice_type; 1366 1367 if (currSliceType == h264_PtypeP ) 1368 { 1369 /////////////////////////////////////////////// Reordering reference list for P slice 1370 /// Forward reordering 1371 if (pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag) 1372 h264_dpb_reorder_ref_pic_list(pInfo, 0, pInfo->SliceHeader.num_ref_idx_l0_active); 1373 else 1374 { 1375 1376 } 1377 pInfo->dpb.listXsize[0]=pInfo->SliceHeader.num_ref_idx_l0_active; 1378 } else if (currSliceType == h264_PtypeB) 1379 { 1380 /////////////////////////////////////////////// Reordering reference list for B slice 1381 /// Forward reordering 1382 if (pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag) 1383 h264_dpb_reorder_ref_pic_list(pInfo, 0, pInfo->SliceHeader.num_ref_idx_l0_active); 1384 else 1385 { 1386 1387 } 1388 pInfo->dpb.listXsize[0]=pInfo->SliceHeader.num_ref_idx_l0_active; 1389 1390 /// Backward reordering 1391 if (pInfo->SliceHeader.sh_refpic_l1.ref_pic_list_reordering_flag) 1392 h264_dpb_reorder_ref_pic_list(pInfo, 1, pInfo->SliceHeader.num_ref_idx_l1_active); 1393 else 1394 { 1395 1396 } 1397 pInfo->dpb.listXsize[1]=pInfo->SliceHeader.num_ref_idx_l1_active; 1398 } 1399 1400 //// Check if need recover reference list with previous recovery point 1401 h264_dpb_RP_check_list(pInfo); 1402 1403 1404 return; 1405 } 1406 1407 ////////////////////////////////////////// DPB management ////////////////////// 1408 1409 ////////////////////////////////////////////////////////////////////////////// 1410 // avc_dpb_get_non_output_frame_number () 1411 // 1412 // get total non output frame number in the DPB. 1413 // 1414 static int32_t avc_dpb_get_non_output_frame_number(h264_Info * pInfo) 1415 { 1416 int32_t idx; 1417 int32_t number=0; 1418 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1419 1420 for (idx = 0; idx < p_dpb->used_size; idx++) 1421 { 1422 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 1423 1424 if (viddec_h264_get_is_output(active_fs) == 0) 1425 { 1426 (number)++; 1427 } 1428 } 1429 1430 return number; 1431 } 1432 1433 1434 /* ------------------------------------------------------------------------------------------ */ 1435 /* ------------------------------------------------------------------------------------------ */ 1436 /* ------------------------------------------------------------------------------------------ */ 1437 //// Store previous picture in DPB, and then update DPB queue, remove unused frames from DPB 1438 1439 void h264_dpb_store_previous_picture_in_dpb(h264_Info * pInfo,int32_t NonExisting, int32_t use_old) 1440 { 1441 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1442 1443 int32_t used_for_reference; 1444 int32_t is_direct_output; 1445 int32_t second_field_stored = 0; 1446 int32_t poc; 1447 int32_t pos; 1448 int32_t flag; 1449 int32_t first_field_non_ref = 0; 1450 int32_t idr_flag; 1451 1452 if(NonExisting) { 1453 if(p_dpb->fs_non_exist_idc == MPD_DPB_FS_NULL_IDC) 1454 return; 1455 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc); 1456 } else { 1457 if(p_dpb->fs_dec_idc == MPD_DPB_FS_NULL_IDC) 1458 return; 1459 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1460 } 1461 1462 if(NonExisting == 0) 1463 { 1464 //active_fs->sps_disp_index = (next_sps_disp_entry == 0)? 7 : next_sps_disp_entry - 1; 1465 pInfo->img.last_has_mmco_5 = 0; 1466 pInfo->img.last_pic_bottom_field = pInfo->img.bottom_field_flag; 1467 1468 //used_for_reference = (use_old) ? !(old_pInfo->img.old_disposable_flag) : !(pInfo->img.disposable_flag); 1469 used_for_reference = (use_old) ? !(pInfo->old_slice.nal_ref_idc==0) : !(pInfo->SliceHeader.nal_ref_idc==0); 1470 1471 switch (viddec_h264_get_dec_structure(active_fs)) 1472 { 1473 case(TOP_FIELD) : { 1474 active_fs->top_field.used_for_reference = used_for_reference; 1475 viddec_h264_set_is_top_used(active_fs, 1); 1476 //active_fs->crc_field_coded = 1; 1477 }break; 1478 case(BOTTOM_FIELD): { 1479 active_fs->bottom_field.used_for_reference = used_for_reference << 1; 1480 viddec_h264_set_is_bottom_used(active_fs, 1); 1481 //active_fs->crc_field_coded = 1; 1482 }break; 1483 default: { 1484 active_fs->frame.used_for_reference = used_for_reference?3:0; 1485 viddec_h264_set_is_frame_used(active_fs, 3); 1486 //if(pInfo->img.MbaffFrameFlag) active_fs->crc_field_coded = 1; 1487 1488 }break; 1489 } 1490 1491 //freeze_assert = use_old ? old_pInfo->img.sei_freeze_this_image : pInfo->img.sei_freeze_this_image; 1492 //if (freeze_assert) sei_information.disp_frozen = 1; 1493 1494 idr_flag = use_old ? pInfo->old_slice.idr_flag : pInfo->SliceHeader.idr_flag; 1495 if (idr_flag) { 1496 h264_dpb_idr_memory_management (pInfo, &pInfo->active_SPS, pInfo->img.no_output_of_prior_pics_flag); 1497 } else { 1498 // adaptive memory management 1499 if (used_for_reference & pInfo->SliceHeader.sh_dec_refpic.adaptive_ref_pic_marking_mode_flag) { 1500 h264_dpb_adaptive_memory_management(pInfo); 1501 } 1502 } 1503 // Reset the active frame store - could have changed in mem management ftns 1504 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1505 1506 if ((viddec_h264_get_dec_structure(active_fs) == TOP_FIELD)||(viddec_h264_get_dec_structure(active_fs) == BOTTOM_FIELD)) 1507 { 1508 // check for frame store with same pic_number -- always true in my case, YH 1509 // when we allocate frame store for the second field, we make sure the frame store for the second 1510 // field is the one that contains the first field of the frame- see h264_dpb_init_frame_store() 1511 // This is different from JM model. 1512 // In this way we don't need to move image data around and can reduce memory bandwidth. 1513 // simply check if the check if the other field has been decoded or not 1514 1515 if (viddec_h264_get_is_used(active_fs) != 0) 1516 { 1517 if(pInfo->img.second_field) 1518 { 1519 h264_dpb_insert_picture_in_dpb(pInfo, used_for_reference, 0, NonExisting, use_old); 1520 second_field_stored = 1; 1521 } 1522 } 1523 } 1524 } 1525 else 1526 { // Set up locals for non-existing frames 1527 used_for_reference = 1; 1528 1529 active_fs->frame.used_for_reference = used_for_reference?3:0; 1530 viddec_h264_set_is_frame_used(active_fs, 3); 1531 viddec_h264_set_dec_structure(active_fs, FRAME); 1532 pInfo->img.structure = FRAME; 1533 } 1534 1535 is_direct_output = 0; 1536 if (NonExisting == 0) 1537 { 1538 if(p_dpb->used_size >= p_dpb->BumpLevel) 1539 { 1540 // non-reference frames may be output directly 1541 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1542 1543 if ((used_for_reference == 0) && (viddec_h264_get_is_used(active_fs) == 3)) 1544 { 1545 h264_dpb_get_smallest_poc (p_dpb, &poc, &pos); 1546 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1547 if ((pos == MPD_DPB_FS_NULL_IDC) || (pInfo->img.ThisPOC < poc)) 1548 { 1549 is_direct_output = 1; 1550 } 1551 } 1552 } 1553 } 1554 1555 if (NonExisting) { 1556 h264_dpb_sliding_window_memory_management(p_dpb, NonExisting, pInfo->active_SPS.num_ref_frames); 1557 } else if(pInfo->SliceHeader.idr_flag == 0) { 1558 if(used_for_reference){ 1559 if(pInfo->img.second_field == 0) { 1560 if (pInfo->SliceHeader.sh_dec_refpic.adaptive_ref_pic_marking_mode_flag == 0) { 1561 h264_dpb_sliding_window_memory_management(p_dpb, NonExisting, pInfo->active_SPS.num_ref_frames); 1562 } 1563 } 1564 } 1565 } 1566 1567 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 1568 1569 //if (is_direct_output == 0) 1570 { 1571 if ((pInfo->img.second_field == 0) || (NonExisting)) 1572 { 1573 h264_dpb_insert_picture_in_dpb(pInfo, used_for_reference, 1, NonExisting, use_old); 1574 } 1575 1576 // In an errored stream we saw a condition where 1577 // p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer > p_dpb->BumpLevel, 1578 // which in itself is an error, but this means first_field_non_ref will 1579 // not get set and causes problems for h264_dpb_queue_update() 1580 if((pInfo->img.structure != FRAME) && (pInfo->img.second_field == 0)) { 1581 if(used_for_reference == 0) 1582 if(p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer == p_dpb->BumpLevel) 1583 first_field_non_ref = 1; 1584 } 1585 1586 } 1587 1588 if(NonExisting) 1589 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc); 1590 else 1591 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1592 1593 if(NonExisting == 0) 1594 { 1595 if((pInfo->img.second_field == 1) || (pInfo->img.structure == FRAME)) 1596 { 1597 //h264_send_new_decoded_frame(); 1598 if((p_dpb->OutputCtrl) && (is_direct_output == 0)) 1599 h264_dpb_output_one_frame_from_dpb(pInfo, 0, 0,pInfo->active_SPS.num_ref_frames); 1600 1601 // Pictures inserted by this point - check if we have reached the specified output 1602 // level (if one has been specified) so we can begin on next call 1603 1604 /* 1605 Fixed HSD 212625---------------should compare OutputLevel with non-output frame number in dpb, not the used number in dpb 1606 if((p_dpb->OutputLevelValid)&&(p_dpb->OutputCtrl == 0)) 1607 { 1608 if(p_dpb->used_size == p_dpb->OutputLevel) 1609 p_dpb->OutputCtrl = 1; 1610 } 1611 */ 1612 1613 if(p_dpb->OutputLevelValid) 1614 { 1615 int32_t non_output_frame_number=0; 1616 non_output_frame_number = avc_dpb_get_non_output_frame_number(pInfo); 1617 1618 if(non_output_frame_number == p_dpb->OutputLevel) 1619 p_dpb->OutputCtrl = 1; 1620 else 1621 p_dpb->OutputCtrl = 0; 1622 } 1623 else { 1624 p_dpb->OutputCtrl = 0; 1625 } 1626 } 1627 } 1628 1629 while(p_dpb->used_size > (p_dpb->BumpLevel + first_field_non_ref)) 1630 //while(p_dpb->used_size > p_dpb->BumpLevel) 1631 { 1632 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame 1633 //h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 1634 } 1635 1636 // 1637 // Do not output "direct output" pictures until the sempahore has been set that the pic is 1638 // decoded!! 1639 // 1640 if(is_direct_output) { 1641 h264_dpb_queue_update(pInfo, 1, 1, 0,pInfo->active_SPS.num_ref_frames); 1642 //h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 1643 } 1644 1645 // 1646 // Add reference pictures into Reference list 1647 // 1648 if(used_for_reference) { 1649 h264_dpb_insert_ref_lists(&pInfo->dpb, NonExisting); 1650 } 1651 1652 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 1653 1654 1655 return; 1656 } ////////////// End of DPB store pic 1657 1658 1659 /* ------------------------------------------------------------------------------------------ */ 1660 /* ------------------------------------------------------------------------------------------ */ 1661 /* ------------------------------------------------------------------------------------------ */ 1662 ////////////////////////////////////////////////////////////////////////////// 1663 // h264_dpb_insert_picture_in_dpb () 1664 // 1665 // Insert the decoded picture into the DPB. A free DPB position is necessary 1666 // for frames, . 1667 // This ftn tends to fill out the framestore's top level parameters from the 1668 // storable picture's parameters within it. It is called from h264_dpb_store_picture_in_dpb() 1669 // 1670 // This function finishes by updating the reference lists - this means it must be called after 1671 // h264_dpb_sliding_window_memory_management() 1672 // 1673 // In the case of a frame it will call h264_dpb_split_field() 1674 // In the case of the second field of a complementary field pair it calls h264_dpb_combine_field() 1675 // 1676 1677 void h264_dpb_insert_picture_in_dpb(h264_Info * pInfo,int32_t used_for_reference, int32_t add2dpb, int32_t NonExisting, int32_t use_old) 1678 { 1679 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1680 1681 if(NonExisting == 0) { 1682 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 1683 active_fs->frame_num = (use_old) ? pInfo->old_slice.frame_num : pInfo->SliceHeader.frame_num; 1684 } 1685 else { 1686 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc); 1687 active_fs->frame_num = active_fs->frame.pic_num; 1688 } 1689 1690 if (add2dpb) { 1691 p_dpb->fs_dpb_idc[p_dpb->used_size] = active_fs->fs_idc; 1692 p_dpb->used_size++; 1693 } 1694 1695 1696 switch (viddec_h264_get_dec_structure(active_fs)) 1697 { 1698 case FRAME :{ 1699 viddec_h264_set_is_frame_used(active_fs, 3); 1700 active_fs->frame.used_for_reference = used_for_reference?3:0; 1701 if (used_for_reference) 1702 { 1703 active_fs->frame.used_for_reference = 3; 1704 if (active_fs->frame.is_long_term) 1705 viddec_h264_set_is_frame_long_term(active_fs, 3); 1706 } 1707 // Split frame to 2 fields for prediction 1708 h264_dpb_split_field(pInfo); 1709 1710 }break; 1711 case TOP_FIELD :{ 1712 viddec_h264_set_is_top_used(active_fs, 1); 1713 1714 active_fs->top_field.used_for_reference = used_for_reference; 1715 if (used_for_reference) 1716 { 1717 active_fs->frame.used_for_reference |= 0x1; 1718 if (active_fs->top_field.is_long_term) 1719 { 1720 viddec_h264_set_is_top_long_term(active_fs, 1); 1721 active_fs->long_term_frame_idx = active_fs->top_field.long_term_frame_idx; 1722 } 1723 } 1724 if (viddec_h264_get_is_used(active_fs) == 3) { 1725 h264_dpb_combine_field(use_old); // generate frame view 1726 } 1727 else 1728 { 1729 active_fs->frame.poc = active_fs->top_field.poc; 1730 } 1731 1732 }break; 1733 case BOTTOM_FIELD :{ 1734 viddec_h264_set_is_bottom_used(active_fs, 1); 1735 1736 active_fs->bottom_field.used_for_reference = (used_for_reference<<1); 1737 if (used_for_reference) 1738 { 1739 active_fs->frame.used_for_reference |= 0x2; 1740 if (active_fs->bottom_field.is_long_term) 1741 { 1742 viddec_h264_set_is_bottom_long_term(active_fs, 1); 1743 active_fs->long_term_frame_idx = active_fs->bottom_field.long_term_frame_idx; 1744 } 1745 } 1746 if (viddec_h264_get_is_used(active_fs) == 3) { 1747 h264_dpb_combine_field(use_old); // generate frame view 1748 } 1749 else 1750 { 1751 active_fs->frame.poc = active_fs->bottom_field.poc; 1752 } 1753 1754 }break; 1755 } 1756 /* 1757 if ( gRestartMode.LastRestartType == RESTART_SEI ) 1758 { 1759 if ( active_fs->open_gop_entry ) dpb.WaitSeiRecovery = 1; 1760 } 1761 1762 gRestartMode.LastRestartType = 0xFFFF; 1763 */ 1764 1765 return; 1766 } ////// End of insert picture in DPB 1767 1768 /* ------------------------------------------------------------------------------------------ */ 1769 /* ------------------------------------------------------------------------------------------ */ 1770 /* ------------------------------------------------------------------------------------------ */ 1771 ////////////////////////////////////////////////////////////////////////////// 1772 // h264_dpb_mm_unmark_short_term_for_reference () 1773 // 1774 // Adaptive Memory Management: Mark short term picture unused 1775 // 1776 1777 void h264_dpb_mm_unmark_short_term_for_reference(h264_Info * pInfo, int32_t difference_of_pic_nums_minus1) 1778 { 1779 int32_t picNumX; 1780 int32_t currPicNum; 1781 uint32_t idx; 1782 int32_t unmark_done; 1783 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1784 1785 if (pInfo->img.structure == FRAME) 1786 currPicNum = pInfo->img.frame_num; 1787 else 1788 currPicNum = (pInfo->img.frame_num << 1) + 1; 1789 1790 picNumX = currPicNum - (difference_of_pic_nums_minus1 + 1); 1791 1792 unmark_done = 0; 1793 1794 for (idx =0; (idx < p_dpb->ref_frames_in_buffer) && (!(unmark_done)); idx++) 1795 { 1796 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 1797 1798 if (pInfo->img.structure == FRAME) 1799 { 1800 /* If all pic numbers in the list are different (and they should be) 1801 we should terminate the for loop the moment we match pic numbers, 1802 no need to continue to check - hence set unmark_done 1803 */ 1804 1805 if ((active_fs->frame.used_for_reference == 3) && (viddec_h264_get_is_long_term(active_fs) == 0) && 1806 (active_fs->frame.pic_num == picNumX)) 1807 { 1808 h264_dpb_unmark_for_reference(p_dpb, active_fs->fs_idc); 1809 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc); 1810 unmark_done = 1; 1811 } 1812 } 1813 else 1814 { 1815 /* 1816 If we wish to unmark a short-term picture by picture number when the current picture 1817 is a field, we have to unmark the corresponding field as unused for reference, 1818 and also if it was part of a frame or complementary reference field pair, the 1819 frame is to be marked as unused. However the opposite field may still be used as a 1820 reference for future fields 1821 1822 How will this affect the reference list update ftn coming after?? 1823 1824 */ 1825 if ((active_fs->frame.used_for_reference&0x1) && (!(viddec_h264_get_is_long_term(active_fs)&0x01))&& 1826 (active_fs->top_field.pic_num == picNumX) ) 1827 { 1828 active_fs->top_field.used_for_reference = 0; 1829 active_fs->frame.used_for_reference &= 2; 1830 1831 unmark_done = 1; 1832 1833 //Check if other field is used for short-term reference, if not remove from list... 1834 if(active_fs->bottom_field.used_for_reference == 0) 1835 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]); 1836 } 1837 if ((active_fs->frame.used_for_reference&0x2) && (!(viddec_h264_get_is_long_term(active_fs)&0x2)) && 1838 (active_fs->bottom_field.pic_num == picNumX) ) 1839 { 1840 active_fs->bottom_field.used_for_reference = 0; 1841 active_fs->frame.used_for_reference &= 1; 1842 1843 unmark_done = 1; 1844 1845 //Check if other field is used for reference, if not remove from list... 1846 if(active_fs->top_field.used_for_reference == 0) 1847 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]); 1848 } 1849 } 1850 } 1851 1852 return; 1853 } 1854 1855 /* ------------------------------------------------------------------------------------------ */ 1856 /* ------------------------------------------------------------------------------------------ */ 1857 /* ------------------------------------------------------------------------------------------ */ 1858 //////////////////////////////////////////////////////////////////////////////////// 1859 // h264_dpb_mm_unmark_long_term_for_reference () 1860 // 1861 // Adaptive Memory Management: Mark long term picture unused 1862 // 1863 // In a frame situation the long_term_pic_num will refer to another frame. 1864 // Thus we can call h264_dpb_unmark_for_long_term_reference() and then remove the picture 1865 // from the list 1866 // 1867 // If the current picture is a field, long_term_pic_num will refer to another field 1868 // It is also the case that each individual field should have a unique picture number 1869 // 8.2.5.4.2 suggests that when curr pic is a field, an mmco == 2 operation 1870 // should be accompanied by a second op to unmark the other field as being unused 1871 /////////////////////////////////////////////////////////////////////////////////// 1872 1873 void h264_dpb_mm_unmark_long_term_for_reference (h264_Info * pInfo, int32_t long_term_pic_num) 1874 { 1875 uint32_t idx; 1876 int32_t unmark_done; 1877 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1878 1879 unmark_done = 0; 1880 for (idx = 0; (idx < p_dpb->ltref_frames_in_buffer) && (!(unmark_done)); idx++) 1881 { 1882 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 1883 1884 if (pInfo->img.structure == FRAME) 1885 { 1886 if ((active_fs->frame.used_for_reference==3) && (viddec_h264_get_is_long_term(active_fs)==3) && 1887 (active_fs->frame.long_term_pic_num == long_term_pic_num)) 1888 { 1889 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx]); 1890 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]); 1891 unmark_done = 1; 1892 } 1893 } 1894 else 1895 { 1896 /// Check top field 1897 if ((active_fs->frame.used_for_reference&0x1) && (viddec_h264_get_is_long_term(active_fs)&0x1) && 1898 (active_fs->top_field.long_term_pic_num == long_term_pic_num) ) 1899 { 1900 active_fs->top_field.used_for_reference = 0; 1901 active_fs->top_field.is_long_term = 0; 1902 active_fs->frame.used_for_reference &= 2; 1903 viddec_h264_set_is_frame_long_term(active_fs, 2); 1904 1905 unmark_done = 1; 1906 1907 //Check if other field is used for long term reference, if not remove from list... 1908 if ((active_fs->bottom_field.used_for_reference == 0) || (active_fs->bottom_field.is_long_term == 0)) 1909 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]); 1910 } 1911 1912 /// Check Bottom field 1913 if ((active_fs->frame.used_for_reference&0x2) && (viddec_h264_get_is_long_term(active_fs)&0x2) && 1914 (active_fs->bottom_field.long_term_pic_num == long_term_pic_num) ) 1915 { 1916 active_fs->bottom_field.used_for_reference = 0; 1917 active_fs->bottom_field.is_long_term = 0; 1918 active_fs->frame.used_for_reference &= 1; 1919 viddec_h264_set_is_frame_long_term(active_fs, 1); 1920 1921 unmark_done = 1; 1922 //Check if other field is used for long term reference, if not remove from list... 1923 if ((active_fs->top_field.used_for_reference == 0) || (active_fs->top_field.is_long_term == 0)) 1924 { 1925 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]); 1926 } 1927 } 1928 } // field structure 1929 } //for(idx) 1930 1931 return; 1932 } 1933 /* ------------------------------------------------------------------------------------------ */ 1934 /* ------------------------------------------------------------------------------------------ */ 1935 /* ------------------------------------------------------------------------------------------ */ 1936 ////////////////////////////////////////////////////////////////////////////// 1937 // h264_dpb_get_pic_struct_by_pic_num 1938 // 1939 // Searches the fields appearing in short term reference list 1940 // Returns the polarity of the field with pic_num = picNumX 1941 ////////////////////////////////////////////////////////////////////////////// 1942 1943 int32_t h264_dpb_get_pic_struct_by_pic_num(h264_DecodedPictureBuffer *p_dpb, int32_t picNumX) 1944 { 1945 uint32_t idx; 1946 int32_t pic_struct = INVALID; 1947 int32_t found = 0; 1948 1949 for (idx =0; (idx < p_dpb->ref_frames_in_buffer) && (!(found)); idx++) 1950 { 1951 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 1952 1953 if ((active_fs->frame.used_for_reference&0x1) && (!(viddec_h264_get_is_long_term(active_fs)&0x01))&& 1954 (active_fs->top_field.pic_num == picNumX) ) 1955 { 1956 found = 1; 1957 pic_struct = TOP_FIELD; 1958 1959 } 1960 if ((active_fs->frame.used_for_reference&0x2) && (!(viddec_h264_get_is_long_term(active_fs)&0x2)) && 1961 (active_fs->bottom_field.pic_num == picNumX) ) 1962 { 1963 found = 1; 1964 pic_struct = BOTTOM_FIELD; 1965 1966 } 1967 } 1968 1969 return pic_struct; 1970 } 1971 /* ------------------------------------------------------------------------------------------ */ 1972 /* ------------------------------------------------------------------------------------------ */ 1973 /* ------------------------------------------------------------------------------------------ */ 1974 ////////////////////////////////////////////////////////////////////////////// 1975 // h264_dpb_mm_assign_long_term_frame_idx () 1976 // 1977 // Assign a long term frame index to a short term picture 1978 // Both lists must be updated as part of this process... 1979 ////////////////////////////////////////////////////////////////////////////// 1980 1981 void h264_dpb_mm_assign_long_term_frame_idx(h264_Info * pInfo, int32_t difference_of_pic_nums_minus1, int32_t long_term_frame_idx) 1982 { 1983 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 1984 int32_t picNumX; 1985 int32_t currPicNum; 1986 int32_t polarity = 0; 1987 1988 if (pInfo->img.structure == FRAME) { 1989 currPicNum = pInfo->img.frame_num; 1990 } else { 1991 currPicNum = (pInfo->img.frame_num << 1) + 1; 1992 } 1993 1994 picNumX = currPicNum - (difference_of_pic_nums_minus1 + 1); 1995 1996 // remove frames / fields with same long_term_frame_idx 1997 if (pInfo->img.structure == FRAME) { 1998 h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(p_dpb, long_term_frame_idx); 1999 } else { 2000 polarity = h264_dpb_get_pic_struct_by_pic_num(p_dpb, picNumX); 2001 2002 if(polarity != INVALID) 2003 h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(p_dpb, long_term_frame_idx, active_fs->fs_idc, polarity); 2004 } 2005 2006 h264_dpb_mark_pic_long_term(pInfo, long_term_frame_idx, picNumX); 2007 2008 return; 2009 } 2010 /* ------------------------------------------------------------------------------------------ */ 2011 /* ------------------------------------------------------------------------------------------ */ 2012 /* ------------------------------------------------------------------------------------------ */ 2013 ////////////////////////////////////////////////////////////////////////////// 2014 // h264_dpb_mm_update_max_long_term_frame_idx () 2015 // 2016 // Set new max long_term_frame_idx 2017 // 2018 2019 void h264_dpb_mm_update_max_long_term_frame_idx(h264_DecodedPictureBuffer *p_dpb,int32_t max_long_term_frame_idx_plus1) 2020 { 2021 //h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 2022 int32_t idx; 2023 int32_t temp; 2024 int32_t removed_count; 2025 int32_t idx2 = 0; 2026 2027 p_dpb->max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1; 2028 2029 temp = p_dpb->ltref_frames_in_buffer; 2030 removed_count = 0; 2031 2032 // check for invalid frames 2033 for (idx = 0; idx < temp; idx++) 2034 { 2035 idx2 = idx - removed_count; 2036 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx2]); 2037 2038 if (active_fs->long_term_frame_idx > p_dpb->max_long_term_pic_idx) 2039 { 2040 removed_count++; 2041 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx2]); 2042 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx2]); 2043 } 2044 } 2045 return; 2046 } 2047 /* ------------------------------------------------------------------------------------------ */ 2048 /* ------------------------------------------------------------------------------------------ */ 2049 /* ------------------------------------------------------------------------------------------ */ 2050 ////////////////////////////////////////////////////////////////////////////// 2051 // h264_dpb_mm_unmark_all_short_term_for_reference () 2052 // 2053 // Unmark all short term refernce pictures 2054 // 2055 2056 void h264_dpb_mm_unmark_all_short_term_for_reference (h264_DecodedPictureBuffer *p_dpb) 2057 { 2058 int32_t idx; 2059 int32_t temp = p_dpb->ref_frames_in_buffer; 2060 2061 for (idx = 0; idx < temp; idx++) 2062 { 2063 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]); 2064 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]); 2065 } 2066 return; 2067 } 2068 /* ------------------------------------------------------------------------------------------ */ 2069 /* ------------------------------------------------------------------------------------------ */ 2070 /* ------------------------------------------------------------------------------------------ */ 2071 ////////////////////////////////////////////////////////////////////////////// 2072 // h264_dpb_mm_mark_current_picture_long_term () 2073 // 2074 // Marks the current picture as long term after unmarking any long term picture 2075 // already assigned with the same long term frame index 2076 // 2077 2078 void h264_dpb_mm_mark_current_picture_long_term(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx) 2079 { 2080 int32_t picNumX; 2081 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 2082 2083 if (viddec_h264_get_dec_structure(active_fs) == FRAME) 2084 { 2085 h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(p_dpb, long_term_frame_idx); 2086 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 2087 active_fs->frame.is_long_term = 1; 2088 active_fs->frame.long_term_frame_idx = long_term_frame_idx; 2089 active_fs->frame.long_term_pic_num = long_term_frame_idx; 2090 } 2091 else 2092 { 2093 if(viddec_h264_get_dec_structure(active_fs) == TOP_FIELD) 2094 { 2095 picNumX = (active_fs->top_field.pic_num << 1) + 1; 2096 active_fs->top_field.is_long_term = 1; 2097 active_fs->top_field.long_term_frame_idx = long_term_frame_idx; 2098 2099 // Assign long-term pic num 2100 active_fs->top_field.long_term_pic_num = (long_term_frame_idx << 1) + 1; 2101 } 2102 else 2103 { 2104 picNumX = (active_fs->bottom_field.pic_num << 1) + 1; 2105 active_fs->bottom_field.is_long_term = 1; 2106 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx; 2107 2108 // Assign long-term pic num 2109 active_fs->bottom_field.long_term_pic_num = (long_term_frame_idx << 1) + 1; 2110 2111 } 2112 h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(p_dpb, long_term_frame_idx, p_dpb->fs_dec_idc, viddec_h264_get_dec_structure(active_fs)); 2113 } 2114 // Add to long term list 2115 //h264_dpb_add_ltref_list(p_dpb->fs_dec_idc); 2116 2117 return; 2118 } 2119 /* ------------------------------------------------------------------------------------------ */ 2120 /* ------------------------------------------------------------------------------------------ */ 2121 /* ------------------------------------------------------------------------------------------ */ 2122 ////////////////////////////////////////////////////////////////////////////// 2123 // h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx () 2124 // 2125 // Mark a long-term reference frame or complementary field pair unused for referemce 2126 // NOTE: Obviously this ftn cannot be used to unmark individual fields... 2127 ////////////////////////////////////////////////////////////////////////////// 2128 2129 void h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx) 2130 { 2131 uint32_t idx; 2132 for(idx =0; idx < p_dpb->ltref_frames_in_buffer; idx++) 2133 { 2134 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 2135 2136 if (active_fs->long_term_frame_idx == long_term_frame_idx) 2137 { 2138 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx]); 2139 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]); 2140 } 2141 } 2142 return; 2143 } 2144 2145 /* ------------------------------------------------------------------------------------------ */ 2146 /* ------------------------------------------------------------------------------------------ */ 2147 /* ------------------------------------------------------------------------------------------ */ 2148 ////////////////////////////////////////////////////////////////////////////// 2149 // h264_dpb_unmark_long_term_field_for_reference_by_frame_idx () 2150 // 2151 // Mark a long-term reference field unused for reference. However if it is the 2152 // complementary field (opposite polarity) of the picture stored in fs_idc, 2153 // we do not unmark it 2154 ////////////////////////////////////////////////////////////////////////////// 2155 2156 void h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx, int32_t fs_idc, int32_t polarity) 2157 { 2158 uint32_t idx; 2159 int32_t found = 0; 2160 int32_t is_complement = 0; 2161 2162 for (idx = 0; (idx < p_dpb->ltref_frames_in_buffer) && (found == 0); idx++) 2163 { 2164 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]); 2165 if (active_fs->long_term_frame_idx == long_term_frame_idx) 2166 { 2167 if(active_fs->fs_idc == fs_idc) 2168 { 2169 // Again these seem like redundant checks but for safety while until JM is updated 2170 if (polarity == TOP_FIELD) 2171 is_complement = (active_fs->bottom_field.is_long_term)? 1:0; 2172 else if(polarity == BOTTOM_FIELD) 2173 is_complement = (active_fs->top_field.is_long_term) ? 1:0; 2174 } 2175 found = 1; 2176 } 2177 } 2178 2179 if(found) { 2180 if(is_complement == 0) 2181 { 2182 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx-1]); 2183 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx-1]); 2184 } 2185 } 2186 2187 return; 2188 } 2189 2190 2191 /* ------------------------------------------------------------------------------------------ */ 2192 /* ------------------------------------------------------------------------------------------ */ 2193 /* ------------------------------------------------------------------------------------------ */ 2194 ////////////////////////////////////////////////////////////////////////////// 2195 // h264_dpb_mark_pic_long_term () 2196 // 2197 // This is used on a picture already in the dpb - i.e. not for the current picture 2198 // dpb_split / dpb_combine field will perform ftnality in that case 2199 // 2200 // Marks a picture as used for long-term reference. Adds it to the long-term 2201 // reference list. Also removes it from the short term reference list if required 2202 // 2203 // Note: if the current picture is a frame, the picture to be marked will be a 2204 // short-term reference frame or short-term complemenetary reference field pair 2205 // We use the pic_num assigned to the frame part of the structure to locate it 2206 // Both its fields will have their long_term_frame_idx and long_term_pic_num 2207 // assigned to be equal to long_term_frame_idx 2208 // 2209 // If the current picture is a field, the picture to be marked will be a 2210 // short-term reference field. We use the pic_nums assigned to the field parts of 2211 // the structure to identify the appropriate field. We assign the long_term_frame_idx 2212 // of the field equal to long_term_frame_idx. 2213 // 2214 // We also check to see if this marking has resulted in both fields of the frame 2215 // becoming long_term. If it has, we update the frame part of the structure by 2216 // setting its long_term_frame_idx 2217 ////////////////////////////////////////////////////////////////////////////// 2218 2219 void h264_dpb_mark_pic_long_term(h264_Info * pInfo, int32_t long_term_frame_idx, int32_t picNumX) 2220 { 2221 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 2222 uint32_t idx; 2223 int32_t mark_done; 2224 int32_t polarity = 0; 2225 2226 mark_done = 0; 2227 2228 if (pInfo->img.structure == FRAME) 2229 { 2230 for (idx = 0; (idx < p_dpb->ref_frames_in_buffer) && (!(mark_done)); idx++) 2231 { 2232 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]); 2233 2234 if (active_fs->frame.used_for_reference == 3) 2235 { 2236 if ((!(active_fs->frame.is_long_term))&&(active_fs->frame.pic_num == picNumX)) 2237 { 2238 active_fs->long_term_frame_idx = long_term_frame_idx; 2239 active_fs->frame.long_term_frame_idx = long_term_frame_idx; 2240 active_fs->top_field.long_term_frame_idx = long_term_frame_idx; 2241 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx; 2242 2243 active_fs->frame.is_long_term = 1; 2244 active_fs->top_field.is_long_term = 1; 2245 active_fs->bottom_field.is_long_term = 1; 2246 2247 viddec_h264_set_is_frame_long_term(active_fs, 3); 2248 mark_done = 1; 2249 2250 // Assign long-term pic num 2251 active_fs->frame.long_term_pic_num = long_term_frame_idx; 2252 active_fs->top_field.long_term_pic_num = long_term_frame_idx; 2253 active_fs->bottom_field.long_term_pic_num = long_term_frame_idx; 2254 // Add to long term list 2255 h264_dpb_add_ltref_list(p_dpb, p_dpb->fs_ref_idc[idx]); 2256 // Remove from short-term list 2257 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]); 2258 } 2259 } 2260 } 2261 } 2262 else 2263 { 2264 polarity = h264_dpb_get_pic_struct_by_pic_num(p_dpb, picNumX); 2265 active_fs->long_term_frame_idx = long_term_frame_idx; /////BUG 2266 2267 if(polarity == TOP_FIELD) 2268 { 2269 active_fs->top_field.long_term_frame_idx = long_term_frame_idx; 2270 active_fs->top_field.is_long_term = 1; 2271 viddec_h264_set_is_top_long_term(active_fs, 1); 2272 2273 // Assign long-term pic num 2274 active_fs->top_field.long_term_pic_num = (long_term_frame_idx << 1) + ((pInfo->img.structure == TOP_FIELD) ? 1 : 0); 2275 2276 } 2277 else if (polarity == BOTTOM_FIELD) 2278 { 2279 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx; 2280 active_fs->bottom_field.is_long_term = 1; 2281 viddec_h264_set_is_bottom_long_term(active_fs, 1); 2282 2283 // Assign long-term pic num 2284 active_fs->bottom_field.long_term_pic_num = (long_term_frame_idx << 1) + ((pInfo->img.structure == BOTTOM_FIELD) ? 1 : 0); 2285 } 2286 2287 if (viddec_h264_get_is_long_term(active_fs) == 3) 2288 { 2289 active_fs->frame.is_long_term = 1; 2290 active_fs->frame.long_term_frame_idx = long_term_frame_idx; 2291 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc); 2292 } 2293 else 2294 { 2295 // We need to add this idc to the long term ref list... 2296 h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc); 2297 2298 // If the opposite field is not a short term reference, remove it from the 2299 // short term list. Since we know top field is a reference but both are not long term 2300 // we can simply check that both fields are not references... 2301 if(active_fs->frame.used_for_reference != 3) 2302 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc); 2303 } 2304 } 2305 return; 2306 } ///// End of mark pic long term 2307 2308 2309 /* ------------------------------------------------------------------------------------------ */ 2310 /* ------------------------------------------------------------------------------------------ */ 2311 /* ------------------------------------------------------------------------------------------ */ 2312 ////////////////////////////////////////////////////////////////////////////// 2313 // h264_dpb_adaptive_memory_management () 2314 // 2315 // Perform Adaptive memory control decoded reference picture marking process 2316 ////////////////////////////////////////////////////////////////////////////// 2317 2318 void h264_dpb_adaptive_memory_management (h264_Info * pInfo) 2319 { 2320 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 2321 int32_t idx; 2322 2323 idx = 0; 2324 2325 while (idx < pInfo->SliceHeader.sh_dec_refpic.dec_ref_pic_marking_count) 2326 { 2327 switch(pInfo->SliceHeader.sh_dec_refpic.memory_management_control_operation[idx]) 2328 { 2329 case 1:{ //Mark a short-term reference picture as unused for reference? 2330 h264_dpb_mm_unmark_short_term_for_reference(pInfo, 2331 pInfo->SliceHeader.sh_dec_refpic.difference_of_pic_num_minus1[idx]); 2332 } break; 2333 case 2:{ //Mark a long-term reference picture as unused for reference? 2334 h264_dpb_mm_unmark_long_term_for_reference(pInfo, 2335 pInfo->SliceHeader.sh_dec_refpic.long_term_pic_num[idx]); 2336 }break; 2337 case 3:{ //Mark a short-term reference picture as "used for long-term reference" and assign a long-term frame index to it 2338 h264_dpb_mm_assign_long_term_frame_idx(pInfo, 2339 pInfo->SliceHeader.sh_dec_refpic.difference_of_pic_num_minus1[idx], 2340 pInfo->SliceHeader.sh_dec_refpic.long_term_frame_idx[idx]); 2341 }break; 2342 case 4:{ //Specify the maximum long-term frame index and 2343 //mark all long-term reference pictureshaving long-term frame indices greater than 2344 //the maximum value as "unused for reference" 2345 h264_dpb_mm_update_max_long_term_frame_idx (&pInfo->dpb, 2346 pInfo->SliceHeader.sh_dec_refpic.max_long_term_frame_idx_plus1[idx]); 2347 }break; 2348 case 5:{ //Mark all reference pictures as "unused for reference" and set the MaxLongTermFrameIdx variable to 2349 // "no long-term frame indices" 2350 h264_dpb_mm_unmark_all_short_term_for_reference(&pInfo->dpb); 2351 h264_dpb_mm_update_max_long_term_frame_idx(&pInfo->dpb, 0); 2352 pInfo->img.last_has_mmco_5 = 1; 2353 }break; 2354 case 6:{ //Mark the current picture as "used for long-term reference" and assign a long-term frame index to it 2355 h264_dpb_mm_mark_current_picture_long_term(&pInfo->dpb, 2356 pInfo->SliceHeader.sh_dec_refpic.long_term_frame_idx[idx]); 2357 }break; 2358 } 2359 idx++; 2360 } 2361 2362 2363 if (pInfo->img.last_has_mmco_5) 2364 { 2365 pInfo->img.frame_num = 0; 2366 pInfo->SliceHeader.frame_num=0; 2367 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 2368 2369 if (viddec_h264_get_dec_structure(active_fs) == FRAME) 2370 { 2371 pInfo->img.bottompoc -= active_fs->frame.poc; 2372 pInfo->img.toppoc -= active_fs->frame.poc; 2373 2374 2375 active_fs->frame.poc = 0; 2376 active_fs->frame.pic_num = 0; 2377 active_fs->frame_num = 0; 2378 } 2379 2380 else if (viddec_h264_get_dec_structure(active_fs) == TOP_FIELD) 2381 { 2382 active_fs->top_field.poc = active_fs->top_field.pic_num = 0; 2383 pInfo->img.toppoc = active_fs->top_field.poc; 2384 } 2385 else if (viddec_h264_get_dec_structure(active_fs) == BOTTOM_FIELD) 2386 { 2387 active_fs->bottom_field.poc = active_fs->bottom_field.pic_num = 0; 2388 pInfo->img.bottompoc = 0; 2389 } 2390 2391 h264_dpb_flush_dpb(pInfo, 1, pInfo->img.second_field,pInfo->active_SPS.num_ref_frames); 2392 } 2393 // Reset the marking count operations for the current picture... 2394 pInfo->SliceHeader.sh_dec_refpic.dec_ref_pic_marking_count = 0; 2395 2396 return; 2397 } ////// End of adaptive memory management 2398 2399 /* ------------------------------------------------------------------------------------------ */ 2400 /* ------------------------------------------------------------------------------------------ */ 2401 /* ------------------------------------------------------------------------------------------ */ 2402 ////////////////////////////////////////////////////////////////////////////// 2403 // h264_dpb_gaps_in_frame_num_mem_management () 2404 // 2405 // Produces a set of frame_nums pertaining to "non-existing" pictures 2406 // Calls h264_dpb_store_picture_in_dpb 2407 ////////////////////////////////////////////////////////////////////////////// 2408 2409 void h264_dpb_gaps_in_frame_num_mem_management(h264_Info * pInfo) 2410 { 2411 int32_t temp_frame_num = 0; 2412 int32_t idx, prev_idc; 2413 int32_t prev_frame_num_plus1_wrap; 2414 uint32_t temp; 2415 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4); 2416 seq_param_set_used_ptr active_sps = &pInfo->active_SPS; 2417 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 2418 2419 pInfo->img.gaps_in_frame_num = 0; 2420 2421 // pInfo->img.last_has_mmco_5 set thru store_picture_in_dpb 2422 if (pInfo->img.last_has_mmco_5) 2423 { 2424 // If the previous picture was an unpaired field, mark it as a dangler 2425 if(p_dpb->used_size) 2426 { 2427 idx = p_dpb->used_size-1; 2428 prev_idc = p_dpb->fs_dpb_idc[idx]; 2429 if (prev_idc != MPD_DPB_FS_NULL_IDC) 2430 { 2431 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 2432 active_fs->frame_num =0; 2433 } 2434 } 2435 pInfo->img.PreviousFrameNumOffset = 0; 2436 //CONFORMANCE_ISSUE 2437 pInfo->img.PreviousFrameNum = 0; 2438 2439 } 2440 2441 // Check for gaps in frame_num 2442 if(pInfo->SliceHeader.idr_flag) { 2443 pInfo->img.PreviousFrameNum = pInfo->img.frame_num; 2444 } 2445 // Have we re-started following a recovery point message? 2446 /* 2447 else if(got_sei_recovery || aud_got_restart){ 2448 pInfo->img.PreviousFrameNum = pInfo->img.frame_num; 2449 //got_sei_recovery = 0; 2450 //aud_got_restart = 0; 2451 } 2452 */ 2453 else if(pInfo->img.frame_num != pInfo->img.PreviousFrameNum) 2454 { 2455 if (MaxFrameNum) 2456 ldiv_mod_u((uint32_t)(pInfo->img.PreviousFrameNum + 1), (uint32_t)MaxFrameNum, &temp); 2457 2458 prev_frame_num_plus1_wrap = temp; 2459 if(pInfo->img.frame_num != prev_frame_num_plus1_wrap) 2460 { 2461 pInfo->img.gaps_in_frame_num = (pInfo->img.frame_num < pInfo->img.PreviousFrameNum)? ((MaxFrameNum + pInfo->img.frame_num -1) - pInfo->img.PreviousFrameNum): (pInfo->img.frame_num - pInfo->img.PreviousFrameNum - 1); 2462 // We should test for an error here - should infer an unintentional loss of pictures 2463 } 2464 } 2465 2466 2467 //if(active_sps->gaps_in_frame_num_value_allowed_flag == 0) { 2468 if(pInfo->img.gaps_in_frame_num && (active_sps->gaps_in_frame_num_value_allowed_flag == 0)) { 2469 // infer an unintentional loss of pictures 2470 // only invoke following process for a conforming bitstream 2471 // when gaps_in_frame_num_value_allowed_flag is equal to 1 2472 pInfo->img.gaps_in_frame_num = 0; 2473 2474 //mfd_printf("ERROR STREAM??\n"); 2475 ////// Error handling here---- 2476 } 2477 2478 /////// Removed following OLO source (Sodaville H.D) 2479 //else if (pInfo->img.gaps_in_frame_num > active_sps->num_ref_frames) { 2480 // // No need to produce any more non-existent frames than the amount required to flush the dpb 2481 // pInfo->img.gaps_in_frame_num = active_sps->num_ref_frames; 2482 //mfd_printf("gaps in frame: %d\n", gaps_in_frame_num); 2483 //} 2484 2485 // If the previous picture was an unpaired field, mark it as a dangler 2486 if(p_dpb->used_size) 2487 { 2488 idx = p_dpb->used_size-1; 2489 prev_idc = p_dpb->fs_dpb_idc[idx]; 2490 if (prev_idc != MPD_DPB_FS_NULL_IDC) 2491 { 2492 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 2493 if(viddec_h264_get_is_used(active_fs) != 3) { 2494 h264_dpb_mark_dangling_field(p_dpb, active_fs->fs_idc); //, DANGLING_TYPE_GAP_IN_FRAME 2495 } 2496 } 2497 } 2498 2499 while(temp_frame_num < pInfo->img.gaps_in_frame_num) 2500 { 2501 h264_dpb_assign_frame_store(pInfo, 1); 2502 2503 // Set up initial markings - not sure if all are needed 2504 viddec_h264_set_dec_structure(active_fs, FRAME); 2505 2506 if(MaxFrameNum) 2507 ldiv_mod_u((uint32_t)(pInfo->img.PreviousFrameNum + 1), (uint32_t)MaxFrameNum, &temp); 2508 2509 active_fs->frame.pic_num = temp; 2510 active_fs->long_term_frame_idx = 0; 2511 active_fs->frame.long_term_pic_num = 0; 2512 viddec_h264_set_is_frame_long_term(active_fs, 0); 2513 2514 // Note the call below will overwrite some aspects of the img structure with info relating to the 2515 // non-existent picture 2516 // However, since this is called before h264_hdr_decoding_poc() for the current existing picture 2517 // it should be o.k. 2518 if(pInfo->img.pic_order_cnt_type) 2519 h264_hdr_decoding_poc(pInfo, 1, temp); 2520 2521 pInfo->img.structure = FRAME; 2522 active_fs->frame.poc = pInfo->img.framepoc; 2523 2524 // call store_picture_in_dpb 2525 2526 h264_dpb_store_previous_picture_in_dpb(pInfo, 1, 0); 2527 2528 h264_hdr_post_poc(pInfo, 1, temp, 0); 2529 2530 temp_frame_num++; 2531 } 2532 } 2533 2534 /* ------------------------------------------------------------------------------------------ */ 2535 /* ------------------------------------------------------------------------------------------ */ 2536 /* ------------------------------------------------------------------------------------------ */ 2537 2538 ////////////////////////////////////////////////////////////////////////////// 2539 // h264_dpb_unmark_for_reference () 2540 // 2541 // Mark FrameStore unused for reference. Removes it from the short term reference list 2542 ////////////////////////////////////////////////////////////////////////////// 2543 2544 void h264_dpb_unmark_for_reference(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc) 2545 { 2546 h264_dpb_set_active_fs(p_dpb, fs_idc); 2547 2548 if (viddec_h264_get_is_used(active_fs)&0x1) active_fs->top_field.used_for_reference = 0; 2549 if (viddec_h264_get_is_used(active_fs)&0x2) active_fs->bottom_field.used_for_reference = 0; 2550 if (viddec_h264_get_is_used(active_fs) == 3) active_fs->frame.used_for_reference = 0; 2551 2552 active_fs->frame.used_for_reference = 0; 2553 return; 2554 } 2555 2556 2557 /* ------------------------------------------------------------------------------------------ */ 2558 /* ------------------------------------------------------------------------------------------ */ 2559 /* ------------------------------------------------------------------------------------------ */ 2560 ////////////////////////////////////////////////////////////////////////////// 2561 // h264_dpb_unmark_for_long_term_reference () 2562 // 2563 // mark FrameStore unused for reference and reset long term flags 2564 // This function does not remove it form the long term list 2565 ////////////////////////////////////////////////////////////////////////////// 2566 2567 void h264_dpb_unmark_for_long_term_reference(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc) 2568 { 2569 h264_dpb_set_active_fs(p_dpb, fs_idc); 2570 2571 if (viddec_h264_get_is_used(active_fs)&0x1) 2572 { 2573 active_fs->top_field.used_for_reference = 0; 2574 active_fs->top_field.is_long_term = 0; 2575 } 2576 2577 if (viddec_h264_get_is_used(active_fs)&0x2) 2578 { 2579 active_fs->bottom_field.used_for_reference = 0; 2580 active_fs->bottom_field.is_long_term = 0; 2581 } 2582 if (viddec_h264_get_is_used(active_fs) == 3) 2583 { 2584 active_fs->frame.used_for_reference = 0; 2585 active_fs->frame.is_long_term = 0; 2586 } 2587 2588 active_fs->frame.used_for_reference = 0; 2589 viddec_h264_set_is_frame_long_term(active_fs, 0); 2590 2591 return; 2592 } 2593 2594 2595 /* ------------------------------------------------------------------------------------------ */ 2596 /* ------------------------------------------------------------------------------------------ */ 2597 /* ------------------------------------------------------------------------------------------ */ 2598 ////////////////////////////////////////////////////////////////////////////// 2599 // h264_dpb_mark_dangling_field 2600 // 2601 // Tells HW previous field was dangling 2602 // Marks it in SW as so 2603 // Takes appropriate actions. - sys_data needs thought through... 2604 ////////////////////////////////////////////////////////////////////////////// 2605 2606 void h264_dpb_mark_dangling_field(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc) 2607 { 2608 2609 h264_dpb_set_active_fs(p_dpb, fs_idc); 2610 2611 //PRINTF(MFD_NONE, " fs_idc = %d DANGLING_TYPE = %d \n", fs_idc, reason); 2612 /* 2613 Make the check that it has not already been marked 2614 This covers the situation of a dangling field followed by a 2615 frame which is direct output (i.e. never entered into the dpb). 2616 In this case we could attempt to mark the prev unpaired field 2617 as a dangler twice which would upset the HW dpb_disp_q count 2618 */ 2619 2620 if(viddec_h264_get_is_dangling(active_fs) == 0) 2621 { 2622 switch(viddec_h264_get_dec_structure(active_fs)) 2623 { 2624 case TOP_FIELD: 2625 viddec_h264_set_is_dangling(active_fs, 1); 2626 //PRINTF(MFD_NONE, "FN:%d fs_idc=%d FRAME_FLAG_DANGLING_TOP_FIELD\n ", (h264_frame_number+1), active_fs->fs_idc); 2627 break; 2628 case BOTTOM_FIELD: 2629 //PRINTF(MFD_NONE, " FN:%d fs_idc=%d FRAME_FLAG_DANGLING_BOTTOM_FIELD \n ", (h264_frame_number+1), active_fs->fs_idc); 2630 viddec_h264_set_is_dangling(active_fs, 1); 2631 break; 2632 default: 2633 //PRINTF(MFD_NONE, "FN:%d fs_idc=%d DANGLING: FATAL_ERROR\n ", (h264_frame_number+1), active_fs->fs_idc); 2634 break; 2635 } 2636 2637 //h264_send_new_decoded_frame(); 2638 } 2639 return; 2640 } 2641 2642 /* ------------------------------------------------------------------------------------------ */ 2643 /* ------------------------------------------------------------------------------------------ */ 2644 /* ------------------------------------------------------------------------------------------ */ 2645 2646 2647 ////////////////////////////////////////////////////////////////////////////// 2648 // h264_dpb_is_used_for_reference () 2649 // 2650 // Check if one of the frames/fields in active_fs is used for reference 2651 // 2652 void h264_dpb_is_used_for_reference(int32_t * flag) 2653 { 2654 2655 /* Check out below for embedded */ 2656 *flag = 0; 2657 if (active_fs->frame.used_for_reference) 2658 *flag = 1; 2659 else if (viddec_h264_get_is_used(active_fs) ==3) // frame 2660 *flag = active_fs->frame.used_for_reference; 2661 else 2662 { 2663 if (viddec_h264_get_is_used(active_fs)&0x1) // top field 2664 *flag = active_fs->top_field.used_for_reference; 2665 if (viddec_h264_get_is_used(active_fs)&0x2) // bottom field 2666 *flag = *flag || active_fs->bottom_field.used_for_reference; 2667 } 2668 } 2669 2670 /* ------------------------------------------------------------------------------------------ */ 2671 /* ------------------------------------------------------------------------------------------ */ 2672 /* ------------------------------------------------------------------------------------------ */ 2673 ////////////////////////////////////////////////////////////////////////////// 2674 // h264_dpb_idr_memory_management () 2675 // 2676 // Perform Memory management for idr pictures 2677 ////////////////////////////////////////////////////////////////////////////// 2678 2679 void h264_dpb_idr_memory_management (h264_Info * pInfo,seq_param_set_used_ptr active_sps, int32_t no_output_of_prior_pics_flag) 2680 { 2681 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 2682 uint32_t idx; 2683 uint32_t i; 2684 int32_t DPB_size; 2685 int32_t FrameSizeInBytes, FrameSizeInMbs; 2686 uint32_t data; 2687 int32_t num_ref_frames = active_sps->num_ref_frames; 2688 int32_t level_idc = active_sps->level_idc; 2689 uint32_t temp_bump_level=0; 2690 2691 2692 /// H.D----- 2693 /// There are 2 kinds of dpb flush defined, one is with display, the other is without display 2694 /// The function name dpb_flush actually is just the first, and the 2nd one is for error case or no_prior_output 2695 /// We will rewrite the code below to make it clean and clear 2696 /// 2697 if (no_output_of_prior_pics_flag) 2698 { 2699 2700 // free all stored pictures 2701 for (idx = 0; idx < p_dpb->used_size; idx = idx + 1) 2702 { 2703 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 2704 2705 //mfd_printf(" directly freeing fs_idc = %d DSN = 0x%x \n",active_fs->fs_idc, active_fs->first_dsn); 2706 viddec_h264_set_is_frame_used(active_fs, 0); 2707 //if( (active_fs->frame_sent == 0x01) && (active_fs->is_output == 0x0)) 2708 { 2709 //DECODED_FRAME sent but not DISPLAY_FRAME 2710 h264_dpb_unmark_for_reference(p_dpb, active_fs->fs_idc); 2711 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc); 2712 //h264_send_new_display_frame(0x01); //send ignore_frame signal to Host 2713 2714 /// Add into drop-out list for all frms in dpb without display 2715 if(!(viddec_h264_get_is_non_existent(active_fs))) { 2716 if( viddec_h264_get_is_output(&(p_dpb->fs[p_dpb->fs_dpb_idc[idx]])) ) { //// This frame has been displayed but not released 2717 p_dpb->frame_id_need_to_be_removed[p_dpb->frame_numbers_need_to_be_removed] = p_dpb->fs_dpb_idc[idx]; 2718 p_dpb->frame_numbers_need_to_be_removed ++; 2719 } else { //// This frame will be removed without display 2720 p_dpb->frame_id_need_to_be_dropped[p_dpb->frame_numbers_need_to_be_dropped] = p_dpb->fs_dpb_idc[idx]; 2721 p_dpb->frame_numbers_need_to_be_dropped ++; 2722 } 2723 } 2724 } 2725 2726 } 2727 2728 ////////////////////////////////////////// Reset Reference list 2729 for (i = 0; i < p_dpb->ref_frames_in_buffer; i++) 2730 p_dpb->fs_ref_idc[i] = MPD_DPB_FS_NULL_IDC; 2731 2732 for (i = 0; i < p_dpb->ltref_frames_in_buffer; i++) 2733 p_dpb->fs_ltref_idc[i] = MPD_DPB_FS_NULL_IDC; 2734 2735 ////////////////////////////////////////// Reset DPB and dpb list 2736 for (i = 0; i < p_dpb->used_size; i++) { 2737 p_dpb->fs[p_dpb->fs_dpb_idc[i]].fs_idc = MPD_DPB_FS_NULL_IDC; 2738 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC; 2739 } 2740 2741 p_dpb->used_size = 0; 2742 p_dpb->ref_frames_in_buffer = 0; 2743 p_dpb->ltref_frames_in_buffer = 0; 2744 2745 p_dpb->last_output_poc = 0x80000000; 2746 } 2747 else { 2748 h264_dpb_flush_dpb(pInfo, 1, pInfo->img.second_field, num_ref_frames); 2749 } 2750 2751 if (p_dpb->fs_dec_idc != MPD_DPB_FS_NULL_IDC) // added condition for use of DPB initialization 2752 { 2753 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 2754 if (pInfo->img.long_term_reference_flag) 2755 { 2756 p_dpb->max_long_term_pic_idx = 0; 2757 switch (viddec_h264_get_dec_structure(active_fs)) 2758 { 2759 case FRAME : active_fs->frame.is_long_term = 1; 2760 case TOP_FIELD : active_fs->top_field.is_long_term = 1; 2761 case BOTTOM_FIELD : active_fs->bottom_field.is_long_term = 1; 2762 } 2763 active_fs->long_term_frame_idx = 0; 2764 } 2765 else 2766 { 2767 p_dpb->max_long_term_pic_idx = MPD_DPB_FS_NULL_IDC; 2768 viddec_h264_set_is_frame_long_term(active_fs, 0); 2769 } 2770 } 2771 2772 p_dpb->OutputLevel = 0; 2773 p_dpb->OutputLevelValid = 0; 2774 p_dpb->OutputCtrl = 0; 2775 2776 2777 // Set up bumping level - do this every time a parameters set is activated... 2778 if(active_sps->sps_disp.vui_parameters_present_flag) 2779 { 2780 if(active_sps->sps_disp.vui_seq_parameters.bitstream_restriction_flag) 2781 { 2782 //p_dpb->OutputLevel = active_sps->sps_disp.vui_seq_parameters.num_reorder_frames; 2783 //p_dpb->OutputLevelValid = 1; 2784 } 2785 } 2786 2787 // Set up bumping level - do this every time a parameters set is activated... 2788 switch(level_idc) 2789 { 2790 case h264_Level1b: 2791 case h264_Level1: 2792 { 2793 if ((active_sps->profile_idc < 100) && ((active_sps->constraint_set_flags & 0x1) == 0)) { 2794 DPB_size = 338; 2795 } 2796 else { 2797 DPB_size = 149; 2798 } 2799 2800 break; 2801 } 2802 case h264_Level11: 2803 { 2804 DPB_size = 338; 2805 break; 2806 } 2807 case h264_Level12: 2808 case h264_Level13: 2809 case h264_Level2: 2810 { 2811 DPB_size = 891; 2812 break; 2813 } 2814 case h264_Level21: 2815 { 2816 DPB_size = 1782; 2817 break; 2818 } 2819 case h264_Level22: 2820 case h264_Level3: 2821 { 2822 DPB_size = 3038; 2823 break; 2824 } 2825 case h264_Level31: 2826 { 2827 DPB_size = 6750; 2828 break; 2829 } 2830 case h264_Level32: 2831 { 2832 DPB_size = 7680; 2833 break; 2834 } 2835 case h264_Level4: 2836 case h264_Level41: 2837 { 2838 DPB_size = 12288; 2839 break; 2840 } 2841 case h264_Level42: 2842 { 2843 DPB_size = 13056; 2844 break; 2845 } 2846 case h264_Level5: 2847 { 2848 DPB_size = 41400; 2849 break; 2850 } 2851 case h264_Level51: 2852 { 2853 DPB_size = 69120; 2854 break; 2855 } 2856 default : DPB_size = 69120; break; 2857 } 2858 2859 FrameSizeInMbs = pInfo->img.PicWidthInMbs * pInfo->img.FrameHeightInMbs; 2860 FrameSizeInBytes = (FrameSizeInMbs << 8) + (FrameSizeInMbs << 7); 2861 2862 if(FrameSizeInBytes) 2863 { 2864 2865 temp_bump_level = ldiv_mod_u((DPB_size << 10), FrameSizeInBytes, &data); 2866 2867 if(temp_bump_level > 255) 2868 { 2869 p_dpb->BumpLevel = 255; 2870 } 2871 else 2872 { 2873 p_dpb->BumpLevel = (uint8_t)temp_bump_level; 2874 } 2875 } 2876 2877 if (p_dpb->BumpLevel == 0) 2878 p_dpb->BumpLevel = active_sps->num_ref_frames + 1; 2879 2880 if (p_dpb->BumpLevel > 16) 2881 p_dpb->BumpLevel = 16; 2882 2883 2884 if(active_sps->sps_disp.vui_parameters_present_flag && active_sps->sps_disp.vui_seq_parameters.bitstream_restriction_flag) { 2885 2886 if (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering > p_dpb->BumpLevel) { 2887 //MFD_PARSER_DEBUG(ERROR_H264_DPB); 2888 //// err handling here 2889 } 2890 else { 2891 p_dpb->BumpLevel = (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering > 1) ? 2892 (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering) : 1; 2893 } 2894 } 2895 2896 2897 // A new sequence means automatic frame release 2898 //sei_information.disp_frozen = 0; 2899 2900 return; 2901 } //// End --- dpb_idr_memory_management 2902 2903 /* ------------------------------------------------------------------------------------------ */ 2904 /* ------------------------------------------------------------------------------------------ */ 2905 /* ------------------------------------------------------------------------------------------ */ 2906 ////////////////////////////////////////////////////////////////////////////// 2907 // h264_dpb_remove_frame_from_dpb () 2908 // 2909 // remove one frame from DPB 2910 // The parameter index, is the location of the frame to be removed in the 2911 // fs_dpb_idc list. The used size is decremented by one 2912 ////////////////////////////////////////////////////////////////////////////// 2913 2914 void h264_dpb_remove_frame_from_dpb(h264_DecodedPictureBuffer *p_dpb, int32_t idx) 2915 { 2916 int32_t fs_idc; 2917 uint32_t i; 2918 2919 fs_idc = p_dpb->fs_dpb_idc[idx]; 2920 2921 h264_dpb_set_active_fs(p_dpb, fs_idc); 2922 viddec_h264_set_is_frame_used(active_fs, 0); 2923 2924 //add to support frame relocation interface to host 2925 if(!(viddec_h264_get_is_non_existent(active_fs))) 2926 { 2927 p_dpb->frame_id_need_to_be_removed[p_dpb->frame_numbers_need_to_be_removed] = p_dpb->fs[fs_idc].fs_idc; 2928 p_dpb->frame_numbers_need_to_be_removed ++; 2929 } 2930 2931 ///////////////////////////////////////// Reset FS 2932 p_dpb->fs[fs_idc].fs_idc = MPD_DPB_FS_NULL_IDC; 2933 2934 /////Remove unused frame from dpb-list 2935 i = idx; 2936 while( (i + 1)< p_dpb->used_size) 2937 { 2938 p_dpb->fs_dpb_idc[i] = p_dpb->fs_dpb_idc[i + 1]; 2939 i ++; 2940 } 2941 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC; 2942 2943 //////////////////////////// 2944 p_dpb->used_size--; 2945 2946 return; 2947 } 2948 2949 /* ------------------------------------------------------------------------------------------ */ 2950 /* ------------------------------------------------------------------------------------------ */ 2951 /* ------------------------------------------------------------------------------------------ */ 2952 2953 ////////////////////////////////////////////////////////////////////////////// 2954 // h264_dpb_remove_unused_frame_from_dpb () 2955 // 2956 // Remove a picture from DPB which is no longer needed. 2957 // Search for a frame which is not used for reference and has previously been placed 2958 // in the output queue - if find one call h264_dpb_remove_frame_from_dpb() and 2959 // set flag 1 2960 ////////////////////////////////////////////////////////////////////////////// 2961 2962 void h264_dpb_remove_unused_frame_from_dpb(h264_DecodedPictureBuffer *p_dpb, int32_t * flag) 2963 { 2964 uint32_t idx; 2965 int32_t first_non_exist_valid, non_exist_idx; 2966 int32_t used_for_reference = 0; 2967 2968 *flag = 0; 2969 first_non_exist_valid = 0x0; 2970 non_exist_idx = 0x0; 2971 2972 for (idx = 0; (idx < p_dpb->used_size) && (*flag == 0); idx++) 2973 { 2974 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 2975 h264_dpb_is_used_for_reference(&used_for_reference); 2976 2977 //if( (used_for_reference == 0x0 ) && active_fs->is_output && active_fs->is_non_existent == 0x0) 2978 //{ 2979 //PRINTF(MFD_NONE, " requesting to send FREE: fs_idc = %d fb_id = %d \n", active_fs->fs_idc, active_fs->fb_id); 2980 //dpb_release_fb(&h264_dpb, active_fs->fb_id, 1); 2981 //} 2982 2983 if (viddec_h264_get_is_output(active_fs) && (used_for_reference == 0)) 2984 { 2985 h264_dpb_remove_frame_from_dpb(p_dpb, idx); 2986 *flag = 1; 2987 } 2988 /* 2989 /////// Removed following OLO source (Sodaville H.D) 2990 else if ( (first_non_exist_valid == 0x0) && active_fs->is_non_existent ) 2991 { 2992 first_non_exist_valid = 0x01; 2993 non_exist_idx = idx; 2994 } 2995 */ 2996 } 2997 /* 2998 /////// Removed following OLO source (Sodaville H.D) 2999 if ( *flag == 0x0 && first_non_exist_valid) { 3000 h264_dpb_remove_frame_from_dpb(p_dpb,non_exist_idx); 3001 *flag = 1; 3002 } 3003 */ 3004 return; 3005 } //// End of h264_dpb_remove_unused_frame_from_dpb 3006 3007 3008 /* ------------------------------------------------------------------------------------------ */ 3009 /* ------------------------------------------------------------------------------------------ */ 3010 /* ------------------------------------------------------------------------------------------ */ 3011 ////////////////////////////////////////////////////////////////////////////// 3012 // h264_dpb_get_smallest_poc () 3013 // 3014 // find smallest POC in the DPB which has not as yet been output 3015 // This function only checks for frames and dangling fields... 3016 // unless the dpb used size is one, in which case it will accept an unpaired field 3017 ////////////////////////////////////////////////////////////////////////////// 3018 void h264_dpb_get_smallest_poc(h264_DecodedPictureBuffer *p_dpb, int32_t *poc, int32_t *pos) 3019 { 3020 int32_t poc_int; 3021 uint32_t idx; 3022 int32_t first_non_output = 1; 3023 3024 *pos = MPD_DPB_FS_NULL_IDC; 3025 3026 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[0]); 3027 poc_int = active_fs->frame.poc; 3028 3029 for (idx = 0; idx < p_dpb->used_size; idx++) 3030 { 3031 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 3032 3033 if (viddec_h264_get_is_output(active_fs) == 0) 3034 { 3035 //PRINTF(MFD_NONE, " active_fs->fs_idc = %d active_fs->is_used = %d, active_fs->is_dangling = %d , active_fs->poc = %d \n", active_fs->fs_idc, active_fs->is_used, active_fs->is_dangling, active_fs->poc); 3036 if ((viddec_h264_get_is_used(active_fs) == 3) || (viddec_h264_get_is_dangling(active_fs))) 3037 { 3038 if (first_non_output) 3039 { 3040 *pos = idx; 3041 first_non_output = 0; 3042 poc_int = active_fs->frame.poc; 3043 } 3044 else if (poc_int > active_fs->frame.poc) 3045 { 3046 poc_int = active_fs->frame.poc; 3047 *pos = idx; 3048 } 3049 } 3050 else if (p_dpb->used_size == 1) 3051 { 3052 poc_int = active_fs->frame.poc; 3053 *pos = idx; 3054 } 3055 } 3056 } 3057 3058 *poc = poc_int; 3059 3060 return; 3061 } 3062 3063 /* ------------------------------------------------------------------------------------------ */ 3064 /* ------------------------------------------------------------------------------------------ */ 3065 /* ------------------------------------------------------------------------------------------ */ 3066 ////////////////////////////////////////////////////////////////////////////// 3067 // h264_dpb_split_field () 3068 // 3069 // Extract field information from a frame 3070 ////////////////////////////////////////////////////////////////////////////// 3071 3072 void h264_dpb_split_field (h264_Info * pInfo) 3073 { 3074 3075 //active_fs->frame.poc = active_fs->frame.poc; 3076 // active_fs->top_field.poc = active_fs->frame.poc; 3077 // This line changed on 11/05/05 KMc 3078 active_fs->top_field.poc = pInfo->img.toppoc; 3079 active_fs->bottom_field.poc = pInfo->img.bottompoc; 3080 3081 active_fs->top_field.used_for_reference = active_fs->frame.used_for_reference & 1; 3082 active_fs->bottom_field.used_for_reference = active_fs->frame.used_for_reference >> 1; 3083 3084 active_fs->top_field.is_long_term = active_fs->frame.is_long_term; 3085 active_fs->bottom_field.is_long_term = active_fs->frame.is_long_term; 3086 3087 active_fs->long_term_frame_idx = active_fs->frame.long_term_frame_idx; 3088 active_fs->top_field.long_term_frame_idx = active_fs->frame.long_term_frame_idx; 3089 active_fs->bottom_field.long_term_frame_idx = active_fs->frame.long_term_frame_idx; 3090 3091 3092 // Assign field mvs attached to MB-Frame buffer to the proper buffer 3093 //! Generate field MVs from Frame MVs 3094 // ... 3095 // these will be done in RTL through using proper memory mapping 3096 return; 3097 } 3098 3099 3100 /* ------------------------------------------------------------------------------------------ */ 3101 /* ------------------------------------------------------------------------------------------ */ 3102 /* ------------------------------------------------------------------------------------------ */ 3103 ////////////////////////////////////////////////////////////////////////////// 3104 // h264_dpb_combine_field (int32_t use_old) 3105 // 3106 // Generate a frame from top and bottom fields 3107 ////////////////////////////////////////////////////////////////////////////// 3108 3109 void h264_dpb_combine_field(int32_t use_old) 3110 { 3111 3112 //remove warning 3113 use_old = use_old; 3114 3115 active_fs->frame.poc = (active_fs->top_field.poc < active_fs->bottom_field.poc)? 3116 active_fs->top_field.poc: active_fs->bottom_field.poc; 3117 3118 //active_fs->frame.poc = active_fs->poc; 3119 3120 3121 active_fs->frame.used_for_reference = active_fs->top_field.used_for_reference |(active_fs->bottom_field.used_for_reference); 3122 3123 active_fs->frame.is_long_term = active_fs->top_field.is_long_term |(active_fs->bottom_field.is_long_term <<1); 3124 3125 if (active_fs->frame.is_long_term) 3126 active_fs->frame.long_term_frame_idx = active_fs->long_term_frame_idx; 3127 3128 return; 3129 3130 } 3131 3132 /* ------------------------------------------------------------------------------------------ */ 3133 /* ------------------------------------------------------------------------------------------ */ 3134 /* ------------------------------------------------------------------------------------------ */ 3135 3136 ////////////////////////////////////////////////////////////////////////////// 3137 // h264_dpb_sliding_window_memory_management () 3138 // 3139 // Perform Sliding window decoded reference picture marking process 3140 // It must be the reference frame, complementary reference field pair 3141 // or non-paired reference field that has the smallest value of 3142 // FrameNumWrap which is marked as unused for reference. Note : We CANNOT 3143 // simply use frame_num!!!! 3144 // 3145 // Although we hold frame_num_wrap in SW, currently, this is not 3146 // being updated for every picture (the b-picture parameter non-update 3147 // phenomenon of the reference software) 3148 ////////////////////////////////////////////////////////////////////////////// 3149 3150 void h264_dpb_sliding_window_memory_management(h264_DecodedPictureBuffer *p_dpb, int32_t NonExisting, int32_t num_ref_frames) 3151 { 3152 // if this is a reference pic with sliding window, unmark first ref frame 3153 // should this be (p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer) 3154 // Rem: adaptive marking can be on a slice by slice basis so we 3155 // could have pictures merked as long term reference in adaptive marking and then 3156 // the marking mode changed back to sliding_window_memory_management 3157 if (p_dpb->ref_frames_in_buffer >= (num_ref_frames - p_dpb->ltref_frames_in_buffer)) 3158 { 3159 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]); 3160 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]); 3161 3162 if(NonExisting == 0) 3163 { 3164 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc); 3165 viddec_h264_set_is_frame_long_term(active_fs, 0); 3166 } 3167 } 3168 } 3169 3170 /* ------------------------------------------------------------------------------------------ */ 3171 /* ------------------------------------------------------------------------------------------ */ 3172 /* ------------------------------------------------------------------------------------------ */ 3173 ////////////////////////////////////////////////////////////////////////////// 3174 // h264_dpb_store_picture_in_dpb () 3175 // 3176 // First we run the marking procedure. 3177 // Then, before we add the current frame_store to the list of refernce stores we run some checks 3178 // These include checking the number of existing reference frames 3179 // in DPB and if necessary, flushing frames. 3180 // 3181 // \param NonExisting 3182 // If non-zero this is called to store a non-existing frame resulting from gaps_in_frame_num 3183 ////////////////////////////////////////////////////////////////////////////// 3184 3185 ////////////////////////////////////////////////////////////////////////////// 3186 // h264_dpb_frame_output () 3187 // 3188 // If direct == 1, Directly output a frame without storing it in the p_dpb-> 3189 // Therefore we must set is_used to 0, which I guess means it will not appear 3190 // in the fs_dpb_idc list and is_output to 1 which means it should be in the 3191 // fs_output_idc list. 3192 // 3193 // If it is a non-existing pcture we do not actually place it in the output queue 3194 ////////////////////////////////////////////////////////////////////////////// 3195 3196 void h264_dpb_frame_output(h264_Info * pInfo,int32_t fs_idc, int32_t direct, int32_t * existing) 3197 { 3198 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 3199 3200 h264_dpb_set_active_fs(p_dpb, fs_idc); 3201 3202 //h264_dpb_push_output_queue(); 3203 if(pInfo->sei_information.disp_frozen) 3204 { 3205 // check pocs 3206 if(active_fs->top_field.poc >= pInfo->sei_information.freeze_POC) 3207 { 3208 if(active_fs->top_field.poc < pInfo->sei_information.release_POC) 3209 { 3210 viddec_h264_set_is_top_skipped(active_fs, 1); 3211 } 3212 else 3213 { 3214 pInfo->sei_information.disp_frozen = 0; 3215 } 3216 } 3217 3218 if(active_fs->bottom_field.poc >= pInfo->sei_information.freeze_POC) 3219 { 3220 if(active_fs->bottom_field.poc < pInfo->sei_information.release_POC) 3221 { 3222 viddec_h264_set_is_bottom_skipped(active_fs, 1); 3223 } 3224 else 3225 { 3226 pInfo->sei_information.disp_frozen = 0; 3227 } 3228 } 3229 } 3230 3231 if ( viddec_h264_get_broken_link_picture(active_fs) ) 3232 pInfo->sei_information.broken_link = 1; 3233 3234 if( pInfo->sei_information.broken_link) 3235 { 3236 // Check if this was the recovery point picture - going to have recovery point on 3237 // a frame basis 3238 if(viddec_h264_get_recovery_pt_picture(active_fs)) 3239 { 3240 pInfo->sei_information.broken_link = 0; 3241 // Also reset wait on sei recovery point picture 3242 p_dpb->WaitSeiRecovery = 0; 3243 } 3244 else 3245 { 3246 viddec_h264_set_is_frame_skipped(active_fs, 3); 3247 } 3248 } 3249 else 3250 { 3251 // even if this is not a broken - link, we need to follow SEI recovery point rules 3252 // Did we use SEI recovery point for th elast restart? 3253 if ( p_dpb->WaitSeiRecovery ) 3254 { 3255 if ( viddec_h264_get_recovery_pt_picture(active_fs) ) { 3256 p_dpb->WaitSeiRecovery = 0; 3257 } else { 3258 viddec_h264_set_is_frame_skipped(active_fs, 3); 3259 } 3260 } 3261 } 3262 3263 if ( p_dpb->SuspendOutput ) 3264 { 3265 if ( viddec_h264_get_open_gop_entry(active_fs) ) { 3266 p_dpb->SuspendOutput = 0; 3267 } else{ 3268 viddec_h264_set_is_frame_skipped(active_fs, 3); 3269 } 3270 } 3271 3272 //h264_send_new_display_frame(0x0); 3273 viddec_h264_set_is_output(active_fs, 1); 3274 3275 if(viddec_h264_get_is_non_existent(active_fs) == 0) 3276 { 3277 *existing = 1; 3278 p_dpb->frame_id_need_to_be_displayed[p_dpb->frame_numbers_need_to_be_displayed]=active_fs->fs_idc; 3279 p_dpb->frame_numbers_need_to_be_displayed++; 3280 3281 //if(direct) 3282 //h264_dpb_remove_frame_from_dpb(p_dpb, active_fs->fs_idc); // Remove dpb.fs_dpb_idc[pos] 3283 } 3284 else 3285 { 3286 *existing = 0; 3287 } 3288 3289 if(direct) { 3290 viddec_h264_set_is_frame_used(active_fs, 0); 3291 active_fs->frame.used_for_reference = 0; 3292 active_fs->top_field.used_for_reference = 0; 3293 active_fs->bottom_field.used_for_reference = 0; 3294 active_fs->fs_idc = MPD_DPB_FS_NULL_IDC; 3295 } 3296 return; 3297 } ///////// End of dpb frame output 3298 3299 3300 /* ------------------------------------------------------------------------------------------ */ 3301 /* ------------------------------------------------------------------------------------------ */ 3302 /* ------------------------------------------------------------------------------------------ */ 3303 ////////////////////////////////////////////////////////////////////////////// 3304 // h264_dpb_output_one_frame_from_dpb () 3305 // 3306 // Output one frame stored in the DPB. Basiclly this results in its placment 3307 // in the fs_output_idc list. 3308 // Placement in the output queue should cause an automatic removal from the dpb 3309 // if the frame store is not being used as a reference 3310 // This may need another param for a frame request so that it definitely outputs one non-exiosting frame 3311 ////////////////////////////////////////////////////////////////////////////// 3312 int32_t h264_dpb_output_one_frame_from_dpb(h264_Info* pInfo,int32_t direct, int32_t request, int32_t num_ref_frames) 3313 { 3314 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 3315 int32_t poc; 3316 int32_t pos; 3317 int32_t used_for_reference; 3318 3319 int32_t existing = 0; 3320 int32_t is_refused = 0; 3321 int32_t is_pushed = 0; 3322 3323 //remove warning 3324 request = request; 3325 3326 if(direct) 3327 { 3328 h264_dpb_frame_output(pInfo, p_dpb->fs_dec_idc, 1, &existing); 3329 } 3330 else 3331 { 3332 if(p_dpb->used_size != 0) 3333 { 3334 // Should this be dpb.not_as_yet_output_num > 0 ?? 3335 // There should maybe be a is_refused == 0 condition instead... 3336 while ((p_dpb->used_size > 0) && (existing == 0) && (is_refused == 0)) 3337 { 3338 // find smallest non-output POC 3339 h264_dpb_get_smallest_poc(p_dpb, &poc, &pos); 3340 if (pos != MPD_DPB_FS_NULL_IDC) 3341 { 3342 // put it into the output queue 3343 h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[pos], 0, &existing); 3344 3345 p_dpb->last_output_poc = poc; 3346 if (existing) is_pushed = 1; 3347 // If non-reference, free frame store and move empty store to end of buffer 3348 3349 h264_dpb_is_used_for_reference(&used_for_reference); 3350 if (!(used_for_reference)) 3351 h264_dpb_remove_frame_from_dpb(p_dpb, pos); // Remove dpb.fs_dpb_idc[pos] 3352 } 3353 else 3354 { 3355 int32_t flag; 3356 uint32_t idx; 3357 3358 // This is basically an error condition caused by too many reference frames in the DPB. 3359 // It should only happen in errored streams, and can happen if this picture had an MMCO, 3360 // thus disabling h264_dpb_sliding_window_memory_management(), which would normally have 3361 // unmarked the oldest reference frame. 3362 h264_dpb_sliding_window_memory_management(p_dpb, 0,num_ref_frames); 3363 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 3364 3365 if (flag == 0) { 3366 for (idx = 0; idx < p_dpb->used_size; idx++) 3367 { 3368 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 3369 h264_dpb_is_used_for_reference(&used_for_reference); 3370 3371 if (used_for_reference) { 3372 break; 3373 } 3374 } 3375 3376 if (idx < p_dpb->used_size) { 3377 // Short term 3378 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_dpb_idc[idx]); 3379 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_dpb_idc[idx]); 3380 3381 // Long term 3382 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_dpb_idc[idx]); 3383 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_dpb_idc[idx]); 3384 3385 // Remove from DPB 3386 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 3387 } 3388 } 3389 return 1; 3390 } 3391 } 3392 } 3393 } 3394 3395 return is_pushed; 3396 } 3397 3398 3399 /* ------------------------------------------------------------------------------------------ */ 3400 /* ------------------------------------------------------------------------------------------ */ 3401 /* ------------------------------------------------------------------------------------------ */ 3402 3403 ////////////////////////////////////////////////////////////////////////////// 3404 // h264_dpb_queue_update 3405 // 3406 // This should be called anytime the output queue might be changed 3407 ////////////////////////////////////////////////////////////////////////////// 3408 3409 int32_t h264_dpb_queue_update(h264_Info* pInfo,int32_t push, int32_t direct, int32_t frame_request, int32_t num_ref_frames) 3410 { 3411 3412 int32_t frame_output = 0; 3413 3414 if(push) 3415 { 3416 frame_output = h264_dpb_output_one_frame_from_dpb(pInfo, direct, 0, num_ref_frames); 3417 } 3418 else if(frame_request) 3419 { 3420 frame_output = h264_dpb_output_one_frame_from_dpb(pInfo, 0, 1,num_ref_frames); 3421 } 3422 3423 3424 return frame_output; 3425 3426 } 3427 3428 /* ------------------------------------------------------------------------------------------ */ 3429 /* ------------------------------------------------------------------------------------------ */ 3430 /* ------------------------------------------------------------------------------------------ */ 3431 3432 ////////////////////////////////////////////////////////////////////////////// 3433 // h264_dpb_flush_dpb () 3434 // 3435 // Unmarks all reference pictures in the short-term and long term lists and 3436 // in doing so resets the lists. 3437 // 3438 // Flushing the dpb, adds all the current frames in the dpb, not already on the output list 3439 // to the output list and removes them from the dpb (they will all be marked as unused for 3440 // reference first) 3441 ////////////////////////////////////////////////////////////////////////////// 3442 3443 void h264_dpb_flush_dpb (h264_Info* pInfo,int32_t output_all, int32_t keep_complement, int32_t num_ref_frames) 3444 { 3445 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 3446 3447 int32_t idx, flag; 3448 int32_t ref_frames_in_buffer; 3449 3450 ref_frames_in_buffer = p_dpb->ref_frames_in_buffer; 3451 3452 for (idx = 0; idx < ref_frames_in_buffer; idx++){ 3453 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]); 3454 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]); 3455 } 3456 3457 ref_frames_in_buffer = p_dpb->ltref_frames_in_buffer; 3458 3459 for (idx = 0; idx < ref_frames_in_buffer; idx++) 3460 { 3461 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[0]); 3462 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[0]); 3463 } 3464 3465 // output frames in POC order 3466 if (output_all) { 3467 while (p_dpb->used_size - keep_complement) { 3468 h264_dpb_queue_update(pInfo, 1, 0, 0,num_ref_frames); 3469 } 3470 } 3471 3472 flag = 1; 3473 while (flag) { 3474 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag); 3475 } 3476 3477 return; 3478 } 3479 3480 /* ------------------------------------------------------------------------------------------ */ 3481 /* ------------------------------------------------------------------------------------------ */ 3482 /* ------------------------------------------------------------------------------------------ */ 3483 ////////////////////////////////////////////////////////////////////////////// 3484 // h264_dpb_reset_dpb () 3485 // 3486 // Used to reset the contents of dpb 3487 // Must calculate memory (aligned) pointers for each of the possible frame stores 3488 // 3489 // Also want to calculate possible max dpb size in terms of frames 3490 // We should have an active SPS when we call this ftn to calc bumping level 3491 ////////////////////////////////////////////////////////////////////////////// 3492 void h264_dpb_reset_dpb(h264_Info * pInfo,int32_t PicWidthInMbs, int32_t FrameHeightInMbs, int32_t SizeChange, int32_t no_output_of_prior_pics_flag) 3493 { 3494 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 3495 3496 int32_t num_ref_frames = pInfo->active_SPS.num_ref_frames; 3497 3498 3499 // If half way through a frame then Frame in progress will still be high, 3500 // so mark the previous field as a dangling field. This is also needed to 3501 // keep cs7050_sif_dpb_disp_numb_ptr correct. Better to reset instead? 3502 if(p_dpb->used_size) 3503 { 3504 int32_t idx; 3505 idx = p_dpb->used_size-1; 3506 if (p_dpb->fs_dpb_idc[idx] != MPD_DPB_FS_NULL_IDC) 3507 { 3508 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]); 3509 3510 if(viddec_h264_get_is_used(active_fs) != 3) 3511 h264_dpb_mark_dangling_field(p_dpb, active_fs->fs_idc); //, DANGLING_TYPE_DPB_RESET 3512 } 3513 } 3514 3515 // initialize software DPB 3516 if(active_fs) { 3517 viddec_h264_set_dec_structure(active_fs, INVALID); 3518 } 3519 h264_dpb_idr_memory_management(pInfo, &pInfo->active_SPS, no_output_of_prior_pics_flag); // implied no_output_of_prior_pics_flag==1 3520 3521 3522 // May always be a size change which calls this function now... 3523 // could eliminate below branch 3524 if(SizeChange) 3525 { 3526 3527 /*** 3528 Note : 21/03/2005 14:16 3529 Danger asociated with resetting curr_alloc_mem as it would allow the FW top reallocate 3530 frame stores from 0 -> NUM_FRAME_STORES again - could lead to queue overflow and corruption 3531 3532 Placed in size change condition in the hope that this will only ensure dpb is empty 3533 and thus this behaviour is valid before continuing again 3534 ***/ 3535 3536 3537 p_dpb->PicWidthInMbs = PicWidthInMbs; 3538 p_dpb->FrameHeightInMbs = FrameHeightInMbs; 3539 3540 p_dpb->fs_dec_idc = MPD_DPB_FS_NULL_IDC; 3541 //Flush the current DPB. 3542 h264_dpb_flush_dpb(pInfo, 1,0,num_ref_frames); 3543 } 3544 3545 return; 3546 } ///// End of reset DPB 3547 3548 /* ------------------------------------------------------------------------------------------ */ 3549 /* ------------------------------------------------------------------------------------------ */ 3550 /* ------------------------------------------------------------------------------------------ */ 3551 // --------------------------------------------------------------------------- 3552 // Note that if an 'missing_pip_fb' condition exists, the message will 3553 // sent to the host each time setup_free_fb is called. However, since this 3554 // condition is not expected to happen if pre-defined steps are followed, we let 3555 // it be for now and will change it if required. Basically, as long as host 3556 // enables PiP after adding PiP buffers and disables PiP before removing buffers 3557 // and matches PiP fb_id's with normal decode fb_id's this condition should 3558 // not occur. 3559 // --------------------------------------------------------------------------- 3560 int32_t dpb_setup_free_fb( h264_DecodedPictureBuffer *p_dpb, uint8_t* fb_id, pip_setting_t* pip_setting ) 3561 { 3562 uint8_t idx; 3563 3564 //remove warning 3565 pip_setting = pip_setting; 3566 3567 3568 for (idx = 0; idx < NUM_DPB_FRAME_STORES; idx++) 3569 { 3570 if (p_dpb->fs[idx].fs_idc == MPD_DPB_FS_NULL_IDC) 3571 { 3572 *fb_id = idx; 3573 break; 3574 } 3575 } 3576 3577 if(idx == NUM_DPB_FRAME_STORES) 3578 return 1; 3579 3580 p_dpb->fs[idx].fs_idc = idx; 3581 3582 return 0; 3583 3584 } 3585 3586 /* ------------------------------------------------------------------------------------------ */ 3587 /* ------------------------------------------------------------------------------------------ */ 3588 /* ------------------------------------------------------------------------------------------ */ 3589 ////////////////////////////////////////////////////////////////////////////// 3590 // h264_dpb_assign_frame_store () 3591 // 3592 // may need a non-existing option parameter 3593 // 3594 3595 int32_t h264_dpb_assign_frame_store(h264_Info * pInfo, int32_t NonExisting) 3596 { 3597 uint8_t idc = MPD_DPB_FS_NULL_IDC; 3598 pip_setting_t pip_setting; 3599 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb; 3600 3601 3602 while( dpb_setup_free_fb(p_dpb, &idc, &pip_setting) != 0 ) { 3603 /// 3604 /// Generally this is triggered a error case, no more frame buffer avaliable for next 3605 /// What we do here is just remove one with min-POC before get more info 3606 /// 3607 3608 int32_t pos = 0, poc = 0, existing = 1; 3609 3610 // find smallest non-output POC 3611 h264_dpb_get_smallest_poc(p_dpb, &poc, &pos); 3612 if (pos != MPD_DPB_FS_NULL_IDC) 3613 { 3614 // put it into the output queue 3615 h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[pos], 0, &existing); 3616 p_dpb->last_output_poc = poc; 3617 h264_dpb_remove_frame_from_dpb(p_dpb, pos); // Remove dpb.fs_dpb_idc[pos] 3618 } 3619 } 3620 3621 3622 if(NonExisting) { 3623 p_dpb->fs_non_exist_idc = idc; 3624 }else { 3625 p_dpb->fs_dec_idc = idc; 3626 } 3627 3628 //add to support frame relocation interface to host 3629 if(!NonExisting) 3630 { 3631 p_dpb->frame_numbers_need_to_be_allocated = 1; 3632 p_dpb->frame_id_need_to_be_allocated = p_dpb->fs_dec_idc; 3633 } 3634 3635 3636 ///////////////////////////////h264_dpb_reset_fs(); 3637 h264_dpb_set_active_fs(p_dpb, idc); 3638 active_fs->fs_flag_1 = 0; 3639 active_fs->fs_flag_2 = 0; 3640 viddec_h264_set_is_non_existent(active_fs, NonExisting); 3641 viddec_h264_set_is_output(active_fs, (NonExisting?1:0)); 3642 3643 active_fs->pic_type = ((FRAME_TYPE_INVALID<<FRAME_TYPE_TOP_OFFSET)|(FRAME_TYPE_INVALID<<FRAME_TYPE_BOTTOM_OFFSET)); //---- 3644 3645 // Only put members in here which will not be reset somewhere else 3646 // and which could be used before they are overwritten again with 3647 // new valid values 3648 // eg ->is_used is reset on removal from dpb, no need for it here 3649 // ->poc would only be changed when we overwrite on insert_Picture_in_dpb() 3650 // but would be used by get_smallest_poc() 3651 // ->top.poc would also not be overwritten until a new valid value comes along, 3652 // but I don't think it is used before then so no need to reset 3653 //active_fs->is_long_term = 0; 3654 active_fs->frame.used_for_reference = 0; 3655 active_fs->frame.poc = 0; 3656 3657 return 1; 3658 } 3659 3660 3661 /* ------------------------------------------------------------------------------------------ */ 3662 /* ------------------------------------------------------------------------------------------ */ 3663 /* ------------------------------------------------------------------------------------------ */ 3664 ////////////////////////////////////////////////////////////////////////////// 3665 // h264_dpb_update_queue_dangling_field (h264_Info * pInfo) 3666 // 3667 // Update DPB for Dangling field special case 3668 // 3669 void h264_dpb_update_queue_dangling_field(h264_Info * pInfo) 3670 { 3671 h264_DecodedPictureBuffer *dpb_ptr = &pInfo->dpb; 3672 int32_t prev_pic_unpaired_field = 0; 3673 3674 if(dpb_ptr->used_size > dpb_ptr->BumpLevel) 3675 { 3676 if (dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1] != MPD_DPB_FS_NULL_IDC) 3677 { 3678 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1]); 3679 if(viddec_h264_get_is_used(active_fs) != 3) 3680 { 3681 prev_pic_unpaired_field = 1; 3682 } 3683 } 3684 3685 if (pInfo->img.structure != FRAME) 3686 { 3687 // To prove this is the second field, 3688 // 1) The previous picture is an (as yet) unpaired field 3689 if(prev_pic_unpaired_field) 3690 { 3691 // If we establish the previous pic was an unpaired field and this picture is not 3692 // its complement, the previous picture was a dangling field 3693 if(pInfo->img.second_field == 0) { 3694 while(dpb_ptr->used_size > dpb_ptr->BumpLevel) 3695 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame 3696 } 3697 } 3698 } 3699 else if (prev_pic_unpaired_field) { 3700 while(dpb_ptr->used_size > dpb_ptr->BumpLevel) 3701 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame 3702 } 3703 } 3704 3705 3706 return; 3707 } ///// End of init Frame Store 3708 3709 3710 /* ------------------------------------------------------------------------------------------ */ 3711 /* ------------------------------------------------------------------------------------------ */ 3712 /* ------------------------------------------------------------------------------------------ */ 3713 ////////////////////////////////////////////////////////////////////////////// 3714 // h264_dpb_init_frame_store (h264_Info * pInfo) 3715 // 3716 // Set the frame store to be used in decoding the picture 3717 // 3718 3719 void h264_dpb_init_frame_store(h264_Info * pInfo) 3720 { 3721 h264_DecodedPictureBuffer *dpb_ptr = &pInfo->dpb; 3722 3723 int32_t free_fs_found; 3724 int32_t idx = 0; 3725 int32_t prev_pic_unpaired_field = 0; 3726 int32_t prev_idc = MPD_DPB_FS_NULL_IDC; 3727 int32_t structure = pInfo->img.structure; 3728 3729 if(dpb_ptr->used_size) 3730 { 3731 idx = dpb_ptr->used_size-1; 3732 prev_idc = dpb_ptr->fs_dpb_idc[idx]; 3733 } 3734 3735 if (prev_idc != MPD_DPB_FS_NULL_IDC) 3736 { 3737 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1]); 3738 if(viddec_h264_get_is_used(active_fs) != 3) 3739 { 3740 //PRINTF(MFD_NONE, " FN: %d active_fs->is_used = %d \n", (h264_frame_number+1), active_fs->is_used); 3741 prev_pic_unpaired_field = 1; 3742 } 3743 } 3744 3745 //if ((pInfo->img.curr_has_mmco_5) || (pInfo->img.idr_flag)) curr_fld_not_prev_comp = 1; 3746 3747 if (structure != FRAME) 3748 { 3749 3750 // To prove this is the second field, 3751 // 1) The previous picture is an (as yet) unpaired field 3752 if(prev_pic_unpaired_field) 3753 { 3754 // If we establish the previous pic was an unpaired field and this picture is not 3755 // its complement, the previous picture was a dangling field 3756 if(pInfo->img.second_field == 0) 3757 h264_dpb_mark_dangling_field(dpb_ptr, active_fs->fs_idc); //, DANGLING_TYPE_FIELD 3758 } 3759 } 3760 else if (prev_pic_unpaired_field) { 3761 h264_dpb_mark_dangling_field(dpb_ptr, active_fs->fs_idc); //, DANGLING_TYPE_FRAME 3762 } 3763 3764 free_fs_found = 0; 3765 3766 // If this is not a second field, we must find a free space for the current picture 3767 if (!(pInfo->img.second_field)) 3768 { 3769 dpb_ptr->fs_dec_idc = MPD_DPB_FS_NULL_IDC; 3770 free_fs_found = h264_dpb_assign_frame_store(pInfo, 0); 3771 //h264_frame_number++; 3772 //PRINTF(MFD_NONE, " FN: %d (inc) fs_idc = %d \n", (h264_frame_number+1), dpb.fs_dec_idc); 3773 } 3774 3775 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dec_idc); 3776 3777 ////////////// TODO: THe following init 3778 #if 1 3779 if( pInfo->img.second_field) { 3780 //active_fs->second_dsn = pInfo->img.dsn; 3781 //active_fs->prev_dsn = pInfo->img.prev_dsn; 3782 if (active_fs->pic_type == FRAME_TYPE_IDR || 3783 active_fs->pic_type == FRAME_TYPE_I) { 3784 3785 viddec_h264_set_first_field_intra(active_fs, 1); 3786 } else { 3787 viddec_h264_set_first_field_intra(active_fs, 0); 3788 } 3789 3790 } 3791 else { 3792 //active_fs->first_dsn = pInfo->img.dsn; 3793 //active_fs->prev_dsn = pInfo->img.prev_dsn; 3794 viddec_h264_set_first_field_intra(active_fs, 0); 3795 } 3796 3797 if (pInfo->img.structure == FRAME) { 3798 //active_fs->second_dsn = 0x0; 3799 } 3800 3801 if ( pInfo->sei_information.broken_link_pic ) 3802 { 3803 viddec_h264_set_broken_link_picture(active_fs, 1); 3804 pInfo->sei_information.broken_link_pic = 0; 3805 } 3806 3807 if ((pInfo->img.frame_num == pInfo->sei_information.recovery_frame_num)&&(pInfo->SliceHeader.nal_ref_idc != 0)) 3808 viddec_h264_set_recovery_pt_picture(active_fs, 1); 3809 3810 //if ((( gRestartMode.aud ) || ( gRestartMode.sei )) && ( !gRestartMode.idr)) 3811 if(pInfo->img.recovery_point_found == 6) 3812 { 3813 viddec_h264_set_open_gop_entry(active_fs, 1); 3814 pInfo->dpb.SuspendOutput = 1; 3815 } 3816 #endif 3817 3818 if ((pInfo->img.second_field) || (free_fs_found)) 3819 { 3820 viddec_h264_set_dec_structure(active_fs, pInfo->img.structure); 3821 viddec_h264_set_is_output(active_fs, 0); 3822 3823 switch(pInfo->img.structure) 3824 { 3825 case (FRAME) :{ 3826 active_fs->frame.pic_num = pInfo->img.frame_num; 3827 active_fs->frame.long_term_frame_idx = 0; 3828 active_fs->frame.long_term_pic_num = 0; 3829 active_fs->frame.used_for_reference = 0; 3830 active_fs->frame.is_long_term = 0; 3831 //active_fs->frame.structure = pInfo->img.structure; 3832 active_fs->frame.poc = pInfo->img.framepoc; 3833 }break; 3834 case (TOP_FIELD) :{ 3835 active_fs->top_field.pic_num = pInfo->img.frame_num; 3836 active_fs->top_field.long_term_frame_idx = 0; 3837 active_fs->top_field.long_term_pic_num = 0; 3838 active_fs->top_field.used_for_reference = 0; 3839 active_fs->top_field.is_long_term = 0; 3840 //active_fs->top_field.structure = pInfo->img.structure; 3841 active_fs->top_field.poc = pInfo->img.toppoc; 3842 }break; 3843 case(BOTTOM_FIELD) :{ 3844 active_fs->bottom_field.pic_num = pInfo->img.frame_num; 3845 active_fs->bottom_field.long_term_frame_idx = 0; 3846 active_fs->bottom_field.long_term_pic_num = 0; 3847 active_fs->bottom_field.used_for_reference = 0; 3848 active_fs->bottom_field.is_long_term = 0; 3849 //active_fs->bottom_field.structure = pInfo->img.structure; 3850 active_fs->bottom_field.poc = pInfo->img.bottompoc; 3851 }break; 3852 } 3853 } 3854 else 3855 { 3856 // Need to drop a frame or something here 3857 } 3858 3859 return; 3860 } ///// End of init Frame Store 3861 3862 3863 /* ------------------------------------------------------------------------------------------ */ 3864 /* ------------------------------------------------------------------------------------------ */ 3865 /* ------------------------------------------------------------------------------------------ */ 3866 ////////////////////////////////////////////////////////////////////////////// 3867 // Decoding POC for current Picture 3868 // 1) pic_order_cnt_type (0, 1, 2) 3869 // 3870 ////////////////////////////////////////////////////////////////////////////// 3871 3872 void h264_hdr_decoding_poc (h264_Info * pInfo,int32_t NonExisting, int32_t frame_num) 3873 { 3874 int32_t MaxPicOrderCntLsb = (1<<(pInfo->active_SPS.log2_max_pic_order_cnt_lsb_minus4+4)); 3875 int32_t delta_pic_order_count[2]; 3876 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4); 3877 3878 int32_t AbsFrameNum =0; 3879 int32_t ExpectedDeltaPerPicOrderCntCycle =0; 3880 int32_t PicOrderCntCycleCnt = 0; 3881 int32_t FrameNumInPicOrderCntCycle =0; 3882 int32_t ExpectedPicOrderCnt =0; 3883 3884 int32_t actual_frame_num =0; 3885 3886 3887 3888 if(NonExisting) actual_frame_num = frame_num; 3889 else actual_frame_num = pInfo->img.frame_num; 3890 3891 switch (pInfo->active_SPS.pic_order_cnt_type) 3892 { 3893 case 0: 3894 if(NonExisting != 0) break; 3895 3896 if (pInfo->SliceHeader.idr_flag) 3897 { 3898 pInfo->img.PicOrderCntMsb = 0; 3899 pInfo->img.PrevPicOrderCntLsb = 0; 3900 } 3901 else if (pInfo->img.last_has_mmco_5) 3902 { 3903 if (pInfo->img.last_pic_bottom_field) 3904 { 3905 pInfo->img.PicOrderCntMsb = 0; 3906 pInfo->img.PrevPicOrderCntLsb = 0; 3907 } 3908 else 3909 { 3910 pInfo->img.PicOrderCntMsb = 0; 3911 pInfo->img.PrevPicOrderCntLsb = pInfo->img.toppoc; 3912 } 3913 } 3914 3915 // Calculate the MSBs of current picture 3916 if((pInfo->img.pic_order_cnt_lsb < pInfo->img.PrevPicOrderCntLsb) && 3917 ((pInfo->img.PrevPicOrderCntLsb - pInfo->img.pic_order_cnt_lsb )>=(MaxPicOrderCntLsb>>1)) ) 3918 { 3919 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb + MaxPicOrderCntLsb; 3920 } else if ((pInfo->img.pic_order_cnt_lsb > pInfo->img.PrevPicOrderCntLsb) && 3921 ((pInfo->img.pic_order_cnt_lsb - pInfo->img.PrevPicOrderCntLsb ) > (MaxPicOrderCntLsb>>1)) ) 3922 { 3923 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb - MaxPicOrderCntLsb; 3924 } else 3925 { 3926 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb; 3927 } 3928 3929 // 2nd 3930 3931 if(pInfo->img.field_pic_flag==0) 3932 { 3933 //frame pix 3934 pInfo->img.toppoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb; 3935 pInfo->img.bottompoc = pInfo->img.toppoc + pInfo->img.delta_pic_order_cnt_bottom; 3936 pInfo->img.ThisPOC = pInfo->img.framepoc = (pInfo->img.toppoc < pInfo->img.bottompoc)? pInfo->img.toppoc : pInfo->img.bottompoc; // POC200301 3937 } 3938 else if (pInfo->img.bottom_field_flag==0) 3939 { //top field 3940 pInfo->img.ThisPOC= pInfo->img.toppoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb; 3941 } 3942 else 3943 { //bottom field 3944 pInfo->img.ThisPOC= pInfo->img.bottompoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb; 3945 } 3946 pInfo->img.framepoc=pInfo->img.ThisPOC; 3947 3948 if ( pInfo->img.frame_num != pInfo->old_slice.frame_num) 3949 pInfo->img.PreviousFrameNum = pInfo->img.frame_num; 3950 3951 if(pInfo->SliceHeader.nal_ref_idc) 3952 { 3953 pInfo->img.PrevPicOrderCntLsb = pInfo->img.pic_order_cnt_lsb; 3954 pInfo->img.PicOrderCntMsb = pInfo->img.CurrPicOrderCntMsb; 3955 } 3956 3957 break; 3958 case 1: { 3959 if(NonExisting) 3960 { 3961 delta_pic_order_count[0] = 0; 3962 delta_pic_order_count[1] = 0; 3963 } 3964 else 3965 { 3966 delta_pic_order_count[0] = ( pInfo->img.delta_pic_order_always_zero_flag ) ? 0 : pInfo->img.delta_pic_order_cnt[0]; 3967 delta_pic_order_count[1] = ( pInfo->img.delta_pic_order_always_zero_flag ) ? 0 : 3968 ( (!pInfo->active_PPS.pic_order_present_flag) && (!(pInfo->img.field_pic_flag))) ? 0 : 3969 pInfo->img.delta_pic_order_cnt[1]; 3970 } 3971 3972 // this if branch should not be taken during processing of a gap_in_frame_num pic since 3973 // an IDR picture cannot produce non-existent frames... 3974 if(pInfo->SliceHeader.idr_flag) 3975 { 3976 pInfo->img.FrameNumOffset = 0; 3977 } 3978 else 3979 { 3980 3981 if (actual_frame_num < pInfo->img.PreviousFrameNum) 3982 { 3983 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset + MaxFrameNum; 3984 } 3985 else 3986 { 3987 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset; 3988 } 3989 } 3990 3991 // pInfo->img.num_ref_frames_in_pic_order_cnt_cycle set from SPS 3992 // so constant between existent and non-existent frames 3993 if (pInfo->img.num_ref_frames_in_pic_order_cnt_cycle) 3994 AbsFrameNum = pInfo->img.FrameNumOffset + actual_frame_num; 3995 else 3996 AbsFrameNum = 0; 3997 3998 // pInfo->img.disposable_flag should never be true for a non-existent frame since these are always 3999 // references... 4000 if ((pInfo->SliceHeader.nal_ref_idc == 0) && (AbsFrameNum > 0)) AbsFrameNum = AbsFrameNum - 1; 4001 4002 // 3rd 4003 ExpectedDeltaPerPicOrderCntCycle = pInfo->active_SPS.expectedDeltaPerPOCCycle; 4004 4005 if (AbsFrameNum) 4006 { 4007 // Rem: pInfo->img.num_ref_frames_in_pic_order_cnt_cycle takes max value of 255 (8 bit) 4008 // Frame NUm may be 2^16 (17 bits) 4009 // I guess we really have to treat AbsFrameNum as a 32 bit number 4010 uint32_t temp = 0; 4011 int32_t i=0; 4012 int32_t offset_for_ref_frame[MAX_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE]; 4013 4014 if (pInfo->img.num_ref_frames_in_pic_order_cnt_cycle) 4015 PicOrderCntCycleCnt = ldiv_mod_u((uint32_t)(AbsFrameNum-1), (uint32_t)pInfo->img.num_ref_frames_in_pic_order_cnt_cycle, &temp); 4016 4017 ExpectedPicOrderCnt = mult_u((uint32_t)PicOrderCntCycleCnt, (uint32_t)ExpectedDeltaPerPicOrderCntCycle); 4018 4019 FrameNumInPicOrderCntCycle = temp; 4020 4021 //ExpectedPicOrderCnt +=pInfo->active_SPS.expectedDeltaPerPOCCycle; 4022 #ifndef USER_MODE 4023 h264_Parse_Copy_Offset_Ref_Frames_From_DDR(pInfo, offset_for_ref_frame, pInfo->active_SPS.seq_parameter_set_id); 4024 for (i = 0; i <= FrameNumInPicOrderCntCycle; i++) 4025 ExpectedPicOrderCnt += offset_for_ref_frame[i]; 4026 #else 4027 for (i = 0; i <= FrameNumInPicOrderCntCycle; i++) 4028 ExpectedPicOrderCnt += pInfo->active_SPS.offset_for_ref_frame[i]; 4029 #endif 4030 } 4031 else { 4032 ExpectedPicOrderCnt = 0; 4033 } 4034 4035 if (pInfo->SliceHeader.nal_ref_idc == 0) 4036 ExpectedPicOrderCnt += pInfo->img.offset_for_non_ref_pic; 4037 4038 if (!(pInfo->img.field_pic_flag)) 4039 { 4040 pInfo->img.toppoc = ExpectedPicOrderCnt + delta_pic_order_count[0]; 4041 pInfo->img.bottompoc = pInfo->img.toppoc + pInfo->img.offset_for_top_to_bottom_field + delta_pic_order_count[1]; 4042 pInfo->img.framepoc = (pInfo->img.toppoc < pInfo->img.bottompoc)? pInfo->img.toppoc : pInfo->img.bottompoc; 4043 pInfo->img.ThisPOC = pInfo->img.framepoc; 4044 } 4045 else if (!(pInfo->img.bottom_field_flag)) 4046 { 4047 //top field 4048 pInfo->img.toppoc = ExpectedPicOrderCnt + delta_pic_order_count[0]; 4049 pInfo->img.ThisPOC = pInfo->img.toppoc; 4050 pInfo->img.bottompoc = 0; 4051 } 4052 else 4053 { 4054 //bottom field 4055 pInfo->img.toppoc = 0; 4056 pInfo->img.bottompoc = ExpectedPicOrderCnt + pInfo->img.offset_for_top_to_bottom_field + delta_pic_order_count[0]; 4057 pInfo->img.ThisPOC = pInfo->img.bottompoc; 4058 } 4059 4060 //CONFORMANCE_ISSUE 4061 pInfo->img.framepoc=pInfo->img.ThisPOC; 4062 4063 //CONFORMANCE_ISSUE 4064 pInfo->img.PreviousFrameNum=pInfo->img.frame_num; 4065 pInfo->img.PreviousFrameNumOffset=pInfo->img.FrameNumOffset; 4066 4067 } 4068 break; 4069 case 2: { // POC MODE 2 4070 if (pInfo->SliceHeader.idr_flag) 4071 { 4072 pInfo->img.FrameNumOffset = 0; 4073 pInfo->img.framepoc = 0; 4074 pInfo->img.toppoc = 0; 4075 pInfo->img.bottompoc = 0; 4076 pInfo->img.ThisPOC = 0; 4077 } 4078 else 4079 { 4080 if (pInfo->img.last_has_mmco_5) 4081 { 4082 pInfo->img.PreviousFrameNum = 0; 4083 pInfo->img.PreviousFrameNumOffset = 0; 4084 } 4085 if (actual_frame_num < pInfo->img.PreviousFrameNum) 4086 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset + MaxFrameNum; 4087 else 4088 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset; 4089 4090 AbsFrameNum = pInfo->img.FrameNumOffset + actual_frame_num; 4091 if (pInfo->SliceHeader.nal_ref_idc == 0) pInfo->img.ThisPOC = (AbsFrameNum<<1) - 1; 4092 else pInfo->img.ThisPOC = (AbsFrameNum<<1); 4093 4094 if (!(pInfo->img.field_pic_flag)) 4095 { 4096 pInfo->img.toppoc = pInfo->img.ThisPOC; 4097 pInfo->img.bottompoc = pInfo->img.ThisPOC; 4098 pInfo->img.framepoc = pInfo->img.ThisPOC; 4099 } 4100 else if (!(pInfo->img.bottom_field_flag)) 4101 { 4102 pInfo->img.toppoc = pInfo->img.ThisPOC; 4103 pInfo->img.framepoc = pInfo->img.ThisPOC; 4104 } 4105 else 4106 { 4107 pInfo->img.bottompoc = pInfo->img.ThisPOC; 4108 pInfo->img.framepoc = pInfo->img.ThisPOC; 4109 } 4110 } 4111 4112 //CONFORMANCE_ISSUE 4113 pInfo->img.PreviousFrameNum = pInfo->img.frame_num; 4114 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset; 4115 } 4116 break; 4117 default: 4118 break; 4119 } 4120 4121 return; 4122 } //// End of decoding_POC 4123 4124 /* ------------------------------------------------------------------------------------------ */ 4125 /* ------------------------------------------------------------------------------------------ */ 4126 /* ------------------------------------------------------------------------------------------ */ 4127 ////////////////////////////////////////////////////////////////////////////// 4128 // h264_hdr_post_poc () 4129 // 4130 ////////////////////////////////////////////////////////////////////////////// 4131 4132 void h264_hdr_post_poc(h264_Info* pInfo, int32_t NonExisting, int32_t frame_num, int32_t use_old) 4133 { 4134 int32_t actual_frame_num = (NonExisting)? frame_num : 4135 (use_old)? pInfo->old_slice.frame_num : 4136 pInfo->img.frame_num; 4137 4138 int32_t disposable_flag = (use_old)?(pInfo->old_slice.nal_ref_idc == 0) : 4139 (pInfo->SliceHeader.nal_ref_idc == 0); 4140 4141 switch(pInfo->img.pic_order_cnt_type) 4142 { 4143 case 0: { 4144 pInfo->img.PreviousFrameNum = actual_frame_num; 4145 if ((disposable_flag == 0) && (NonExisting == 0)) 4146 { 4147 pInfo->img.PrevPicOrderCntLsb = (use_old)? pInfo->old_slice.pic_order_cnt_lsb : 4148 pInfo->SliceHeader.pic_order_cnt_lsb; 4149 pInfo->img.PicOrderCntMsb = pInfo->img.CurrPicOrderCntMsb; 4150 } 4151 } 4152 break; 4153 case 1: { 4154 pInfo->img.PreviousFrameNum = actual_frame_num; 4155 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset; 4156 } 4157 break; 4158 case 2: { 4159 pInfo->img.PreviousFrameNum = actual_frame_num; 4160 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset; 4161 4162 }break; 4163 4164 default: { 4165 }break; 4166 } 4167 4168 return; 4169 } ///// End of h264_hdr_post_poc 4170 4171 4172