ihevcd_utils.c revision b3a53cebdb51e50fe7ddd670b306271268f19d18
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 = ps_sps->i2_pic_width_in_luma_samples * 573 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 ps_sps->i2_pic_width_in_luma_samples * 695 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(ps_sps->i2_pic_width_in_luma_samples * 712 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 747 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i); 748 749 if(0 != buf_ret) 750 { 751 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR; 752 return IHEVCD_BUF_MGR_ERROR; 753 } 754 pu1_buf += pic_mv_bank_size; 755 ps_mv_buf++; 756 757 } 758 return ret; 759} 760/** 761******************************************************************************* 762* 763* @brief 764* Picture level initializations required during parsing 765* 766* @par Description: 767* Initialize picture level context variables during parsing Initialize mv 768* bank buffer manager in the first init call 769* 770* @param[in] ps_codec 771* Pointer to codec context 772* 773* @returns Error from IHEVCD_ERROR_T 774* 775* @remarks 776* 777* 778******************************************************************************* 779*/ 780IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) 781{ 782 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 783 mv_buf_t *ps_mv_buf; 784 sps_t *ps_sps; 785 WORD32 num_min_cu; 786 WORD32 cur_pic_buf_id; 787 WORD32 cur_mv_bank_buf_id; 788 pic_buf_t *ps_cur_pic; 789 slice_header_t *ps_slice_hdr; 790 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma; 791 WORD32 i; 792 793 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS; 794 ps_sps = ps_codec->s_parse.ps_sps; 795 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 796 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */ 797 ps_codec->i4_pic_present = 1; 798 799 /* Memset picture level intra map and transquant bypass map to zero */ 800 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64); 801 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu); 802 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu); 803 804 805 806 if(0 == ps_codec->s_parse.i4_first_pic_init) 807 { 808 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec); 809 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 810 811 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec); 812 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 813 814 ps_codec->s_parse.i4_first_pic_init = 1; 815 } 816 817 /* Initialize all the slice headers' slice addresses to zero */ 818 { 819 WORD32 slice_idx; 820 WORD32 slice_start_idx; 821 822 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1; 823 824 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++) 825 { 826 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx; 827 ps_slice_hdr_tmp->i2_ctb_x = -1; 828 ps_slice_hdr_tmp->i2_ctb_y = -1; 829 830 } 831 } 832 833 /* Get free MV Bank to hold current picture's motion vector data */ 834 { 835 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); 836 837 /* If there are no free buffers then return with an error code. 838 * If the buffer is to be freed by another thread , change the 839 * following to call thread yield and wait for buffer to be freed 840 */ 841 if(NULL == ps_mv_buf) 842 { 843 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK; 844 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK; 845 return IHEVCD_NO_FREE_MVBANK; 846 } 847 848 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf; 849 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer 850 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array 851 * and getting a buffer id to free 852 */ 853 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 854 } 855 856 /* Get free picture buffer to hold current picture recon data */ 857 /* TODO: For asynchronous api the following initializations related to picture 858 * buffer should be moved to processing side 859 */ 860 { 861 862 UWORD8 *pu1_buf; 863 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); 864 865 /* If there are no free buffers then return with an error code. 866 * TODO: If the buffer is to be freed by another thread , change the 867 * following to call thread yield and wait for buffer to be freed 868 */ 869 if(NULL == ps_cur_pic) 870 { 871 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF; 872 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF; 873 return IHEVCD_NO_FREE_PICBUF; 874 } 875 876 /* Store input timestamp sent with input buffer */ 877 ps_cur_pic->u4_ts = ps_codec->u4_ts; 878 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 879 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb; 880 pu1_buf = ps_cur_pic->pu1_luma; 881 pu1_cur_pic_luma = pu1_buf; 882 883 pu1_buf = ps_cur_pic->pu1_chroma; 884 885 pu1_cur_pic_chroma = pu1_buf; 886 } 887 888 if(0 == ps_codec->u4_pic_cnt) 889 { 890 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); 891 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); 892 } 893 894 /* Fill the remaining entries of the reference lists with the nearest POC 895 * This is done to handle cases where there is a corruption in the reference index */ 896 { 897 pic_buf_t *ps_pic_buf_ref; 898 mv_buf_t *ps_mv_buf_ref; 899 WORD32 r_idx; 900 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr; 901 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr; 902 903 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt); 904 if(NULL == ps_pic_buf_ref) 905 { 906 ps_pic_buf_ref = ps_cur_pic; 907 ps_mv_buf_ref = ps_mv_buf; 908 } 909 else 910 { 911 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc); 912 } 913 914 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++) 915 { 916 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf) 917 { 918 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 919 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 920 } 921 } 922 923 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++) 924 { 925 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 926 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 927 } 928 929 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++) 930 { 931 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf) 932 { 933 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 934 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 935 } 936 } 937 938 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++) 939 { 940 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref; 941 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref; 942 } 943 } 944 945 946 /* Reset the jobq to start of the jobq buffer */ 947 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq); 948 949 ps_codec->s_parse.i4_pic_pu_idx = 0; 950 ps_codec->s_parse.i4_pic_tu_idx = 0; 951 952 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map; 953 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu; 954 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx; 955 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 956 for(i = 0; i < MAX_PROCESS_THREADS; i++) 957 { 958 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map; 959 } 960 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 961 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu; 962 963 { 964 UWORD8 *pu1_buf; 965 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt; 966 WORD32 pic_size; 967 WORD32 num_ctb; 968 969 pic_size = ps_sps->i2_pic_width_in_luma_samples * 970 ps_sps->i2_pic_height_in_luma_samples; 971 972 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE); 973 974 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1; 975 976 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt; 977 978 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE); 979 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data; 980 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf; 981 pu1_buf += (num_ctb + 1) * sizeof(WORD32); 982 983 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf; 984 pu1_buf += ctb_min_tu_cnt; 985 986 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf; 987 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t); 988 989 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf; 990 991 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 992 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu; 993 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 994 } 995 996 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 997 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 998 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 999 1000 1001 /* Set number of CTBs to be processed simultaneously */ 1002 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps); 1003 1004 /* Memset Parse Map and process map at the start of frame */ 1005 //TODO: In case of asynchronous API proc_map can not be set to zero here 1006 { 1007 WORD32 num_ctb; 1008 1009 num_ctb = ps_sps->i4_pic_size_in_ctb; 1010 1011 memset(ps_codec->pu1_parse_map, 0, num_ctb); 1012 1013 memset(ps_codec->pu1_proc_map, 0, num_ctb); 1014 } 1015 1016 1017 1018 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is 1019 * buffer to be displayed 1020 */ 1021 ps_codec->i4_disp_buf_id = -1; 1022 ps_codec->ps_disp_buf = NULL; 1023 1024 ps_codec->i4_disable_deblk_pic = 0; 1025 ps_codec->i4_disable_sao_pic = 0; 1026 ps_codec->i4_fullpel_inter_pred = 0; 1027 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF; 1028 1029 /* If degrade is enabled, set the degrade flags appropriately */ 1030 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics) 1031 { 1032 WORD32 degrade_pic; 1033 ps_codec->i4_degrade_pic_cnt++; 1034 degrade_pic = 0; 1035 1036 /* If degrade is to be done in all frames, then do not check further */ 1037 switch(ps_codec->i4_degrade_pics) 1038 { 1039 case 4: 1040 { 1041 degrade_pic = 1; 1042 break; 1043 } 1044 case 3: 1045 { 1046 if(ps_slice_hdr->i1_slice_type != ISLICE) 1047 degrade_pic = 1; 1048 1049 break; 1050 } 1051 case 2: 1052 { 1053 1054 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */ 1055 if((ps_slice_hdr->i1_slice_type != ISLICE) && 1056 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval)) 1057 degrade_pic = 1; 1058 1059 break; 1060 } 1061 case 1: 1062 { 1063 /* Check if the current picture is non-ref */ 1064 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1065 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1066 { 1067 degrade_pic = 1; 1068 } 1069 break; 1070 } 1071 1072 1073 } 1074 if(degrade_pic) 1075 { 1076 if(ps_codec->i4_degrade_type & 0x1) 1077 ps_codec->i4_disable_sao_pic = 1; 1078 1079 if(ps_codec->i4_degrade_type & 0x2) 1080 ps_codec->i4_disable_deblk_pic = 1; 1081 1082 /* MC degrading is done only for non-ref pictures */ 1083 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) && 1084 (ps_slice_hdr->i1_nal_unit_type % 2 == 0)) 1085 { 1086 if(ps_codec->i4_degrade_type & 0x4) 1087 ps_codec->i4_mv_frac_mask = 0; 1088 1089 if(ps_codec->i4_degrade_type & 0x8) 1090 ps_codec->i4_mv_frac_mask = 0; 1091 } 1092 } 1093 else 1094 ps_codec->i4_degrade_pic_cnt = 0; 1095 } 1096 1097 1098 { 1099 WORD32 i; 1100 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1101 { 1102 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx; 1103 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu; 1104 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map; 1105 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx; 1106 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu; 1107 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map; 1108 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data; 1109 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id; 1110 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx; 1111 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx; 1112 1113 /* TODO: For asynchronous api the following initializations related to picture 1114 * buffer should be moved to processing side 1115 */ 1116 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma; 1117 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1118 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic; 1119 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id; 1120 1121 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer; 1122 if(1 < ps_codec->i4_num_cores) 1123 { 1124 ps_codec->as_process[i].i4_check_parse_status = 1; 1125 ps_codec->as_process[i].i4_check_proc_status = 1; 1126 } 1127 else 1128 { 1129 ps_codec->as_process[i].i4_check_parse_status = 0; 1130 ps_codec->as_process[i].i4_check_proc_status = 0; 1131 } 1132 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag; 1133 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1134 ps_codec->as_process[i].i4_init_done = 0; 1135 1136 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx; 1137 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx; 1138 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu; 1139 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1140 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1141 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1142 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag; 1143 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1144 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1145 if(i < (ps_codec->i4_num_cores - 1)) 1146 { 1147 ithread_create(ps_codec->apv_process_thread_handle[i], NULL, 1148 (void *)ihevcd_process_thread, 1149 (void *)&ps_codec->as_process[i]); 1150 ps_codec->ai4_process_thread_created[i] = 1; 1151 } 1152 else 1153 { 1154 ps_codec->ai4_process_thread_created[i] = 0; 1155 } 1156 1157 } 1158 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1159 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1160 1161 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; 1162 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; 1163 } 1164 /* Since any input bitstream buffer that contains slice data will be sent to output(even in 1165 * case of error, this buffer is added to display queue and next buffer in the display queue 1166 * will be returned as the display buffer. 1167 * Note: If format conversion (or frame copy) is used and is scheduled 1168 * in a different thread then it has to check if the processing for the current row is complete before 1169 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be 1170 * returned, which requires a status check to ensure that the current row is reconstructed before copying. 1171 */ 1172 /* Add current picture to display manager */ 1173 { 1174 WORD32 abs_poc; 1175 slice_header_t *ps_slice_hdr; 1176 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr; 1177 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt; 1178 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, 1179 ps_codec->as_process[0].i4_cur_pic_buf_id, 1180 abs_poc, 1181 ps_codec->as_process[0].ps_cur_pic); 1182 } 1183 ps_codec->ps_disp_buf = NULL; 1184 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */ 1185 /* Since the current will be decoded, check is fore >= instead of > */ 1186 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]) || 1187 ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder)) 1188 1189 { 1190 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); 1191 ps_codec->u4_disp_cnt++; 1192 } 1193 1194 ps_codec->s_fmt_conv.i4_cur_row = 0; 1195 /* Set number of rows to be processed at a time */ 1196 ps_codec->s_fmt_conv.i4_num_rows = 4; 1197 1198 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1)) 1199 { 1200 process_ctxt_t *ps_proc; 1201 1202 /* i4_num_cores - 1 contexts are currently being used by other threads */ 1203 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 1204 1205 /* If the frame being decoded and displayed are different, schedule format conversion jobs 1206 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead 1207 * If the frame being decoded and displayed are same, then format conversion is scheduled later. 1208 */ 1209 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) && 1210 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt))) 1211 { 1212 1213 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++) 1214 { 1215 proc_job_t s_job; 1216 IHEVCD_ERROR_T ret; 1217 s_job.i4_cmd = CMD_FMTCONV; 1218 s_job.i2_ctb_cnt = 0; 1219 s_job.i2_ctb_x = 0; 1220 s_job.i2_ctb_y = i; 1221 s_job.i2_slice_idx = 0; 1222 s_job.i4_tu_coeff_data_ofst = 0; 1223 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, 1224 &s_job, sizeof(proc_job_t), 1); 1225 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 1226 return ret; 1227 } 1228 } 1229 } 1230 1231 1232 return ret; 1233} 1234 1235 1236