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