1 /****************************************************************************** 2 * 3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 /** 19 ******************************************************************************* 20 * @file 21 * ihevcd_utils.c 22 * 23 * @brief 24 * Contains miscellaneous utility functions such as init() etc 25 * 26 * @author 27 * Harish 28 * 29 * @par List of Functions: 30 * 31 * @remarks 32 * None 33 * 34 ******************************************************************************* 35 */ 36 /*****************************************************************************/ 37 /* File Includes */ 38 /*****************************************************************************/ 39 #include <stdio.h> 40 #include <stddef.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <assert.h> 44 45 #include "ihevc_typedefs.h" 46 #include "iv.h" 47 #include "ivd.h" 48 #include "ihevcd_cxa.h" 49 #include "ithread.h" 50 51 #include "ihevc_defs.h" 52 #include "ihevc_debug.h" 53 #include "ihevc_defs.h" 54 #include "ihevc_error.h" 55 #include "ihevc_structs.h" 56 #include "ihevc_buf_mgr.h" 57 #include "ihevc_dpb_mgr.h" 58 #include "ihevc_macros.h" 59 #include "ihevc_platform_macros.h" 60 61 #include "ihevc_common_tables.h" 62 #include "ihevc_buf_mgr.h" 63 #include "ihevc_disp_mgr.h" 64 #include "ihevc_cabac_tables.h" 65 66 #include "ihevcd_defs.h" 67 68 #include "ihevcd_function_selector.h" 69 #include "ihevcd_structs.h" 70 #include "ihevcd_error.h" 71 #include "ihevcd_nal.h" 72 #include "ihevcd_bitstream.h" 73 #include "ihevcd_utils.h" 74 #include "ihevcd_trace.h" 75 #include "ihevcd_process_slice.h" 76 #include "ihevcd_job_queue.h" 77 #define MAX_DPB_PIC_BUF 6 78 79 /* Function declarations */ 80 mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc); 81 82 /** 83 ******************************************************************************* 84 * 85 * @brief 86 * Used to get level index for a given level 87 * 88 * @par Description: 89 * Converts from level_idc (which is multiplied by 30) to an index that can be 90 * used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc 91 * 92 * @param[in] level 93 * Level of the stream 94 * 95 * @returns Level index for a given level 96 * 97 * @remarks 98 * 99 * 100 ******************************************************************************* 101 */ 102 WORD32 ihevcd_get_lvl_idx(WORD32 level) 103 { 104 WORD32 lvl_idx = 0; 105 106 if(level < IHEVC_LEVEL_20) 107 { 108 lvl_idx = 0; 109 } 110 else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21) 111 { 112 lvl_idx = 1; 113 } 114 else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30) 115 { 116 lvl_idx = 2; 117 } 118 else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31) 119 { 120 lvl_idx = 3; 121 } 122 else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40) 123 { 124 lvl_idx = 4; 125 } 126 else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41) 127 { 128 lvl_idx = 5; 129 } 130 else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50) 131 { 132 lvl_idx = 6; 133 } 134 else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51) 135 { 136 lvl_idx = 7; 137 } 138 else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52) 139 { 140 lvl_idx = 8; 141 } 142 else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60) 143 { 144 lvl_idx = 9; 145 } 146 else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61) 147 { 148 lvl_idx = 10; 149 } 150 else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62) 151 { 152 lvl_idx = 11; 153 } 154 else if(level >= IHEVC_LEVEL_62) 155 { 156 lvl_idx = 12; 157 } 158 159 return (lvl_idx); 160 } 161 162 /** 163 ******************************************************************************* 164 * 165 * @brief 166 * Used to get DPB size for a given level, and number of luma samples 167 * 168 * @par Description: 169 * For given width, height and level number of max_dpb_size is computed as per 170 * Annex A.4.1 171 * 172 * @param[in] level 173 * Level of the stream 174 * 175 * @param[in] pic_size 176 * Width * Height 177 * 178 * @returns Number of buffers in DPB 179 * 180 * @remarks 181 * 182 * 183 ******************************************************************************* 184 */ 185 WORD32 ihevcd_get_dpb_size(WORD32 level, WORD32 pic_size) 186 { 187 188 WORD32 max_luma_samples; 189 190 WORD32 max_dpb_size; 191 WORD32 lvl_idx = ihevcd_get_lvl_idx(level); 192 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx]; 193 194 195 196 if(pic_size <= (max_luma_samples >> 2)) 197 { 198 max_dpb_size = MIN(4 * MAX_DPB_PIC_BUF, 16); 199 } 200 else if(pic_size <= (max_luma_samples >> 1)) 201 { 202 max_dpb_size = MIN(2 * MAX_DPB_PIC_BUF, 16); 203 } 204 else if(pic_size <= ((3 * max_luma_samples) >> 2)) 205 { 206 max_dpb_size = MIN((4 * MAX_DPB_PIC_BUF) / 3, 16); 207 } 208 else 209 { 210 max_dpb_size = MAX_DPB_PIC_BUF; 211 } 212 213 return max_dpb_size; 214 } 215 /** 216 ******************************************************************************* 217 * 218 * @brief 219 * Used to get reference picture buffer size for a given level and 220 * and padding used 221 * 222 * @par Description: 223 * Used to get reference picture buffer size for a given level and padding used 224 * Each picture is padded on all four sides 225 * 226 * @param[in] pic_size 227 * Mumber of luma samples (Width * Height) 228 * 229 * @param[in] level 230 * Level 231 * 232 * @param[in] horz_pad 233 * Total padding used in horizontal direction 234 * 235 * @param[in] vert_pad 236 * Total padding used in vertical direction 237 * 238 * @returns Total picture buffer size 239 * 240 * @remarks 241 * 242 * 243 ******************************************************************************* 244 */ 245 WORD32 ihevcd_get_total_pic_buf_size(WORD32 pic_size, 246 WORD32 level, 247 WORD32 horz_pad, 248 WORD32 vert_pad, 249 WORD32 init_num_bufs, 250 WORD32 init_extra_bufs, 251 WORD32 chroma_only) 252 { 253 WORD32 size; 254 WORD32 num_luma_samples; 255 WORD32 lvl_idx; 256 WORD32 max_wd, min_ht; 257 WORD32 max_dpb_size; 258 WORD32 num_samples; 259 WORD32 max_num_bufs; 260 WORD32 pad = MAX(horz_pad, vert_pad); 261 262 263 /* Get maximum number of buffers for the current picture size */ 264 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 265 266 267 max_num_bufs = (2 * max_dpb_size + 1); 268 /* If num_ref_frames and num_reorder_frmaes is specified 269 * Use minimum value 270 */ 271 max_num_bufs = MIN(max_num_bufs, init_num_bufs); 272 273 /* 274 * Add extra buffers if required 275 */ 276 max_num_bufs += init_extra_bufs; 277 max_num_bufs = MIN(max_num_bufs, BUF_MGR_MAX_CNT); 278 279 /* Get level index */ 280 lvl_idx = ihevcd_get_lvl_idx(level); 281 282 283 /* Maximum width of luma samples in a picture at given level */ 284 max_wd = ALIGN64(gai4_ihevc_max_wd_ht[lvl_idx]); 285 286 /* Minimum height of luma samples in a picture at given level */ 287 min_ht = ALIGN64(gai4_ihevc_min_wd_ht[lvl_idx]); 288 289 /* Use max_wd and min_ht to get maximum number of luma samples for given level */ 290 /* Because max_wd and min_ht are aligned to 64, product will be higher than the 291 * value given by the spec for a given level 292 */ 293 num_luma_samples = max_wd * min_ht; 294 295 /* Allocation is required for 296 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1) 297 * 298 * Above expanded as 299 * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1) 300 * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1) 301 * Now max_dpb_size increases with smaller Wd and Ht, but Wd * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht * dpb_size 302 * 303 * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below 304 * 305 * For the padded area use MAX(horz_pad, vert_pad) as pad 306 * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding 307 * 308 * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min 309 * So use max_wd and min_ht 310 */ 311 312 /* Account for padding area */ 313 314 num_luma_samples += (pad * pad) + pad * (max_wd + min_ht); 315 316 /* Account for chroma */ 317 if(0 == chroma_only) 318 num_samples = num_luma_samples * 3 / 2; 319 else 320 num_samples = num_luma_samples / 2; 321 322 /* Number of bytes in reference pictures */ 323 size = num_samples * max_num_bufs; 324 325 326 return size; 327 } 328 /** 329 ******************************************************************************* 330 * 331 * @brief 332 * Used to get MV bank size for a given number of luma samples 333 * 334 * @par Description: 335 * For given number of luma samples one MV bank size is computed 336 * Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture 337 * 338 * @param[in] num_luma_samples 339 * Max number of luma pixels in the frame 340 * 341 * @returns Total MV Bank size 342 * 343 * @remarks 344 * 345 * 346 ******************************************************************************* 347 */ 348 WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples) 349 { 350 WORD32 size; 351 352 WORD32 pic_size; 353 354 WORD32 mv_bank_size; 355 WORD32 num_pu; 356 WORD32 num_ctb; 357 pic_size = num_luma_samples; 358 359 360 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 361 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 362 363 mv_bank_size = 0; 364 365 /* Size for storing pu_t start index each CTB */ 366 /* One extra entry is needed to compute number of PUs in the last CTB */ 367 mv_bank_size += (num_ctb + 1) * sizeof(WORD32); 368 369 /* Size for pu_map */ 370 mv_bank_size += num_pu; 371 372 /* Size for storing pu_t for each PU */ 373 mv_bank_size += num_pu * sizeof(pu_t); 374 375 size = mv_bank_size; 376 return size; 377 } 378 /** 379 ******************************************************************************* 380 * 381 * @brief 382 * Used to get TU data size for a given number luma samples 383 * 384 * @par Description: 385 * For a given number of luma samples TU data size is computed 386 * Each TU data includes tu_map and tu_t and coeff data for all 387 * the min TUs(4x4) in given CTB 388 * 389 * @param[in] num_luma_samples 390 * Number of 64 x 64 CTBs for which TU data has to be allocated. 391 * 392 * @returns Total TU data size 393 * 394 * @remarks Assumption is num_luma_samples will be at least 395 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well 396 * 397 ******************************************************************************* 398 */ 399 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples) 400 { 401 402 403 WORD32 tu_data_size; 404 WORD32 num_ctb; 405 WORD32 num_luma_tu, num_chroma_tu, num_tu; 406 num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE); 407 408 num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE); 409 num_chroma_tu = num_luma_tu >> 1; 410 411 num_tu = num_luma_tu + num_chroma_tu; 412 tu_data_size = 0; 413 414 /* Size for storing tu_t start index each CTB */ 415 /* One extra entry is needed to compute number of TUs in the last CTB */ 416 tu_data_size += (num_ctb + 1) * sizeof(WORD32); 417 418 /* Size for storing tu map */ 419 tu_data_size += num_luma_tu * sizeof(UWORD8); 420 421 /* Size for storing tu_t for each TU */ 422 tu_data_size += num_tu * sizeof(tu_t); 423 424 /* Size for storing number of coded subblocks and scan_idx for each TU */ 425 tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8)); 426 427 /* Size for storing coeff data for each TU */ 428 tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t); 429 430 431 return tu_data_size; 432 } 433 434 435 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps) 436 { 437 WORD32 nctb = 1; 438 UNUSED(ps_codec); 439 //TODO: Currently set to 1 440 /* If CTB size is less than 32 x 32 then set nCTB as 4 */ 441 if(ps_sps->i1_log2_ctb_size < 5) 442 nctb = 1; 443 444 return nctb; 445 } 446 447 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps, 448 sps_t *ps_sps, 449 WORD32 ctb_x, 450 WORD32 ctb_y, 451 WORD32 *pi4_ctb_tile_x, 452 WORD32 *pi4_ctb_tile_y, 453 WORD32 *pi4_tile_idx) 454 { 455 456 tile_t *ps_tile_tmp; 457 WORD32 i; 458 WORD32 tile_row, tile_col; 459 460 if(ctb_x < 0 || ctb_y < 0) 461 { 462 *pi4_ctb_tile_x = 0; 463 *pi4_ctb_tile_y = 0; 464 *pi4_tile_idx = 0; 465 466 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 467 } 468 469 tile_row = 0; 470 tile_col = 0; 471 ps_tile_tmp = ps_pps->ps_tile; 472 if(0 == ps_pps->i1_tiles_enabled_flag) 473 { 474 *pi4_ctb_tile_x = ctb_x; 475 *pi4_ctb_tile_y = ctb_y; 476 *pi4_tile_idx = 0; 477 } 478 else 479 { 480 for(i = 0; i < ps_pps->i1_num_tile_columns; i++) 481 { 482 WORD16 next_tile_ctb_x; 483 ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows; 484 if((ps_pps->i1_num_tile_columns - 1) == i) 485 { 486 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb; 487 } 488 else 489 { 490 tile_t *ps_tile_next_tmp; 491 ps_tile_next_tmp = ps_pps->ps_tile + i + 1; 492 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x; 493 } 494 if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x)) 495 { 496 tile_col = i; 497 break; 498 } 499 } 500 *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x; 501 502 for(i = 0; i < ps_pps->i1_num_tile_rows; i++) 503 { 504 WORD16 next_tile_ctb_y; 505 ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns; 506 if((ps_pps->i1_num_tile_rows - 1) == i) 507 { 508 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb; 509 } 510 else 511 { 512 tile_t *ps_tile_next_tmp; 513 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns); 514 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y; 515 } 516 if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y)) 517 { 518 tile_row = i; 519 break; 520 } 521 522 } 523 *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y; 524 *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns 525 + tile_col; 526 } 527 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 528 } 529 /** 530 ******************************************************************************* 531 * 532 * @brief 533 * Function to initialize ps_pic_buf structs add pic buffers to 534 * buffer manager in case of non-shared mode 535 * 536 * @par Description: 537 * Function to initialize ps_pic_buf structs add pic buffers to 538 * buffer manager in case of non-shared mode 539 * To be called once per stream or for every reset 540 * 541 * @param[in] ps_codec 542 * Pointer to codec context 543 * 544 * @returns Error from IHEVCD_ERROR_T 545 * 546 * @remarks 547 * 548 * 549 ******************************************************************************* 550 */ 551 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec) 552 { 553 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 554 WORD32 i; 555 WORD32 max_dpb_size; 556 sps_t *ps_sps; 557 UWORD8 *pu1_buf; 558 pic_buf_t *ps_pic_buf; 559 WORD32 pic_buf_size_allocated; 560 561 WORD32 max_num_bufs; 562 WORD32 pic_size; 563 WORD32 level; 564 565 566 /* Initialize MV Bank buffer manager */ 567 ps_sps = ps_codec->s_parse.ps_sps; 568 569 pic_size = ps_sps->i2_pic_width_in_luma_samples * 570 ps_sps->i2_pic_height_in_luma_samples; 571 572 573 /* Compute the number of MB Bank buffers needed */ 574 level = ps_codec->i4_init_level; 575 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 576 /* Allocate twice dpb size to handle worst case reorder without returning more 577 * than one output per call 578 */ 579 max_dpb_size *= 2; 580 /* Allocate one extra picture to handle current frame 581 * In case of asynchronous parsing and processing, number of buffers should increase here 582 * based on when parsing and processing threads are synchronized 583 */ 584 max_dpb_size++; 585 586 /* If num_ref_frames and num_reorder_frmaes is specified 587 * Use minimum value 588 */ 589 max_num_bufs = MIN(max_dpb_size, (ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1)); 590 591 592 pu1_buf = (UWORD8 *)ps_codec->ps_pic_buf; 593 594 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf; 595 596 pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 597 598 /* In case of non-shared mode, add picture buffers to buffer manager 599 * In case of shared mode buffers are added in the run-time 600 */ 601 if(0 == ps_codec->i4_share_disp_buf) 602 { 603 WORD32 buf_ret; 604 WORD32 luma_samples; 605 WORD32 chroma_samples; 606 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size - 607 BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 608 609 luma_samples = (ps_codec->i4_strd) * 610 (ps_sps->i2_pic_height_in_luma_samples + PAD_HT); 611 612 chroma_samples = luma_samples / 2; 613 614 /* Try to add as many buffers as possible since memory is already allocated */ 615 /* If the number of buffers that can be added is less than max_num_bufs 616 * return with an error. 617 */ 618 for(i = 0; i < (2 * MAX_DPB_SIZE) + 1; i++) 619 { 620 pic_buf_size_allocated -= (luma_samples + chroma_samples); 621 622 if(pic_buf_size_allocated < 0) 623 { 624 if(i < max_num_bufs) 625 { 626 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF; 627 return IHEVCD_INSUFFICIENT_MEM_PICBUF; 628 } 629 break; 630 } 631 632 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT; 633 pu1_buf += luma_samples; 634 635 ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT; 636 pu1_buf += chroma_samples; 637 638 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 639 640 if(0 != buf_ret) 641 { 642 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 643 return IHEVCD_BUF_MGR_ERROR; 644 } 645 ps_pic_buf++; 646 } 647 } 648 649 return ret; 650 } 651 /** 652 ******************************************************************************* 653 * 654 * @brief 655 * Function to add buffers to MV Bank buffer manager 656 * 657 * @par Description: 658 * Function to add buffers to MV Bank buffer manager 659 * To be called once per stream or for every reset 660 * 661 * @param[in] ps_codec 662 * Pointer to codec context 663 * 664 * @returns Error from IHEVCD_ERROR_T 665 * 666 * @remarks 667 * 668 * 669 ******************************************************************************* 670 */ 671 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec) 672 { 673 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 674 WORD32 i; 675 WORD32 max_dpb_size; 676 WORD32 mv_bank_size_allocated; 677 WORD32 pic_mv_bank_size; 678 WORD32 level; 679 sps_t *ps_sps; 680 UWORD8 *pu1_buf; 681 mv_buf_t *ps_mv_buf; 682 683 684 /* Initialize MV Bank buffer manager */ 685 ps_sps = ps_codec->s_parse.ps_sps; 686 687 688 /* Compute the number of MB Bank buffers needed */ 689 level = ps_codec->i4_init_level; 690 max_dpb_size = ihevcd_get_dpb_size(level, 691 ps_sps->i2_pic_width_in_luma_samples * 692 ps_sps->i2_pic_height_in_luma_samples); 693 694 /* Allocate one extra MV Bank to handle current frame 695 * In case of asynchronous parsing and processing, number of buffers should increase here 696 * based on when parsing and processing threads are synchronized 697 */ 698 max_dpb_size++; 699 700 pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base; 701 702 ps_mv_buf = (mv_buf_t *)pu1_buf; 703 pu1_buf += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t); 704 ps_codec->ps_mv_buf = ps_mv_buf; 705 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t); 706 707 /* Compute MV bank size per picture */ 708 pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ps_sps->i2_pic_width_in_luma_samples * 709 ps_sps->i2_pic_height_in_luma_samples); 710 711 for(i = 0; i < max_dpb_size; i++) 712 { 713 WORD32 buf_ret; 714 WORD32 num_pu; 715 WORD32 num_ctb; 716 WORD32 pic_size; 717 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 718 ALIGN64(ps_sps->i2_pic_height_in_luma_samples); 719 720 721 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 722 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 723 724 725 mv_bank_size_allocated -= pic_mv_bank_size; 726 727 if(mv_bank_size_allocated < 0) 728 { 729 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK; 730 return IHEVCD_INSUFFICIENT_MEM_MVBANK; 731 } 732 733 ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf; 734 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 735 736 ps_mv_buf->pu1_pic_pu_map = pu1_buf; 737 pu1_buf += num_pu; 738 739 ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf; 740 pu1_buf += num_ctb * sizeof(UWORD16); 741 742 ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf; 743 744 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i); 745 746 if(0 != buf_ret) 747 { 748 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 749 return IHEVCD_BUF_MGR_ERROR; 750 } 751 pu1_buf += pic_mv_bank_size; 752 ps_mv_buf++; 753 754 } 755 return ret; 756 } 757 /** 758 ******************************************************************************* 759 * 760 * @brief 761 * Picture level initializations required during parsing 762 * 763 * @par Description: 764 * Initialize picture level context variables during parsing Initialize mv 765 * bank buffer manager in the first init call 766 * 767 * @param[in] ps_codec 768 * Pointer to codec context 769 * 770 * @returns Error from IHEVCD_ERROR_T 771 * 772 * @remarks 773 * 774 * 775 ******************************************************************************* 776 */ 777 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) 778 { 779 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 780 mv_buf_t *ps_mv_buf; 781 sps_t *ps_sps; 782 WORD32 num_min_cu; 783 WORD32 cur_pic_buf_id; 784 WORD32 cur_mv_bank_buf_id; 785 pic_buf_t *ps_cur_pic; 786 slice_header_t *ps_slice_hdr; 787 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma; 788 WORD32 i; 789 790 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS; 791 ps_sps = ps_codec->s_parse.ps_sps; 792 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 793 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */ 794 ps_codec->i4_pic_present = 1; 795 796 /* Memset picture level intra map and transquant bypass map to zero */ 797 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64); 798 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu); 799 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu); 800 801 802 803 if(0 == ps_codec->s_parse.i4_first_pic_init) 804 { 805 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec); 806 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 807 808 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec); 809 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 810 811 ps_codec->s_parse.i4_first_pic_init = 1; 812 } 813 814 /* Initialize all the slice headers' slice addresses to zero */ 815 { 816 WORD32 slice_idx; 817 WORD32 slice_start_idx; 818 819 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1; 820 821 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++) 822 { 823 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx; 824 ps_slice_hdr_tmp->i2_ctb_x = -1; 825 ps_slice_hdr_tmp->i2_ctb_y = -1; 826 827 } 828 } 829 830 /* Get free MV Bank to hold current picture's motion vector data */ 831 { 832 ps_mv_buf = (mv_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, &cur_mv_bank_buf_id); 833 834 /* If there are no free buffers then return with an error code. 835 * If the buffer is to be freed by another thread , change the 836 * following to call thread yield and wait for buffer to be freed 837 */ 838 if(NULL == ps_mv_buf) 839 { 840 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK; 841 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK; 842 return IHEVCD_NO_FREE_MVBANK; 843 } 844 845 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf; 846 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer 847 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array 848 * and getting a buffer id to free 849 */ 850 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 851 } 852 853 /* Get free picture buffer to hold current picture recon data */ 854 /* TODO: For asynchronous api the following initializations related to picture 855 * buffer should be moved to processing side 856 */ 857 { 858 859 UWORD8 *pu1_buf; 860 ps_cur_pic = (pic_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, &cur_pic_buf_id); 861 862 /* If there are no free buffers then return with an error code. 863 * TODO: If the buffer is to be freed by another thread , change the 864 * following to call thread yield and wait for buffer to be freed 865 */ 866 if(NULL == ps_cur_pic) 867 { 868 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF; 869 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF; 870 return IHEVCD_NO_FREE_PICBUF; 871 } 872 873 /* Store input timestamp sent with input buffer */ 874 ps_cur_pic->u4_ts = ps_codec->u4_ts; 875 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 876 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb; 877 pu1_buf = ps_cur_pic->pu1_luma; 878 pu1_cur_pic_luma = pu1_buf; 879 880 pu1_buf = ps_cur_pic->pu1_chroma; 881 882 pu1_cur_pic_chroma = pu1_buf; 883 } 884 885 if(0 == ps_codec->u4_pic_cnt) 886 { 887 memset(ps_cur_pic->pu1_luma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples); 888 memset(ps_cur_pic->pu1_chroma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples / 2); 889 } 890 891 /* Fill the remaining entries of the reference lists with the nearest POC 892 * This is done to handle cases where there is a corruption in the reference index */ 893 { 894 pic_buf_t *ps_pic_buf_ref; 895 mv_buf_t *ps_mv_buf_ref; 896 WORD32 r_idx; 897 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr; 898 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr; 899 900 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt); 901 if(NULL == ps_pic_buf_ref) 902 { 903 ps_pic_buf_ref = ps_cur_pic; 904 ps_mv_buf_ref = ps_mv_buf; 905 } 906 else 907 { 908 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc); 909 } 910 911 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++) 912 { 913 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf) 914 { 915 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 916 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 917 } 918 } 919 920 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++) 921 { 922 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 923 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 924 } 925 926 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++) 927 { 928 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf) 929 { 930 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 931 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 932 } 933 } 934 935 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++) 936 { 937 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 938 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 939 } 940 } 941 942 943 /* Reset the jobq to start of the jobq buffer */ 944 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq); 945 946 ps_codec->s_parse.i4_pic_pu_idx = 0; 947 ps_codec->s_parse.i4_pic_tu_idx = 0; 948 949 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map; 950 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu; 951 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx; 952 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 953 for(i = 0; i < MAX_PROCESS_THREADS; i++) 954 { 955 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 956 } 957 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 958 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu; 959 960 { 961 UWORD8 *pu1_buf; 962 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt; 963 WORD32 pic_size; 964 WORD32 num_ctb; 965 966 pic_size = ps_sps->i2_pic_width_in_luma_samples * 967 ps_sps->i2_pic_height_in_luma_samples; 968 969 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE); 970 971 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1; 972 973 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt; 974 975 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 976 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data; 977 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf; 978 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 979 980 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf; 981 pu1_buf += ctb_min_tu_cnt; 982 983 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf; 984 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t); 985 986 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf; 987 988 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 989 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 990 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 991 } 992 993 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 994 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 995 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 996 997 998 /* Set number of CTBs to be processed simultaneously */ 999 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps); 1000 1001 /* Memset Parse Map and process map at the start of frame */ 1002 //TODO: In case of asynchronous API proc_map can not be set to zero here 1003 { 1004 WORD32 num_ctb; 1005 1006 num_ctb = ps_sps->i4_pic_size_in_ctb; 1007 1008 memset(ps_codec->pu1_parse_map, 0, num_ctb); 1009 1010 memset(ps_codec->pu1_proc_map, 0, num_ctb); 1011 } 1012 1013 1014 1015 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is 1016 * buffer to be displayed 1017 */ 1018 ps_codec->i4_disp_buf_id = -1; 1019 ps_codec->ps_disp_buf = NULL; 1020 1021 ps_codec->i4_disable_deblk_pic = 0; 1022 ps_codec->i4_disable_sao_pic = 0; 1023 ps_codec->i4_fullpel_inter_pred = 0; 1024 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF; 1025 1026 /* If degrade is enabled, set the degrade flags appropriately */ 1027 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics) 1028 { 1029 WORD32 degrade_pic; 1030 ps_codec->i4_degrade_pic_cnt++; 1031 degrade_pic = 0; 1032 1033 /* If degrade is to be done in all frames, then do not check further */ 1034 switch(ps_codec->i4_degrade_pics) 1035 { 1036 case 4: 1037 { 1038 degrade_pic = 1; 1039 break; 1040 } 1041 case 3: 1042 { 1043 if(ps_slice_hdr->i1_slice_type != ISLICE) 1044 degrade_pic = 1; 1045 1046 break; 1047 } 1048 case 2: 1049 { 1050 1051 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */ 1052 if((ps_slice_hdr->i1_slice_type != ISLICE) && 1053 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval)) 1054 degrade_pic = 1; 1055 1056 break; 1057 } 1058 case 1: 1059 { 1060 /* Check if the current picture is non-ref */ 1061 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1062 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1063 { 1064 degrade_pic = 1; 1065 } 1066 break; 1067 } 1068 1069 1070 } 1071 if(degrade_pic) 1072 { 1073 if(ps_codec->i4_degrade_type & 0x1) 1074 ps_codec->i4_disable_sao_pic = 1; 1075 1076 if(ps_codec->i4_degrade_type & 0x2) 1077 ps_codec->i4_disable_deblk_pic = 1; 1078 1079 /* MC degrading is done only for non-ref pictures */ 1080 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1081 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1082 { 1083 if(ps_codec->i4_degrade_type & 0x4) 1084 ps_codec->i4_mv_frac_mask = 0; 1085 1086 if(ps_codec->i4_degrade_type & 0x8) 1087 ps_codec->i4_mv_frac_mask = 0; 1088 } 1089 } 1090 else 1091 ps_codec->i4_degrade_pic_cnt = 0; 1092 } 1093 1094 1095 { 1096 WORD32 i; 1097 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1098 { 1099 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 1100 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 1101 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 1102 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 1103 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu; 1104 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 1105 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 1106 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id; 1107 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx; 1108 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx; 1109 1110 /* TODO: For asynchronous api the following initializations related to picture 1111 * buffer should be moved to processing side 1112 */ 1113 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma; 1114 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1115 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic; 1116 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id; 1117 1118 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer; 1119 if(1 < ps_codec->i4_num_cores) 1120 { 1121 ps_codec->as_process[i].i4_check_parse_status = 1; 1122 ps_codec->as_process[i].i4_check_proc_status = 1; 1123 } 1124 else 1125 { 1126 ps_codec->as_process[i].i4_check_parse_status = 0; 1127 ps_codec->as_process[i].i4_check_proc_status = 0; 1128 } 1129 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag; 1130 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1131 ps_codec->as_process[i].i4_init_done = 0; 1132 1133 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx; 1134 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx; 1135 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu; 1136 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1137 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1138 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1139 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1140 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1141 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1142 if(i < (ps_codec->i4_num_cores - 1)) 1143 { 1144 ithread_create(ps_codec->apv_process_thread_handle[i], NULL, 1145 (void *)ihevcd_process_thread, 1146 (void *)&ps_codec->as_process[i]); 1147 ps_codec->ai4_process_thread_created[i] = 1; 1148 } 1149 else 1150 { 1151 ps_codec->ai4_process_thread_created[i] = 0; 1152 } 1153 1154 } 1155 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1156 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1157 1158 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1159 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1160 } 1161 /* Since any input bitstream buffer that contains slice data will be sent to output(even in 1162 * case of error, this buffer is added to display queue and next buffer in the display queue 1163 * will be returned as the display buffer. 1164 * Note: If format conversion (or frame copy) is used and is scheduled 1165 * in a different thread then it has to check if the processing for the current row is complete before 1166 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be 1167 * returned, which requires a status check to ensure that the current row is reconstructed before copying. 1168 */ 1169 /* Add current picture to display manager */ 1170 { 1171 WORD32 abs_poc; 1172 slice_header_t *ps_slice_hdr; 1173 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 1174 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 1175 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, 1176 ps_codec->as_process[0].i4_cur_pic_buf_id, 1177 abs_poc, 1178 ps_codec->as_process[0].ps_cur_pic); 1179 } 1180 ps_codec->ps_disp_buf = NULL; 1181 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */ 1182 /* Since the current will be decoded, check is fore >= instead of > */ 1183 if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) || 1184 ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder)) 1185 1186 { 1187 ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id); 1188 ps_codec->u4_disp_cnt++; 1189 } 1190 1191 ps_codec->s_fmt_conv.i4_cur_row = 0; 1192 /* Set number of rows to be processed at a time */ 1193 ps_codec->s_fmt_conv.i4_num_rows = 4; 1194 1195 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1)) 1196 { 1197 process_ctxt_t *ps_proc; 1198 1199 /* i4_num_cores - 1 contexts are currently being used by other threads */ 1200 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 1201 1202 /* If the frame being decoded and displayed are different, schedule format conversion jobs 1203 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead 1204 * If the frame being decoded and displayed are same, then format conversion is scheduled later. 1205 */ 1206 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) && 1207 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt))) 1208 { 1209 1210 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++) 1211 { 1212 proc_job_t s_job; 1213 IHEVCD_ERROR_T ret; 1214 s_job.i4_cmd = CMD_FMTCONV; 1215 s_job.i2_ctb_cnt = 0; 1216 s_job.i2_ctb_x = 0; 1217 s_job.i2_ctb_y = i; 1218 s_job.i2_slice_idx = 0; 1219 s_job.i4_tu_coeff_data_ofst = 0; 1220 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, 1221 &s_job, sizeof(proc_job_t), 1); 1222 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 1223 return ret; 1224 } 1225 } 1226 } 1227 1228 1229 return ret; 1230 } 1231 1232 1233