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