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 num_ref_frames, 250 WORD32 num_reorder_frames) 251 { 252 WORD32 size; 253 WORD32 num_luma_samples; 254 WORD32 lvl_idx; 255 WORD32 max_wd; 256 WORD32 max_dpb_size; 257 WORD32 num_samples; 258 WORD32 max_num_bufs; 259 WORD32 pad = MAX(horz_pad, vert_pad); 260 261 262 /* Get maximum number of buffers for the current picture size */ 263 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 264 265 266 max_num_bufs = (2 * max_dpb_size + 1); 267 /* If num_ref_frames and num_reorder_frmaes is specified 268 * Use minimum value 269 */ 270 max_num_bufs = MIN(max_num_bufs, (num_ref_frames + num_reorder_frames + 1)); 271 272 /* Get level index */ 273 lvl_idx = ihevcd_get_lvl_idx(level); 274 275 /* Maximum number of luma samples in a picture at given level */ 276 num_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx]; 277 278 /* Account for chroma */ 279 num_samples = num_luma_samples * 3 / 2; 280 281 /* Maximum width of luma samples in a picture at given level */ 282 max_wd = gai4_ihevc_max_wd_ht[lvl_idx]; 283 284 285 /* Allocation is required for 286 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1) 287 * 288 * Above expanded as 289 * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1) 290 * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1) 291 * 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 292 * 293 * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below 294 * 295 * For the padded area use MAX(horz_pad, vert_pad) as pad 296 * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding 297 * 298 * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min 299 * So use max_wd and min_ht 300 */ 301 302 /* Number of bytes in reference pictures */ 303 size = num_samples * max_num_bufs; 304 305 /* Account for padding area */ 306 size += ((pad * pad) + pad * (max_wd + max_wd)) * max_num_bufs; 307 308 return size; 309 } 310 /** 311 ******************************************************************************* 312 * 313 * @brief 314 * Used to get MV bank size for a given number of luma samples 315 * 316 * @par Description: 317 * For given number of luma samples one MV bank size is computed 318 * Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture 319 * 320 * @param[in] num_luma_samples 321 * Max number of luma pixels in the frame 322 * 323 * @returns Total MV Bank size 324 * 325 * @remarks 326 * 327 * 328 ******************************************************************************* 329 */ 330 WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples) 331 { 332 WORD32 size; 333 334 WORD32 pic_size; 335 336 WORD32 mv_bank_size; 337 WORD32 num_pu; 338 WORD32 num_ctb; 339 pic_size = num_luma_samples; 340 341 342 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 343 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 344 345 mv_bank_size = 0; 346 347 /* Size for storing pu_t start index each CTB */ 348 /* One extra entry is needed to compute number of PUs in the last CTB */ 349 mv_bank_size += (num_ctb + 1) * sizeof(WORD32); 350 351 /* Size for pu_map */ 352 mv_bank_size += num_pu; 353 354 /* Size for storing pu_t for each PU */ 355 mv_bank_size += num_pu * sizeof(pu_t); 356 357 358 size = mv_bank_size; 359 return size; 360 } 361 /** 362 ******************************************************************************* 363 * 364 * @brief 365 * Used to get TU data size for a given number luma samples 366 * 367 * @par Description: 368 * For a given number of luma samples TU data size is computed 369 * Each TU data includes tu_map and tu_t and coeff data for all 370 * the min TUs(4x4) in given CTB 371 * 372 * @param[in] num_luma_samples 373 * Number of 64 x 64 CTBs for which TU data has to be allocated. 374 * 375 * @returns Total TU data size 376 * 377 * @remarks Assumption is num_luma_samples will be at least 378 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well 379 * 380 ******************************************************************************* 381 */ 382 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples) 383 { 384 385 386 WORD32 tu_data_size; 387 WORD32 num_ctb; 388 WORD32 num_luma_tu, num_chroma_tu, num_tu; 389 num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE); 390 391 num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE); 392 num_chroma_tu = num_luma_tu >> 1; 393 394 num_tu = num_luma_tu + num_chroma_tu; 395 tu_data_size = 0; 396 397 /* Size for storing tu_t start index each CTB */ 398 /* One extra entry is needed to compute number of TUs in the last CTB */ 399 tu_data_size += (num_ctb + 1) * sizeof(WORD32); 400 401 /* Size for storing tu map */ 402 tu_data_size += num_luma_tu * sizeof(UWORD8); 403 404 /* Size for storing tu_t for each TU */ 405 tu_data_size += num_tu * sizeof(tu_t); 406 407 /* Size for storing number of coded subblocks and scan_idx for each TU */ 408 tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8)); 409 410 /* Size for storing coeff data for each TU */ 411 tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t); 412 413 414 return tu_data_size; 415 } 416 417 418 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps) 419 { 420 WORD32 nctb = 1; 421 UNUSED(ps_codec); 422 //TODO: Currently set to 1 423 /* If CTB size is less than 32 x 32 then set nCTB as 4 */ 424 if(ps_sps->i1_log2_ctb_size < 5) 425 nctb = 1; 426 427 return nctb; 428 } 429 430 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps, 431 sps_t *ps_sps, 432 WORD32 ctb_x, 433 WORD32 ctb_y, 434 WORD32 *pi4_ctb_tile_x, 435 WORD32 *pi4_ctb_tile_y, 436 WORD32 *pi4_tile_idx) 437 { 438 439 tile_t *ps_tile_tmp; 440 WORD32 i; 441 WORD32 tile_row, tile_col; 442 443 if(ctb_x < 0 || ctb_y < 0) 444 { 445 *pi4_ctb_tile_x = 0; 446 *pi4_ctb_tile_y = 0; 447 *pi4_tile_idx = 0; 448 449 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 450 } 451 452 tile_row = 0; 453 tile_col = 0; 454 ps_tile_tmp = ps_pps->ps_tile; 455 if(0 == ps_pps->i1_tiles_enabled_flag) 456 { 457 *pi4_ctb_tile_x = ctb_x; 458 *pi4_ctb_tile_y = ctb_y; 459 *pi4_tile_idx = 0; 460 } 461 else 462 { 463 for(i = 0; i < ps_pps->i1_num_tile_columns; i++) 464 { 465 WORD16 next_tile_ctb_x; 466 ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows; 467 if((ps_pps->i1_num_tile_columns - 1) == i) 468 { 469 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb; 470 } 471 else 472 { 473 tile_t *ps_tile_next_tmp; 474 ps_tile_next_tmp = ps_pps->ps_tile + i + 1; 475 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x; 476 } 477 if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x)) 478 { 479 tile_col = i; 480 break; 481 } 482 } 483 *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x; 484 485 for(i = 0; i < ps_pps->i1_num_tile_rows; i++) 486 { 487 WORD16 next_tile_ctb_y; 488 ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns; 489 if((ps_pps->i1_num_tile_rows - 1) == i) 490 { 491 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb; 492 } 493 else 494 { 495 tile_t *ps_tile_next_tmp; 496 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns); 497 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y; 498 } 499 if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y)) 500 { 501 tile_row = i; 502 break; 503 } 504 505 } 506 *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y; 507 *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns 508 + tile_col; 509 } 510 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 511 } 512 /** 513 ******************************************************************************* 514 * 515 * @brief 516 * Function to initialize ps_pic_buf structs add pic buffers to 517 * buffer manager in case of non-shared mode 518 * 519 * @par Description: 520 * Function to initialize ps_pic_buf structs add pic buffers to 521 * buffer manager in case of non-shared mode 522 * To be called once per stream or for every reset 523 * 524 * @param[in] ps_codec 525 * Pointer to codec context 526 * 527 * @returns Error from IHEVCD_ERROR_T 528 * 529 * @remarks 530 * 531 * 532 ******************************************************************************* 533 */ 534 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec) 535 { 536 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 537 WORD32 i; 538 WORD32 max_dpb_size; 539 sps_t *ps_sps; 540 UWORD8 *pu1_buf; 541 pic_buf_t *ps_pic_buf; 542 WORD32 pic_buf_size_allocated; 543 544 WORD32 max_num_bufs; 545 WORD32 pic_size; 546 WORD32 level; 547 548 549 /* Initialize MV Bank buffer manager */ 550 ps_sps = ps_codec->s_parse.ps_sps; 551 552 pic_size = ps_sps->i2_pic_width_in_luma_samples * 553 ps_sps->i2_pic_height_in_luma_samples; 554 555 556 /* Compute the number of MB Bank buffers needed */ 557 level = ps_codec->i4_init_level; 558 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 559 /* Allocate twice dpb size to handle worst case reorder without returning more 560 * than one output per call 561 */ 562 max_dpb_size *= 2; 563 /* Allocate one extra picture to handle current frame 564 * In case of asynchronous parsing and processing, number of buffers should increase here 565 * based on when parsing and processing threads are synchronized 566 */ 567 max_dpb_size++; 568 569 /* If num_ref_frames and num_reorder_frmaes is specified 570 * Use minimum value 571 */ 572 max_num_bufs = MIN(max_dpb_size, (ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1)); 573 574 575 pu1_buf = (UWORD8 *)ps_codec->ps_pic_buf; 576 577 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf; 578 579 pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 580 581 /* In case of non-shared mode, add picture buffers to buffer manager 582 * In case of shared mode buffers are added in the run-time 583 */ 584 if(0 == ps_codec->i4_share_disp_buf) 585 { 586 WORD32 buf_ret; 587 WORD32 luma_samples; 588 WORD32 chroma_samples; 589 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size - 590 BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 591 592 luma_samples = (ps_codec->i4_strd) * 593 (ps_sps->i2_pic_height_in_luma_samples + PAD_HT); 594 595 chroma_samples = luma_samples / 2; 596 597 /* Try to add as many buffers as possible since memory is already allocated */ 598 /* If the number of buffers that can be added is less than max_num_bufs 599 * return with an error. 600 */ 601 for(i = 0; i < (2 * MAX_DPB_SIZE) + 1; i++) 602 { 603 pic_buf_size_allocated -= (luma_samples + chroma_samples); 604 605 if(pic_buf_size_allocated < 0) 606 { 607 if(i < max_num_bufs) 608 { 609 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF; 610 return IHEVCD_INSUFFICIENT_MEM_PICBUF; 611 } 612 break; 613 } 614 615 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT; 616 pu1_buf += luma_samples; 617 618 ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT; 619 pu1_buf += chroma_samples; 620 621 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 622 623 if(0 != buf_ret) 624 { 625 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 626 return IHEVCD_BUF_MGR_ERROR; 627 } 628 ps_pic_buf++; 629 } 630 } 631 632 return ret; 633 } 634 /** 635 ******************************************************************************* 636 * 637 * @brief 638 * Function to add buffers to MV Bank buffer manager 639 * 640 * @par Description: 641 * Function to add buffers to MV Bank buffer manager 642 * To be called once per stream or for every reset 643 * 644 * @param[in] ps_codec 645 * Pointer to codec context 646 * 647 * @returns Error from IHEVCD_ERROR_T 648 * 649 * @remarks 650 * 651 * 652 ******************************************************************************* 653 */ 654 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec) 655 { 656 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 657 WORD32 i; 658 WORD32 max_dpb_size; 659 WORD32 mv_bank_size_allocated; 660 WORD32 pic_mv_bank_size; 661 WORD32 level; 662 sps_t *ps_sps; 663 UWORD8 *pu1_buf; 664 mv_buf_t *ps_mv_buf; 665 666 667 /* Initialize MV Bank buffer manager */ 668 ps_sps = ps_codec->s_parse.ps_sps; 669 670 671 /* Compute the number of MB Bank buffers needed */ 672 level = ps_codec->i4_init_level; 673 max_dpb_size = ihevcd_get_dpb_size(level, 674 ps_sps->i2_pic_width_in_luma_samples * 675 ps_sps->i2_pic_height_in_luma_samples); 676 677 /* Allocate one extra MV Bank to handle current frame 678 * In case of asynchronous parsing and processing, number of buffers should increase here 679 * based on when parsing and processing threads are synchronized 680 */ 681 max_dpb_size++; 682 683 pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base; 684 685 ps_mv_buf = (mv_buf_t *)pu1_buf; 686 pu1_buf += BUF_MGR_MAX_CNT * sizeof(mv_buf_t); 687 ps_codec->ps_mv_buf = ps_mv_buf; 688 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - BUF_MGR_MAX_CNT * sizeof(mv_buf_t); 689 690 /* Compute MV bank size per picture */ 691 pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ps_sps->i2_pic_width_in_luma_samples * 692 ps_sps->i2_pic_height_in_luma_samples); 693 694 for(i = 0; i < max_dpb_size; i++) 695 { 696 WORD32 buf_ret; 697 WORD32 num_pu; 698 WORD32 num_ctb; 699 WORD32 pic_size; 700 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 701 ALIGN64(ps_sps->i2_pic_height_in_luma_samples); 702 703 704 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 705 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 706 707 708 mv_bank_size_allocated -= pic_mv_bank_size; 709 710 if(mv_bank_size_allocated < 0) 711 { 712 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK; 713 return IHEVCD_INSUFFICIENT_MEM_MVBANK; 714 } 715 716 ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf; 717 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 718 719 ps_mv_buf->pu1_pic_pu_map = pu1_buf; 720 pu1_buf += num_pu; 721 722 ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf; 723 pu1_buf += num_ctb * sizeof(UWORD16); 724 725 ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf; 726 727 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i); 728 729 if(0 != buf_ret) 730 { 731 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 732 return IHEVCD_BUF_MGR_ERROR; 733 } 734 pu1_buf += pic_mv_bank_size; 735 ps_mv_buf++; 736 737 } 738 return ret; 739 } 740 /** 741 ******************************************************************************* 742 * 743 * @brief 744 * Picture level initializations required during parsing 745 * 746 * @par Description: 747 * Initialize picture level context variables during parsing Initialize mv 748 * bank buffer manager in the first init call 749 * 750 * @param[in] ps_codec 751 * Pointer to codec context 752 * 753 * @returns Error from IHEVCD_ERROR_T 754 * 755 * @remarks 756 * 757 * 758 ******************************************************************************* 759 */ 760 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) 761 { 762 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 763 mv_buf_t *ps_mv_buf; 764 sps_t *ps_sps; 765 WORD32 num_min_cu; 766 WORD32 cur_pic_buf_id; 767 WORD32 cur_mv_bank_buf_id; 768 pic_buf_t *ps_cur_pic; 769 slice_header_t *ps_slice_hdr; 770 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma; 771 WORD32 i; 772 773 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS; 774 ps_sps = ps_codec->s_parse.ps_sps; 775 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 776 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */ 777 ps_codec->i4_pic_present = 1; 778 779 /* Memset picture level intra map and transquant bypass map to zero */ 780 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64); 781 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu); 782 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu); 783 784 785 786 if(0 == ps_codec->s_parse.i4_first_pic_init) 787 { 788 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec); 789 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 790 791 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec); 792 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 793 794 ps_codec->s_parse.i4_first_pic_init = 1; 795 } 796 797 /* Initialize all the slice headers' slice addresses to zero */ 798 { 799 WORD32 slice_idx; 800 WORD32 slice_start_idx; 801 802 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1; 803 804 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++) 805 { 806 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx; 807 ps_slice_hdr_tmp->i2_ctb_x = -1; 808 ps_slice_hdr_tmp->i2_ctb_y = -1; 809 810 } 811 } 812 813 /* Get free MV Bank to hold current picture's motion vector data */ 814 { 815 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); 816 817 /* If there are no free buffers then return with an error code. 818 * If the buffer is to be freed by another thread , change the 819 * following to call thread yield and wait for buffer to be freed 820 */ 821 if(NULL == ps_mv_buf) 822 { 823 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK; 824 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK; 825 return IHEVCD_NO_FREE_MVBANK; 826 } 827 828 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf; 829 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer 830 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array 831 * and getting a buffer id to free 832 */ 833 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 834 } 835 836 /* Get free picture buffer to hold current picture recon data */ 837 /* TODO: For asynchronous api the following initializations related to picture 838 * buffer should be moved to processing side 839 */ 840 { 841 842 UWORD8 *pu1_buf; 843 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); 844 845 /* If there are no free buffers then return with an error code. 846 * TODO: If the buffer is to be freed by another thread , change the 847 * following to call thread yield and wait for buffer to be freed 848 */ 849 if(NULL == ps_cur_pic) 850 { 851 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF; 852 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF; 853 return IHEVCD_NO_FREE_PICBUF; 854 } 855 856 /* Store input timestamp sent with input buffer */ 857 ps_cur_pic->u4_ts = ps_codec->u4_ts; 858 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 859 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb; 860 pu1_buf = ps_cur_pic->pu1_luma; 861 pu1_cur_pic_luma = pu1_buf; 862 863 pu1_buf = ps_cur_pic->pu1_chroma; 864 865 pu1_cur_pic_chroma = pu1_buf; 866 } 867 868 if(0 == ps_codec->u4_pic_cnt) 869 { 870 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); 871 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); 872 } 873 874 /* Fill the remaining entries of the reference lists with the nearest POC 875 * This is done to handle cases where there is a corruption in the reference index */ 876 { 877 pic_buf_t *ps_pic_buf_ref; 878 mv_buf_t *ps_mv_buf_ref; 879 WORD32 r_idx; 880 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr; 881 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr; 882 883 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt); 884 if(NULL == ps_pic_buf_ref) 885 { 886 ps_pic_buf_ref = ps_cur_pic; 887 ps_mv_buf_ref = ps_mv_buf; 888 } 889 else 890 { 891 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc); 892 } 893 894 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++) 895 { 896 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf) 897 { 898 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 899 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 900 } 901 } 902 903 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++) 904 { 905 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 906 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 907 } 908 909 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++) 910 { 911 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf) 912 { 913 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 914 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 915 } 916 } 917 918 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++) 919 { 920 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 921 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 922 } 923 } 924 925 926 /* Reset the jobq to start of the jobq buffer */ 927 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq); 928 929 ps_codec->s_parse.i4_pic_pu_idx = 0; 930 ps_codec->s_parse.i4_pic_tu_idx = 0; 931 932 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map; 933 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu; 934 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx; 935 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 936 for(i = 0; i < MAX_PROCESS_THREADS; i++) 937 { 938 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 939 } 940 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 941 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu; 942 943 { 944 UWORD8 *pu1_buf; 945 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt; 946 WORD32 pic_size; 947 WORD32 num_ctb; 948 949 pic_size = ps_sps->i2_pic_width_in_luma_samples * 950 ps_sps->i2_pic_height_in_luma_samples; 951 952 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE); 953 954 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1; 955 956 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt; 957 958 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 959 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data; 960 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf; 961 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 962 963 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf; 964 pu1_buf += ctb_min_tu_cnt; 965 966 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf; 967 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t); 968 969 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf; 970 971 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 972 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 973 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 974 } 975 976 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 977 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 978 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 979 980 981 /* Set number of CTBs to be processed simultaneously */ 982 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps); 983 984 /* Memset Parse Map and process map at the start of frame */ 985 //TODO: In case of asynchronous API proc_map can not be set to zero here 986 { 987 WORD32 num_ctb; 988 989 num_ctb = ps_sps->i4_pic_size_in_ctb; 990 991 memset(ps_codec->pu1_parse_map, 0, num_ctb); 992 993 memset(ps_codec->pu1_proc_map, 0, num_ctb); 994 } 995 996 997 998 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is 999 * buffer to be displayed 1000 */ 1001 ps_codec->i4_disp_buf_id = -1; 1002 ps_codec->ps_disp_buf = NULL; 1003 1004 ps_codec->i4_disable_deblk_pic = 0; 1005 ps_codec->i4_disable_sao_pic = 0; 1006 ps_codec->i4_fullpel_inter_pred = 0; 1007 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF; 1008 1009 /* If degrade is enabled, set the degrade flags appropriately */ 1010 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics) 1011 { 1012 WORD32 degrade_pic; 1013 ps_codec->i4_degrade_pic_cnt++; 1014 degrade_pic = 0; 1015 1016 /* If degrade is to be done in all frames, then do not check further */ 1017 switch(ps_codec->i4_degrade_pics) 1018 { 1019 case 4: 1020 { 1021 degrade_pic = 1; 1022 break; 1023 } 1024 case 3: 1025 { 1026 if(ps_slice_hdr->i1_slice_type != ISLICE) 1027 degrade_pic = 1; 1028 1029 break; 1030 } 1031 case 2: 1032 { 1033 1034 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */ 1035 if((ps_slice_hdr->i1_slice_type != ISLICE) && 1036 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval)) 1037 degrade_pic = 1; 1038 1039 break; 1040 } 1041 case 1: 1042 { 1043 /* Check if the current picture is non-ref */ 1044 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1045 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1046 { 1047 degrade_pic = 1; 1048 } 1049 break; 1050 } 1051 1052 1053 } 1054 if(degrade_pic) 1055 { 1056 if(ps_codec->i4_degrade_type & 0x1) 1057 ps_codec->i4_disable_sao_pic = 1; 1058 1059 if(ps_codec->i4_degrade_type & 0x2) 1060 ps_codec->i4_disable_deblk_pic = 1; 1061 1062 /* MC degrading is done only for non-ref pictures */ 1063 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1064 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1065 { 1066 if(ps_codec->i4_degrade_type & 0x4) 1067 ps_codec->i4_mv_frac_mask = 0; 1068 1069 if(ps_codec->i4_degrade_type & 0x8) 1070 ps_codec->i4_mv_frac_mask = 0; 1071 } 1072 } 1073 else 1074 ps_codec->i4_degrade_pic_cnt = 0; 1075 } 1076 1077 1078 { 1079 WORD32 i; 1080 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1081 { 1082 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 1083 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 1084 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 1085 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 1086 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu; 1087 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 1088 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 1089 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id; 1090 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx; 1091 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx; 1092 1093 /* TODO: For asynchronous api the following initializations related to picture 1094 * buffer should be moved to processing side 1095 */ 1096 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma; 1097 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1098 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic; 1099 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id; 1100 1101 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer; 1102 if(1 < ps_codec->i4_num_cores) 1103 { 1104 ps_codec->as_process[i].i4_check_parse_status = 1; 1105 ps_codec->as_process[i].i4_check_proc_status = 1; 1106 } 1107 else 1108 { 1109 ps_codec->as_process[i].i4_check_parse_status = 0; 1110 ps_codec->as_process[i].i4_check_proc_status = 0; 1111 } 1112 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag; 1113 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1114 ps_codec->as_process[i].i4_init_done = 0; 1115 1116 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx; 1117 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx; 1118 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu; 1119 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1120 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1121 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1122 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1123 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1124 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1125 if(i < (ps_codec->i4_num_cores - 1)) 1126 { 1127 ithread_create(ps_codec->apv_process_thread_handle[i], NULL, 1128 (void *)ihevcd_process_thread, 1129 (void *)&ps_codec->as_process[i]); 1130 ps_codec->ai4_process_thread_created[i] = 1; 1131 } 1132 else 1133 { 1134 ps_codec->ai4_process_thread_created[i] = 0; 1135 } 1136 1137 } 1138 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1139 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1140 1141 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1142 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1143 } 1144 /* Since any input bitstream buffer that contains slice data will be sent to output(even in 1145 * case of error, this buffer is added to display queue and next buffer in the display queue 1146 * will be returned as the display buffer. 1147 * Note: If format conversion (or frame copy) is used and is scheduled 1148 * in a different thread then it has to check if the processing for the current row is complete before 1149 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be 1150 * returned, which requires a status check to ensure that the current row is reconstructed before copying. 1151 */ 1152 /* Add current picture to display manager */ 1153 { 1154 WORD32 abs_poc; 1155 slice_header_t *ps_slice_hdr; 1156 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 1157 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 1158 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, 1159 ps_codec->as_process[0].i4_cur_pic_buf_id, 1160 abs_poc, 1161 ps_codec->as_process[0].ps_cur_pic); 1162 } 1163 ps_codec->ps_disp_buf = NULL; 1164 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */ 1165 /* Since the current will be decoded, check is fore >= instead of > */ 1166 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]) || 1167 ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder)) 1168 1169 { 1170 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); 1171 ps_codec->u4_disp_cnt++; 1172 } 1173 1174 ps_codec->s_fmt_conv.i4_cur_row = 0; 1175 /* Set number of rows to be processed at a time */ 1176 ps_codec->s_fmt_conv.i4_num_rows = 4; 1177 1178 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1)) 1179 { 1180 process_ctxt_t *ps_proc; 1181 1182 /* i4_num_cores - 1 contexts are currently being used by other threads */ 1183 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 1184 1185 /* If the frame being decoded and displayed are different, schedule format conversion jobs 1186 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead 1187 * If the frame being decoded and displayed are same, then format conversion is scheduled later. 1188 */ 1189 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) && 1190 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt))) 1191 { 1192 1193 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++) 1194 { 1195 proc_job_t s_job; 1196 IHEVCD_ERROR_T ret; 1197 s_job.i4_cmd = CMD_FMTCONV; 1198 s_job.i2_ctb_cnt = 0; 1199 s_job.i2_ctb_x = 0; 1200 s_job.i2_ctb_y = i; 1201 s_job.i2_slice_idx = 0; 1202 s_job.i4_tu_coeff_data_ofst = 0; 1203 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, 1204 &s_job, sizeof(proc_job_t), 1); 1205 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 1206 return ret; 1207 } 1208 } 1209 } 1210 1211 1212 return ret; 1213 } 1214 1215 1216