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 /* Pad boundary pixels (one pixel on all sides) */ 522 /* This ensures SAO does not read uninitialized pixels */ 523 /* Note these are not used in actual processing */ 524 { 525 UWORD8 *pu1_buf; 526 WORD32 strd, wd, ht; 527 WORD32 i; 528 strd = ps_codec->i4_strd; 529 wd = ps_codec->i4_wd; 530 ht = ps_codec->i4_ht; 531 532 pu1_buf = ps_pic_buf->pu1_luma; 533 for(i = 0; i < ht; i++) 534 { 535 pu1_buf[-1] = 0; 536 pu1_buf[wd] = 0; 537 pu1_buf += strd; 538 } 539 pu1_buf = ps_pic_buf->pu1_luma; 540 memset(pu1_buf - strd - 1, 0, wd + 2); 541 542 pu1_buf += strd * ht; 543 memset(pu1_buf - 1, 0, wd + 2); 544 545 pu1_buf = ps_pic_buf->pu1_chroma; 546 ht >>= 1; 547 for(i = 0; i < ht; i++) 548 { 549 pu1_buf[-1] = 0; 550 pu1_buf[-2] = 0; 551 pu1_buf[wd] = 0; 552 pu1_buf[wd + 1] = 0; 553 pu1_buf += strd; 554 } 555 pu1_buf = ps_pic_buf->pu1_chroma; 556 memset(pu1_buf - strd - 2, 0, wd + 4); 557 558 pu1_buf += strd * ht; 559 memset(pu1_buf - 2, 0, wd + 4); 560 } 561 562 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 563 564 565 if(0 != buf_ret) 566 { 567 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 568 return IHEVCD_BUF_MGR_ERROR; 569 } 570 ps_pic_buf++; 571 } 572 } 573 else 574 { 575 /* In case of shared mode, buffers are added without adjusting for padding. 576 Update luma and chroma pointers here to account for padding as per stride. 577 In some cases stride might not be available when set_display_frame is called. 578 Hence updated luma and chroma pointers here */ 579 580 for(i = 0; i < BUF_MGR_MAX_CNT; i++) 581 { 582 ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i); 583 if((NULL == ps_pic_buf) || 584 (NULL == ps_pic_buf->pu1_luma) || 585 (NULL == ps_pic_buf->pu1_chroma)) 586 { 587 break; 588 } 589 ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT; 590 ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT; 591 } 592 } 593 594 return ret; 595 } 596 /** 597 ******************************************************************************* 598 * 599 * @brief 600 * Function to add buffers to MV Bank buffer manager 601 * 602 * @par Description: 603 * Function to add buffers to MV Bank buffer manager 604 * To be called once per stream or for every reset 605 * 606 * @param[in] ps_codec 607 * Pointer to codec context 608 * 609 * @returns Error from IHEVCD_ERROR_T 610 * 611 * @remarks 612 * 613 * 614 ******************************************************************************* 615 */ 616 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec) 617 { 618 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 619 WORD32 i; 620 WORD32 max_dpb_size; 621 WORD32 mv_bank_size_allocated; 622 WORD32 pic_mv_bank_size; 623 624 sps_t *ps_sps; 625 UWORD8 *pu1_buf; 626 mv_buf_t *ps_mv_buf; 627 628 629 /* Initialize MV Bank buffer manager */ 630 ps_sps = ps_codec->s_parse.ps_sps; 631 632 633 /* Compute the number of MV Bank buffers needed */ 634 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 635 636 /* Allocate one extra MV Bank to handle current frame 637 * In case of asynchronous parsing and processing, number of buffers should increase here 638 * based on when parsing and processing threads are synchronized 639 */ 640 max_dpb_size++; 641 642 ps_codec->i4_max_dpb_size = max_dpb_size; 643 644 pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base; 645 646 ps_mv_buf = (mv_buf_t *)pu1_buf; 647 pu1_buf += max_dpb_size * sizeof(mv_buf_t); 648 ps_codec->ps_mv_buf = ps_mv_buf; 649 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size * sizeof(mv_buf_t); 650 651 /* Compute MV bank size per picture */ 652 pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 653 ALIGN64(ps_sps->i2_pic_height_in_luma_samples)); 654 655 for(i = 0; i < max_dpb_size; i++) 656 { 657 WORD32 buf_ret; 658 WORD32 num_pu; 659 WORD32 num_ctb; 660 WORD32 pic_size; 661 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 662 ALIGN64(ps_sps->i2_pic_height_in_luma_samples); 663 664 665 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 666 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 667 668 669 mv_bank_size_allocated -= pic_mv_bank_size; 670 671 if(mv_bank_size_allocated < 0) 672 { 673 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK; 674 return IHEVCD_INSUFFICIENT_MEM_MVBANK; 675 } 676 677 ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf; 678 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 679 680 ps_mv_buf->pu1_pic_pu_map = pu1_buf; 681 pu1_buf += num_pu; 682 683 ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf; 684 pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16)); 685 686 ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf; 687 pu1_buf += num_pu * sizeof(pu_t); 688 689 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i); 690 691 if(0 != buf_ret) 692 { 693 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 694 return IHEVCD_BUF_MGR_ERROR; 695 } 696 697 ps_mv_buf++; 698 699 } 700 return ret; 701 } 702 /** 703 ******************************************************************************* 704 * 705 * @brief 706 * Output buffer check 707 * 708 * @par Description: 709 * Check for the number of buffers and buffer sizes of output buffer 710 * 711 * @param[in] ps_codec 712 * Pointer to codec context 713 * 714 * @returns Error from IHEVCD_ERROR_T 715 * 716 * @remarks 717 * 718 * 719 ******************************************************************************* 720 */ 721 IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec) 722 { 723 ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer; 724 UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; 725 UWORD32 u4_min_num_out_bufs = 0, i; 726 UWORD32 wd, ht; 727 728 if(0 == ps_codec->i4_share_disp_buf) 729 { 730 wd = ps_codec->i4_disp_wd; 731 ht = ps_codec->i4_disp_ht; 732 } 733 else 734 { 735 /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */ 736 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 737 } 738 739 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 740 u4_min_num_out_bufs = MIN_OUT_BUFS_420; 741 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 742 u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 743 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 744 u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 745 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 746 u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 747 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 748 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 749 u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 750 751 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 752 { 753 au4_min_out_buf_size[0] = (wd * ht); 754 au4_min_out_buf_size[1] = (wd * ht) >> 2; 755 au4_min_out_buf_size[2] = (wd * ht) >> 2; 756 } 757 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 758 { 759 au4_min_out_buf_size[0] = (wd * ht) * 2; 760 au4_min_out_buf_size[1] = 761 au4_min_out_buf_size[2] = 0; 762 } 763 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 764 { 765 au4_min_out_buf_size[0] = (wd * ht) * 2; 766 au4_min_out_buf_size[1] = 767 au4_min_out_buf_size[2] = 0; 768 } 769 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 770 { 771 au4_min_out_buf_size[0] = (wd * ht) * 4; 772 au4_min_out_buf_size[1] = 773 au4_min_out_buf_size[2] = 0; 774 } 775 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 776 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 777 { 778 au4_min_out_buf_size[0] = (wd * ht); 779 au4_min_out_buf_size[1] = (wd * ht) >> 1; 780 au4_min_out_buf_size[2] = 0; 781 } 782 783 if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs) 784 { 785 return (IHEVCD_ERROR_T)IV_FAIL; 786 } 787 788 for (i = 0 ; i < u4_min_num_out_bufs; i++) 789 { 790 if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i]) 791 { 792 return (IHEVCD_ERROR_T)IV_FAIL; 793 } 794 } 795 796 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 797 } 798 799 /** 800 ******************************************************************************* 801 * 802 * @brief 803 * Picture level initializations required during parsing 804 * 805 * @par Description: 806 * Initialize picture level context variables during parsing Initialize mv 807 * bank buffer manager in the first init call 808 * 809 * @param[in] ps_codec 810 * Pointer to codec context 811 * 812 * @returns Error from IHEVCD_ERROR_T 813 * 814 * @remarks 815 * 816 * 817 ******************************************************************************* 818 */ 819 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) 820 { 821 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 822 mv_buf_t *ps_mv_buf; 823 sps_t *ps_sps; 824 WORD32 num_min_cu; 825 WORD32 cur_pic_buf_id; 826 WORD32 cur_mv_bank_buf_id; 827 pic_buf_t *ps_cur_pic; 828 slice_header_t *ps_slice_hdr; 829 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma; 830 WORD32 i; 831 832 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS; 833 ps_sps = ps_codec->s_parse.ps_sps; 834 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 835 836 /* Memset picture level intra map and transquant bypass map to zero */ 837 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64); 838 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu); 839 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu); 840 841 842 843 if(0 == ps_codec->s_parse.i4_first_pic_init) 844 { 845 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec); 846 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 847 848 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec); 849 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 850 851 ps_codec->s_parse.i4_first_pic_init = 1; 852 } 853 854 /* Output buffer check */ 855 ret = ihevcd_check_out_buf_size(ps_codec); 856 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 857 858 /* Initialize all the slice headers' slice addresses to zero */ 859 { 860 WORD32 slice_idx; 861 WORD32 slice_start_idx; 862 863 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1; 864 865 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++) 866 { 867 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx; 868 ps_slice_hdr_tmp->i2_ctb_x = -1; 869 ps_slice_hdr_tmp->i2_ctb_y = -1; 870 871 } 872 } 873 874 /* Get free MV Bank to hold current picture's motion vector data */ 875 { 876 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); 877 878 /* If there are no free buffers then return with an error code. 879 * If the buffer is to be freed by another thread , change the 880 * following to call thread yield and wait for buffer to be freed 881 */ 882 if(NULL == ps_mv_buf) 883 { 884 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK; 885 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK; 886 return IHEVCD_NO_FREE_MVBANK; 887 } 888 889 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf; 890 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer 891 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array 892 * and getting a buffer id to free 893 */ 894 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 895 } 896 897 /* Get free picture buffer to hold current picture recon data */ 898 /* TODO: For asynchronous api the following initializations related to picture 899 * buffer should be moved to processing side 900 */ 901 { 902 903 UWORD8 *pu1_buf; 904 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); 905 906 /* If there are no free buffers then return with an error code. 907 * TODO: If the buffer is to be freed by another thread , change the 908 * following to call thread yield and wait for buffer to be freed 909 */ 910 if(NULL == ps_cur_pic) 911 { 912 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF; 913 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF; 914 return IHEVCD_NO_FREE_PICBUF; 915 } 916 917 /* Store input timestamp sent with input buffer */ 918 ps_cur_pic->u4_ts = ps_codec->u4_ts; 919 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 920 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb; 921 pu1_buf = ps_cur_pic->pu1_luma; 922 pu1_cur_pic_luma = pu1_buf; 923 924 pu1_buf = ps_cur_pic->pu1_chroma; 925 926 pu1_cur_pic_chroma = pu1_buf; 927 928 ps_cur_pic->s_sei_params.i1_sei_parameters_present_flag = 0; 929 if(ps_codec->s_parse.s_sei_params.i1_sei_parameters_present_flag) 930 { 931 sei_params_t *ps_sei = &ps_codec->s_parse.s_sei_params; 932 ps_cur_pic->s_sei_params = ps_codec->s_parse.s_sei_params; 933 934 /* Once sei_params is copied to pic_buf, 935 * mark sei_params in s_parse as not present, 936 * this ensures that future frames do not use this data again. 937 */ 938 ps_sei->i1_sei_parameters_present_flag = 0; 939 ps_sei->i1_user_data_registered_present_flag = 0; 940 ps_sei->i1_aud_present_flag = 0; 941 ps_sei->i1_time_code_present_flag = 0; 942 ps_sei->i1_buf_period_params_present_flag = 0; 943 ps_sei->i1_pic_timing_params_present_flag = 0; 944 ps_sei->i1_recovery_point_params_present_flag = 0; 945 ps_sei->i1_active_parameter_set = 0; 946 ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags = 0; 947 } 948 } 949 950 if(0 == ps_codec->u4_pic_cnt) 951 { 952 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); 953 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); 954 } 955 956 /* Fill the remaining entries of the reference lists with the nearest POC 957 * This is done to handle cases where there is a corruption in the reference index */ 958 { 959 pic_buf_t *ps_pic_buf_ref; 960 mv_buf_t *ps_mv_buf_ref; 961 WORD32 r_idx; 962 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr; 963 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr; 964 965 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt); 966 if(NULL == ps_pic_buf_ref) 967 { 968 WORD32 size; 969 970 WORD32 num_pu; 971 WORD32 num_ctb; 972 WORD32 pic_size; 973 /* In case current mv buffer itself is being used as reference mv buffer for colocated 974 * calculations, then memset all the buffers to zero. 975 */ 976 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 977 ALIGN64(ps_sps->i2_pic_height_in_luma_samples); 978 979 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE); 980 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 981 982 memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc)); 983 memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt)); 984 memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc)); 985 memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt)); 986 987 size = (num_ctb + 1) * sizeof(WORD32); 988 memset(ps_mv_buf->pu4_pic_pu_idx, 0, size); 989 990 size = num_pu; 991 memset(ps_mv_buf->pu1_pic_pu_map, 0, size); 992 size = ALIGN4(num_ctb * sizeof(UWORD16)); 993 memset(ps_mv_buf->pu1_pic_slice_map, 0, size); 994 size = num_pu * sizeof(pu_t); 995 memset(ps_mv_buf->ps_pic_pu, 0, size); 996 997 ps_pic_buf_ref = ps_cur_pic; 998 ps_mv_buf_ref = ps_mv_buf; 999 } 1000 else 1001 { 1002 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc); 1003 } 1004 1005 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++) 1006 { 1007 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf) 1008 { 1009 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 1010 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 1011 } 1012 } 1013 1014 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++) 1015 { 1016 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 1017 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 1018 } 1019 1020 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++) 1021 { 1022 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf) 1023 { 1024 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 1025 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 1026 } 1027 } 1028 1029 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++) 1030 { 1031 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 1032 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 1033 } 1034 } 1035 1036 1037 /* Reset the jobq to start of the jobq buffer */ 1038 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq); 1039 1040 ps_codec->s_parse.i4_pic_pu_idx = 0; 1041 ps_codec->s_parse.i4_pic_tu_idx = 0; 1042 1043 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map; 1044 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu; 1045 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx; 1046 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 1047 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1048 { 1049 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 1050 } 1051 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 1052 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu; 1053 1054 { 1055 UWORD8 *pu1_buf; 1056 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt; 1057 WORD32 pic_size; 1058 WORD32 num_ctb; 1059 1060 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) * 1061 ALIGN64(ps_sps->i2_pic_height_in_luma_samples); 1062 1063 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE); 1064 1065 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1; 1066 1067 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt; 1068 1069 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 1070 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data; 1071 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf; 1072 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 1073 1074 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf; 1075 pu1_buf += ctb_min_tu_cnt; 1076 1077 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf; 1078 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t); 1079 1080 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf; 1081 1082 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 1083 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 1084 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 1085 } 1086 1087 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 1088 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 1089 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 1090 1091 1092 /* Set number of CTBs to be processed simultaneously */ 1093 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps); 1094 1095 /* Memset Parse Map and process map at the start of frame */ 1096 //TODO: In case of asynchronous API proc_map can not be set to zero here 1097 { 1098 WORD32 num_ctb; 1099 1100 num_ctb = ps_sps->i4_pic_size_in_ctb; 1101 1102 memset(ps_codec->pu1_parse_map, 0, num_ctb); 1103 1104 memset(ps_codec->pu1_proc_map, 0, num_ctb); 1105 } 1106 1107 1108 1109 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is 1110 * buffer to be displayed 1111 */ 1112 ps_codec->i4_disp_buf_id = -1; 1113 ps_codec->ps_disp_buf = NULL; 1114 1115 ps_codec->i4_disable_deblk_pic = 0; 1116 ps_codec->i4_disable_sao_pic = 0; 1117 ps_codec->i4_fullpel_inter_pred = 0; 1118 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF; 1119 1120 /* If degrade is enabled, set the degrade flags appropriately */ 1121 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics) 1122 { 1123 WORD32 degrade_pic; 1124 ps_codec->i4_degrade_pic_cnt++; 1125 degrade_pic = 0; 1126 1127 /* If degrade is to be done in all frames, then do not check further */ 1128 switch(ps_codec->i4_degrade_pics) 1129 { 1130 case 4: 1131 { 1132 degrade_pic = 1; 1133 break; 1134 } 1135 case 3: 1136 { 1137 if(ps_slice_hdr->i1_slice_type != ISLICE) 1138 degrade_pic = 1; 1139 1140 break; 1141 } 1142 case 2: 1143 { 1144 1145 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */ 1146 if((ps_slice_hdr->i1_slice_type != ISLICE) && 1147 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval)) 1148 degrade_pic = 1; 1149 1150 break; 1151 } 1152 case 1: 1153 { 1154 /* Check if the current picture is non-ref */ 1155 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1156 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1157 { 1158 degrade_pic = 1; 1159 } 1160 break; 1161 } 1162 1163 1164 } 1165 if(degrade_pic) 1166 { 1167 if(ps_codec->i4_degrade_type & 0x1) 1168 ps_codec->i4_disable_sao_pic = 1; 1169 1170 if(ps_codec->i4_degrade_type & 0x2) 1171 ps_codec->i4_disable_deblk_pic = 1; 1172 1173 /* MC degrading is done only for non-ref pictures */ 1174 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1175 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1176 { 1177 if(ps_codec->i4_degrade_type & 0x4) 1178 ps_codec->i4_mv_frac_mask = 0; 1179 1180 if(ps_codec->i4_degrade_type & 0x8) 1181 ps_codec->i4_mv_frac_mask = 0; 1182 } 1183 } 1184 else 1185 ps_codec->i4_degrade_pic_cnt = 0; 1186 } 1187 1188 1189 { 1190 WORD32 i; 1191 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1192 { 1193 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 1194 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 1195 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 1196 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 1197 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu; 1198 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 1199 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 1200 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id; 1201 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx; 1202 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx; 1203 1204 /* TODO: For asynchronous api the following initializations related to picture 1205 * buffer should be moved to processing side 1206 */ 1207 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma; 1208 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1209 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic; 1210 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id; 1211 1212 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer; 1213 if(1 < ps_codec->i4_num_cores) 1214 { 1215 ps_codec->as_process[i].i4_check_parse_status = 1; 1216 ps_codec->as_process[i].i4_check_proc_status = 1; 1217 } 1218 else 1219 { 1220 ps_codec->as_process[i].i4_check_parse_status = 0; 1221 ps_codec->as_process[i].i4_check_proc_status = 0; 1222 } 1223 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag; 1224 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1225 ps_codec->as_process[i].i4_init_done = 0; 1226 1227 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx; 1228 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx; 1229 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu; 1230 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1231 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1232 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1233 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1234 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1235 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1236 if(i < (ps_codec->i4_num_cores - 1)) 1237 { 1238 ithread_create(ps_codec->apv_process_thread_handle[i], NULL, 1239 (void *)ihevcd_process_thread, 1240 (void *)&ps_codec->as_process[i]); 1241 ps_codec->ai4_process_thread_created[i] = 1; 1242 } 1243 else 1244 { 1245 ps_codec->ai4_process_thread_created[i] = 0; 1246 } 1247 1248 } 1249 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1250 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1251 1252 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1253 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1254 } 1255 /* Since any input bitstream buffer that contains slice data will be sent to output(even in 1256 * case of error, this buffer is added to display queue and next buffer in the display queue 1257 * will be returned as the display buffer. 1258 * Note: If format conversion (or frame copy) is used and is scheduled 1259 * in a different thread then it has to check if the processing for the current row is complete before 1260 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be 1261 * returned, which requires a status check to ensure that the current row is reconstructed before copying. 1262 */ 1263 /* Add current picture to display manager */ 1264 { 1265 WORD32 abs_poc; 1266 slice_header_t *ps_slice_hdr; 1267 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 1268 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 1269 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, 1270 ps_codec->as_process[0].i4_cur_pic_buf_id, 1271 abs_poc, 1272 ps_codec->as_process[0].ps_cur_pic); 1273 } 1274 ps_codec->ps_disp_buf = NULL; 1275 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */ 1276 /* Since the current will be decoded, check is fore >= instead of > */ 1277 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]) || 1278 (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT)) 1279 1280 { 1281 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); 1282 ps_codec->u4_disp_cnt++; 1283 } 1284 1285 ps_codec->s_fmt_conv.i4_cur_row = 0; 1286 /* Set number of rows to be processed at a time */ 1287 ps_codec->s_fmt_conv.i4_num_rows = 4; 1288 1289 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1)) 1290 { 1291 process_ctxt_t *ps_proc; 1292 1293 /* i4_num_cores - 1 contexts are currently being used by other threads */ 1294 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 1295 1296 /* If the frame being decoded and displayed are different, schedule format conversion jobs 1297 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead 1298 * If the frame being decoded and displayed are same, then format conversion is scheduled later. 1299 */ 1300 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) && 1301 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt))) 1302 { 1303 1304 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++) 1305 { 1306 proc_job_t s_job; 1307 IHEVCD_ERROR_T ret; 1308 s_job.i4_cmd = CMD_FMTCONV; 1309 s_job.i2_ctb_cnt = 0; 1310 s_job.i2_ctb_x = 0; 1311 s_job.i2_ctb_y = i; 1312 s_job.i2_slice_idx = 0; 1313 s_job.i4_tu_coeff_data_ofst = 0; 1314 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, 1315 &s_job, sizeof(proc_job_t), 1); 1316 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 1317 return ret; 1318 } 1319 } 1320 } 1321 1322 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */ 1323 ps_codec->i4_pic_present = 1; 1324 1325 return ret; 1326 } 1327 1328 1329