Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2 *
      3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      4 *
      5 * Licensed under the Apache License, Version 2.0 (the "License");
      6 * you may not use this file except in compliance with the License.
      7 * You may obtain a copy of the License at:
      8 *
      9 * http://www.apache.org/licenses/LICENSE-2.0
     10 *
     11 * Unless required by applicable law or agreed to in writing, software
     12 * distributed under the License is distributed on an "AS IS" BASIS,
     13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 * See the License for the specific language governing permissions and
     15 * limitations under the License.
     16 *
     17 ******************************************************************************/
     18 /**
     19 *******************************************************************************
     20 * @file
     21 *  ihevcd_utils.c
     22 *
     23 * @brief
     24 *  Contains miscellaneous utility functions such as init() etc
     25 *
     26 * @author
     27 *  Harish
     28 *
     29 * @par List of Functions:
     30 *
     31 * @remarks
     32 *  None
     33 *
     34 *******************************************************************************
     35 */
     36 /*****************************************************************************/
     37 /* File Includes                                                             */
     38 /*****************************************************************************/
     39 #include <stdio.h>
     40 #include <stddef.h>
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <assert.h>
     44 
     45 #include "ihevc_typedefs.h"
     46 #include "iv.h"
     47 #include "ivd.h"
     48 #include "ihevcd_cxa.h"
     49 #include "ithread.h"
     50 
     51 #include "ihevc_defs.h"
     52 #include "ihevc_debug.h"
     53 #include "ihevc_defs.h"
     54 #include "ihevc_error.h"
     55 #include "ihevc_structs.h"
     56 #include "ihevc_buf_mgr.h"
     57 #include "ihevc_dpb_mgr.h"
     58 #include "ihevc_macros.h"
     59 #include "ihevc_platform_macros.h"
     60 
     61 #include "ihevc_common_tables.h"
     62 #include "ihevc_buf_mgr.h"
     63 #include "ihevc_disp_mgr.h"
     64 #include "ihevc_cabac_tables.h"
     65 
     66 #include "ihevcd_defs.h"
     67 
     68 #include "ihevcd_function_selector.h"
     69 #include "ihevcd_structs.h"
     70 #include "ihevcd_error.h"
     71 #include "ihevcd_nal.h"
     72 #include "ihevcd_bitstream.h"
     73 #include "ihevcd_utils.h"
     74 #include "ihevcd_trace.h"
     75 #include "ihevcd_process_slice.h"
     76 #include "ihevcd_job_queue.h"
     77 #define MAX_DPB_PIC_BUF 6
     78 
     79 /* Function declarations */
     80 mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc);
     81 
     82 /**
     83 *******************************************************************************
     84 *
     85 * @brief
     86 *  Used to get level index for a given level
     87 *
     88 * @par Description:
     89 *  Converts from level_idc (which is multiplied by 30) to an index that can be
     90 *  used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
     91 *
     92 * @param[in] level
     93 *  Level of the stream
     94 *
     95 * @returns  Level index for a given level
     96 *
     97 * @remarks
     98 *
     99 *
    100 *******************************************************************************
    101 */
    102 WORD32 ihevcd_get_lvl_idx(WORD32 level)
    103 {
    104     WORD32 lvl_idx = 0;
    105 
    106     if(level < IHEVC_LEVEL_20)
    107     {
    108         lvl_idx = 0;
    109     }
    110     else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
    111     {
    112         lvl_idx = 1;
    113     }
    114     else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
    115     {
    116         lvl_idx = 2;
    117     }
    118     else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
    119     {
    120         lvl_idx = 3;
    121     }
    122     else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
    123     {
    124         lvl_idx = 4;
    125     }
    126     else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
    127     {
    128         lvl_idx = 5;
    129     }
    130     else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
    131     {
    132         lvl_idx = 6;
    133     }
    134     else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
    135     {
    136         lvl_idx = 7;
    137     }
    138     else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
    139     {
    140         lvl_idx = 8;
    141     }
    142     else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
    143     {
    144         lvl_idx = 9;
    145     }
    146     else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
    147     {
    148         lvl_idx = 10;
    149     }
    150     else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
    151     {
    152         lvl_idx = 11;
    153     }
    154     else if(level >= IHEVC_LEVEL_62)
    155     {
    156         lvl_idx = 12;
    157     }
    158 
    159     return (lvl_idx);
    160 }
    161 
    162 /**
    163 *******************************************************************************
    164 *
    165 * @brief
    166 *  Used to get DPB size for a given level, and number of luma samples
    167 *
    168 * @par Description:
    169 *  For given width, height and level number of max_dpb_size is computed as per
    170 *  Annex A.4.1
    171 *
    172 * @param[in] level
    173 *  Level of the stream
    174 *
    175 * @param[in] pic_size
    176 *  Width * Height
    177 *
    178 * @returns  Number of buffers in DPB
    179 *
    180 * @remarks
    181 *
    182 *
    183 *******************************************************************************
    184 */
    185 WORD32 ihevcd_get_dpb_size(WORD32 level, WORD32 pic_size)
    186 {
    187 
    188     WORD32 max_luma_samples;
    189 
    190     WORD32 max_dpb_size;
    191     WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
    192     max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
    193 
    194 
    195 
    196     if(pic_size <= (max_luma_samples >> 2))
    197     {
    198         max_dpb_size = MIN(4 * MAX_DPB_PIC_BUF, 16);
    199     }
    200     else if(pic_size <= (max_luma_samples >> 1))
    201     {
    202         max_dpb_size = MIN(2 * MAX_DPB_PIC_BUF, 16);
    203     }
    204     else if(pic_size <= ((3 * max_luma_samples) >> 2))
    205     {
    206         max_dpb_size = MIN((4 * MAX_DPB_PIC_BUF) / 3, 16);
    207     }
    208     else
    209     {
    210         max_dpb_size = MAX_DPB_PIC_BUF;
    211     }
    212 
    213     return max_dpb_size;
    214 }
    215 /**
    216 *******************************************************************************
    217 *
    218 * @brief
    219 *  Used to get reference picture buffer size for a given level and
    220 *  and padding used
    221 *
    222 * @par Description:
    223 *  Used to get reference picture buffer size for a given level and padding used
    224 *  Each picture is padded on all four sides
    225 *
    226 * @param[in] pic_size
    227 *  Mumber of luma samples (Width * Height)
    228 *
    229 * @param[in] level
    230 *  Level
    231 *
    232 * @param[in] horz_pad
    233 *  Total padding used in horizontal direction
    234 *
    235 * @param[in] vert_pad
    236 *  Total padding used in vertical direction
    237 *
    238 * @returns  Total picture buffer size
    239 *
    240 * @remarks
    241 *
    242 *
    243 *******************************************************************************
    244 */
    245 WORD32 ihevcd_get_total_pic_buf_size(WORD32 pic_size,
    246                                      WORD32 level,
    247                                      WORD32 horz_pad,
    248                                      WORD32 vert_pad,
    249                                      WORD32 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 */
    348 WORD32 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 =  mv_bank_size;
    376     return size;
    377 }
    378 /**
    379 *******************************************************************************
    380 *
    381 * @brief
    382 *  Used to get TU data size for a given number luma samples
    383 *
    384 * @par Description:
    385 *  For a given number of luma samples TU data size is computed
    386 *  Each TU data includes tu_map and tu_t and coeff data for all
    387 *  the min TUs(4x4) in given CTB
    388 *
    389 * @param[in] num_luma_samples
    390 *  Number of 64 x 64 CTBs for which TU data has to be allocated.
    391 *
    392 * @returns  Total TU data size
    393 *
    394 * @remarks Assumption is num_luma_samples will be at least
    395 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
    396 *
    397 *******************************************************************************
    398 */
    399 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
    400 {
    401 
    402 
    403     WORD32 tu_data_size;
    404     WORD32 num_ctb;
    405     WORD32 num_luma_tu, num_chroma_tu, num_tu;
    406     num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    407 
    408     num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
    409     num_chroma_tu = num_luma_tu >> 1;
    410 
    411     num_tu = num_luma_tu + num_chroma_tu;
    412     tu_data_size = 0;
    413 
    414     /* Size for storing tu_t start index each CTB */
    415     /* One extra entry is needed to compute number of TUs in the last CTB */
    416     tu_data_size += (num_ctb + 1) * sizeof(WORD32);
    417 
    418     /* Size for storing tu map */
    419     tu_data_size += num_luma_tu * sizeof(UWORD8);
    420 
    421     /* Size for storing tu_t for each TU */
    422     tu_data_size += num_tu * sizeof(tu_t);
    423 
    424     /* Size for storing number of coded subblocks and scan_idx for each TU */
    425     tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
    426 
    427     /* Size for storing coeff data for each TU */
    428     tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
    429 
    430 
    431     return tu_data_size;
    432 }
    433 
    434 
    435 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
    436 {
    437     WORD32 nctb = 1;
    438     UNUSED(ps_codec);
    439     //TODO: Currently set to 1
    440     /* If CTB size is less than 32 x 32 then set nCTB as 4 */
    441     if(ps_sps->i1_log2_ctb_size < 5)
    442         nctb = 1;
    443 
    444     return nctb;
    445 }
    446 
    447 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
    448                                    sps_t *ps_sps,
    449                                    WORD32 ctb_x,
    450                                    WORD32 ctb_y,
    451                                    WORD32 *pi4_ctb_tile_x,
    452                                    WORD32 *pi4_ctb_tile_y,
    453                                    WORD32 *pi4_tile_idx)
    454 {
    455 
    456     tile_t *ps_tile_tmp;
    457     WORD32 i;
    458     WORD32 tile_row, tile_col;
    459 
    460     if(ctb_x < 0 || ctb_y < 0)
    461     {
    462         *pi4_ctb_tile_x = 0;
    463         *pi4_ctb_tile_y = 0;
    464         *pi4_tile_idx = 0;
    465 
    466         return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    467     }
    468 
    469     tile_row = 0;
    470     tile_col = 0;
    471     ps_tile_tmp = ps_pps->ps_tile;
    472     if(0 == ps_pps->i1_tiles_enabled_flag)
    473     {
    474         *pi4_ctb_tile_x = ctb_x;
    475         *pi4_ctb_tile_y = ctb_y;
    476         *pi4_tile_idx = 0;
    477     }
    478     else
    479     {
    480         for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
    481         {
    482             WORD16 next_tile_ctb_x;
    483             ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
    484             if((ps_pps->i1_num_tile_columns - 1) == i)
    485             {
    486                 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
    487             }
    488             else
    489             {
    490                 tile_t *ps_tile_next_tmp;
    491                 ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
    492                 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
    493             }
    494             if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
    495             {
    496                 tile_col = i;
    497                 break;
    498             }
    499         }
    500         *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
    501 
    502         for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
    503         {
    504             WORD16 next_tile_ctb_y;
    505             ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
    506             if((ps_pps->i1_num_tile_rows - 1) == i)
    507             {
    508                 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
    509             }
    510             else
    511             {
    512                 tile_t *ps_tile_next_tmp;
    513                 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
    514                 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
    515             }
    516             if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
    517             {
    518                 tile_row = i;
    519                 break;
    520             }
    521 
    522         }
    523         *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
    524         *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
    525                         + tile_col;
    526     }
    527     return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    528 }
    529 /**
    530 *******************************************************************************
    531 *
    532 * @brief
    533 *  Function to initialize ps_pic_buf structs add pic buffers to
    534 *  buffer manager in case of non-shared mode
    535 *
    536 * @par Description:
    537 *  Function to initialize ps_pic_buf structs add pic buffers to
    538 *  buffer manager in case of non-shared mode
    539 *  To be called once per stream or for every reset
    540 *
    541 * @param[in] ps_codec
    542 *  Pointer to codec context
    543 *
    544 * @returns  Error from IHEVCD_ERROR_T
    545 *
    546 * @remarks
    547 *
    548 *
    549 *******************************************************************************
    550 */
    551 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
    552 {
    553     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    554     WORD32 i;
    555     WORD32 max_dpb_size;
    556     sps_t *ps_sps;
    557     UWORD8 *pu1_buf;
    558     pic_buf_t *ps_pic_buf;
    559     WORD32 pic_buf_size_allocated;
    560 
    561     WORD32 max_num_bufs;
    562     WORD32 pic_size;
    563     WORD32 level;
    564 
    565 
    566     /* Initialize MV Bank buffer manager */
    567     ps_sps = ps_codec->s_parse.ps_sps;
    568 
    569     pic_size = ps_sps->i2_pic_width_in_luma_samples *
    570                     ps_sps->i2_pic_height_in_luma_samples;
    571 
    572 
    573     /* Compute the number of MB Bank buffers needed */
    574     level = ps_codec->i4_init_level;
    575     max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
    576     /* Allocate twice dpb size to handle worst case reorder without returning more
    577      * than one output per call
    578      */
    579     max_dpb_size *= 2;
    580     /* Allocate one extra picture to handle current frame
    581      * In case of asynchronous parsing and processing, number of buffers should increase here
    582      * based on when parsing and processing threads are synchronized
    583      */
    584     max_dpb_size++;
    585 
    586     /* If num_ref_frames and num_reorder_frmaes is specified
    587      * Use minimum value
    588      */
    589     max_num_bufs = MIN(max_dpb_size, (ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
    590 
    591 
    592     pu1_buf = (UWORD8 *)ps_codec->ps_pic_buf;
    593 
    594     ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
    595 
    596     pu1_buf += BUF_MGR_MAX_CNT  * sizeof(pic_buf_t);
    597 
    598     /* In case of non-shared mode, add picture buffers to buffer manager
    599      * In case of shared mode buffers are added in the run-time
    600      */
    601     if(0 == ps_codec->i4_share_disp_buf)
    602     {
    603         WORD32 buf_ret;
    604         WORD32 luma_samples;
    605         WORD32 chroma_samples;
    606         pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size -
    607                         BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
    608 
    609         luma_samples = (ps_codec->i4_strd) *
    610                         (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
    611 
    612         chroma_samples = luma_samples / 2;
    613 
    614         /* Try to add as many buffers as possible since memory is already allocated */
    615         /* If the number of buffers that can be added is less than max_num_bufs
    616          * return with an error.
    617          */
    618         for(i = 0; i < (2 * MAX_DPB_SIZE) + 1; i++)
    619         {
    620             pic_buf_size_allocated -= (luma_samples + chroma_samples);
    621 
    622             if(pic_buf_size_allocated < 0)
    623             {
    624                 if(i < max_num_bufs)
    625                 {
    626                     ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
    627                     return IHEVCD_INSUFFICIENT_MEM_PICBUF;
    628                 }
    629                 break;
    630             }
    631 
    632             ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
    633             pu1_buf += luma_samples;
    634 
    635             ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
    636             pu1_buf += chroma_samples;
    637 
    638             buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
    639 
    640             if(0 != buf_ret)
    641             {
    642                 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
    643                 return IHEVCD_BUF_MGR_ERROR;
    644             }
    645             ps_pic_buf++;
    646         }
    647     }
    648 
    649     return ret;
    650 }
    651 /**
    652 *******************************************************************************
    653 *
    654 * @brief
    655 *  Function to add buffers to MV Bank buffer manager
    656 *
    657 * @par Description:
    658 *  Function to add buffers to MV Bank buffer manager
    659 *  To be called once per stream or for every reset
    660 *
    661 * @param[in] ps_codec
    662 *  Pointer to codec context
    663 *
    664 * @returns  Error from IHEVCD_ERROR_T
    665 *
    666 * @remarks
    667 *
    668 *
    669 *******************************************************************************
    670 */
    671 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
    672 {
    673     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    674     WORD32 i;
    675     WORD32 max_dpb_size;
    676     WORD32 mv_bank_size_allocated;
    677     WORD32 pic_mv_bank_size;
    678     WORD32 level;
    679     sps_t *ps_sps;
    680     UWORD8 *pu1_buf;
    681     mv_buf_t *ps_mv_buf;
    682 
    683 
    684     /* Initialize MV Bank buffer manager */
    685     ps_sps = ps_codec->s_parse.ps_sps;
    686 
    687 
    688     /* Compute the number of MB Bank buffers needed */
    689     level = ps_codec->i4_init_level;
    690     max_dpb_size = ihevcd_get_dpb_size(level,
    691                                        ps_sps->i2_pic_width_in_luma_samples *
    692                                        ps_sps->i2_pic_height_in_luma_samples);
    693 
    694     /* Allocate one extra MV Bank to handle current frame
    695      * In case of asynchronous parsing and processing, number of buffers should increase here
    696      * based on when parsing and processing threads are synchronized
    697      */
    698     max_dpb_size++;
    699 
    700     pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
    701 
    702     ps_mv_buf = (mv_buf_t *)pu1_buf;
    703     pu1_buf += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
    704     ps_codec->ps_mv_buf = ps_mv_buf;
    705     mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
    706 
    707     /* Compute MV bank size per picture */
    708     pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ps_sps->i2_pic_width_in_luma_samples *
    709                                                    ps_sps->i2_pic_height_in_luma_samples);
    710 
    711     for(i = 0; i < max_dpb_size; i++)
    712     {
    713         WORD32 buf_ret;
    714         WORD32 num_pu;
    715         WORD32 num_ctb;
    716         WORD32 pic_size;
    717         pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
    718                         ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
    719 
    720 
    721         num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
    722         num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    723 
    724 
    725         mv_bank_size_allocated -= pic_mv_bank_size;
    726 
    727         if(mv_bank_size_allocated < 0)
    728         {
    729             ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
    730             return IHEVCD_INSUFFICIENT_MEM_MVBANK;
    731         }
    732 
    733         ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
    734         pu1_buf += (num_ctb + 1) * sizeof(WORD32);
    735 
    736         ps_mv_buf->pu1_pic_pu_map = pu1_buf;
    737         pu1_buf += num_pu;
    738 
    739         ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
    740         pu1_buf += num_ctb * sizeof(UWORD16);
    741 
    742         ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
    743 
    744         buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
    745 
    746         if(0 != buf_ret)
    747         {
    748             ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
    749             return IHEVCD_BUF_MGR_ERROR;
    750         }
    751         pu1_buf += pic_mv_bank_size;
    752         ps_mv_buf++;
    753 
    754     }
    755     return ret;
    756 }
    757 /**
    758 *******************************************************************************
    759 *
    760 * @brief
    761 *  Picture level initializations required during parsing
    762 *
    763 * @par Description:
    764 *  Initialize picture level context variables during parsing Initialize mv
    765 * bank buffer manager in the first init call
    766 *
    767 * @param[in] ps_codec
    768 *  Pointer to codec context
    769 *
    770 * @returns  Error from IHEVCD_ERROR_T
    771 *
    772 * @remarks
    773 *
    774 *
    775 *******************************************************************************
    776 */
    777 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
    778 {
    779     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    780     mv_buf_t *ps_mv_buf;
    781     sps_t *ps_sps;
    782     WORD32 num_min_cu;
    783     WORD32 cur_pic_buf_id;
    784     WORD32 cur_mv_bank_buf_id;
    785     pic_buf_t *ps_cur_pic;
    786     slice_header_t *ps_slice_hdr;
    787     UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
    788     WORD32 i;
    789 
    790     ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
    791     ps_sps = ps_codec->s_parse.ps_sps;
    792     ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
    793     /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
    794     ps_codec->i4_pic_present = 1;
    795 
    796     /* Memset picture level intra map and transquant bypass map to zero */
    797     num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
    798     memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
    799     memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
    800 
    801 
    802 
    803     if(0 == ps_codec->s_parse.i4_first_pic_init)
    804     {
    805         ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
    806         RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    807 
    808         ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
    809         RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    810 
    811         ps_codec->s_parse.i4_first_pic_init = 1;
    812     }
    813 
    814     /* Initialize all the slice headers' slice addresses to zero */
    815     {
    816         WORD32 slice_idx;
    817         WORD32 slice_start_idx;
    818 
    819         slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
    820 
    821         for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
    822         {
    823             slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
    824             ps_slice_hdr_tmp->i2_ctb_x = -1;
    825             ps_slice_hdr_tmp->i2_ctb_y = -1;
    826 
    827         }
    828     }
    829 
    830     /* Get free MV Bank to hold current picture's motion vector data */
    831     {
    832         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);
    833 
    834         /* If there are no free buffers then return with an error code.
    835          * If the buffer is to be freed by another thread , change the
    836          * following to call thread yield and wait for buffer to be freed
    837          */
    838         if(NULL == ps_mv_buf)
    839         {
    840             ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
    841             ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
    842             return IHEVCD_NO_FREE_MVBANK;
    843         }
    844 
    845         ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
    846         /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
    847          * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
    848          * and getting a buffer id to free
    849          */
    850         ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    851     }
    852 
    853     /* Get free picture buffer to hold current picture recon data */
    854     /* TODO: For asynchronous api the following initializations related to picture
    855      * buffer should be moved to processing side
    856      */
    857     {
    858 
    859         UWORD8 *pu1_buf;
    860         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);
    861 
    862         /* If there are no free buffers then return with an error code.
    863          * TODO: If the buffer is to be freed by another thread , change the
    864          * following to call thread yield and wait for buffer to be freed
    865          */
    866         if(NULL == ps_cur_pic)
    867         {
    868             ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
    869             ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
    870             return IHEVCD_NO_FREE_PICBUF;
    871         }
    872 
    873         /* Store input timestamp sent with input buffer */
    874         ps_cur_pic->u4_ts = ps_codec->u4_ts;
    875         ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    876         ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
    877         pu1_buf = ps_cur_pic->pu1_luma;
    878         pu1_cur_pic_luma = pu1_buf;
    879 
    880         pu1_buf = ps_cur_pic->pu1_chroma;
    881 
    882         pu1_cur_pic_chroma = pu1_buf;
    883     }
    884 
    885     if(0 == ps_codec->u4_pic_cnt)
    886     {
    887         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);
    888         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);
    889     }
    890 
    891     /* Fill the remaining entries of the reference lists with the nearest POC
    892      * This is done to handle cases where there is a corruption in the reference index */
    893     {
    894         pic_buf_t *ps_pic_buf_ref;
    895         mv_buf_t *ps_mv_buf_ref;
    896         WORD32 r_idx;
    897         dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
    898         buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
    899 
    900         ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
    901         if(NULL == ps_pic_buf_ref)
    902         {
    903             ps_pic_buf_ref = ps_cur_pic;
    904             ps_mv_buf_ref = ps_mv_buf;
    905         }
    906         else
    907         {
    908             ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
    909         }
    910 
    911         for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
    912         {
    913             if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
    914             {
    915                 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
    916                 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
    917             }
    918         }
    919 
    920         for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
    921         {
    922             ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
    923             ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
    924         }
    925 
    926         for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
    927         {
    928             if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
    929             {
    930                 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
    931                 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
    932             }
    933         }
    934 
    935         for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
    936         {
    937             ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
    938             ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
    939         }
    940     }
    941 
    942 
    943     /* Reset the jobq to start of the jobq buffer */
    944     ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
    945 
    946     ps_codec->s_parse.i4_pic_pu_idx = 0;
    947     ps_codec->s_parse.i4_pic_tu_idx = 0;
    948 
    949     ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
    950     ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
    951     ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
    952     ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
    953     for(i = 0; i < MAX_PROCESS_THREADS; i++)
    954     {
    955         ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
    956     }
    957     ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
    958     ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
    959 
    960     {
    961         UWORD8 *pu1_buf;
    962         WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
    963         WORD32 pic_size;
    964         WORD32 num_ctb;
    965 
    966         pic_size = ps_sps->i2_pic_width_in_luma_samples *
    967                         ps_sps->i2_pic_height_in_luma_samples;
    968 
    969         ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
    970 
    971         ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
    972 
    973         ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
    974 
    975         num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    976         pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
    977         ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
    978         pu1_buf += (num_ctb + 1) * sizeof(WORD32);
    979 
    980         ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
    981         pu1_buf += ctb_min_tu_cnt;
    982 
    983         ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
    984         pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
    985 
    986         ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
    987 
    988         ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
    989         ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
    990         ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
    991     }
    992 
    993     ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
    994     ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
    995     ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
    996 
    997 
    998     /* Set number of CTBs to be processed simultaneously */
    999     ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
   1000 
   1001     /* Memset Parse Map and process map at the start of frame */
   1002     //TODO: In case of asynchronous API proc_map can not be set to zero here
   1003     {
   1004         WORD32 num_ctb;
   1005 
   1006         num_ctb = ps_sps->i4_pic_size_in_ctb;
   1007 
   1008         memset(ps_codec->pu1_parse_map, 0, num_ctb);
   1009 
   1010         memset(ps_codec->pu1_proc_map, 0, num_ctb);
   1011     }
   1012 
   1013 
   1014 
   1015     /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
   1016      * buffer to be displayed
   1017      */
   1018     ps_codec->i4_disp_buf_id = -1;
   1019     ps_codec->ps_disp_buf = NULL;
   1020 
   1021     ps_codec->i4_disable_deblk_pic  = 0;
   1022     ps_codec->i4_disable_sao_pic    = 0;
   1023     ps_codec->i4_fullpel_inter_pred = 0;
   1024     ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;
   1025 
   1026     /* If degrade is enabled, set the degrade flags appropriately */
   1027     if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
   1028     {
   1029         WORD32 degrade_pic;
   1030         ps_codec->i4_degrade_pic_cnt++;
   1031         degrade_pic = 0;
   1032 
   1033         /* If degrade is to be done in all frames, then do not check further */
   1034         switch(ps_codec->i4_degrade_pics)
   1035         {
   1036             case 4:
   1037             {
   1038                 degrade_pic = 1;
   1039                 break;
   1040             }
   1041             case 3:
   1042             {
   1043                 if(ps_slice_hdr->i1_slice_type != ISLICE)
   1044                     degrade_pic = 1;
   1045 
   1046                 break;
   1047             }
   1048             case 2:
   1049             {
   1050 
   1051                 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
   1052                 if((ps_slice_hdr->i1_slice_type != ISLICE) &&
   1053                    (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
   1054                     degrade_pic = 1;
   1055 
   1056                 break;
   1057             }
   1058             case 1:
   1059             {
   1060                 /* Check if the current picture is non-ref */
   1061                 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
   1062                    (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
   1063                 {
   1064                     degrade_pic = 1;
   1065                 }
   1066                 break;
   1067             }
   1068 
   1069 
   1070         }
   1071         if(degrade_pic)
   1072         {
   1073             if(ps_codec->i4_degrade_type & 0x1)
   1074                 ps_codec->i4_disable_sao_pic = 1;
   1075 
   1076             if(ps_codec->i4_degrade_type & 0x2)
   1077                 ps_codec->i4_disable_deblk_pic = 1;
   1078 
   1079             /* MC degrading is done only for non-ref pictures */
   1080             if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
   1081                (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
   1082             {
   1083                 if(ps_codec->i4_degrade_type & 0x4)
   1084                     ps_codec->i4_mv_frac_mask = 0;
   1085 
   1086                 if(ps_codec->i4_degrade_type & 0x8)
   1087                     ps_codec->i4_mv_frac_mask = 0;
   1088             }
   1089         }
   1090         else
   1091             ps_codec->i4_degrade_pic_cnt = 0;
   1092     }
   1093 
   1094 
   1095     {
   1096         WORD32 i;
   1097         for(i = 0; i < MAX_PROCESS_THREADS; i++)
   1098         {
   1099             ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
   1100             ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
   1101             ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
   1102             ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
   1103             ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
   1104             ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
   1105             ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
   1106             ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
   1107             ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
   1108             ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
   1109 
   1110             /* TODO: For asynchronous api the following initializations related to picture
   1111              * buffer should be moved to processing side
   1112              */
   1113             ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
   1114             ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1115             ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
   1116             ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
   1117 
   1118             ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
   1119             if(1 < ps_codec->i4_num_cores)
   1120             {
   1121                 ps_codec->as_process[i].i4_check_parse_status = 1;
   1122                 ps_codec->as_process[i].i4_check_proc_status = 1;
   1123             }
   1124             else
   1125             {
   1126                 ps_codec->as_process[i].i4_check_parse_status = 0;
   1127                 ps_codec->as_process[i].i4_check_proc_status = 0;
   1128             }
   1129             ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
   1130             ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1131             ps_codec->as_process[i].i4_init_done = 0;
   1132 
   1133             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
   1134             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
   1135             ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
   1136             ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1137             ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1138             ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1139             ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1140             ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1141             ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1142             if(i < (ps_codec->i4_num_cores - 1))
   1143             {
   1144                 ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
   1145                                (void *)ihevcd_process_thread,
   1146                                (void *)&ps_codec->as_process[i]);
   1147                 ps_codec->ai4_process_thread_created[i] = 1;
   1148             }
   1149             else
   1150             {
   1151                 ps_codec->ai4_process_thread_created[i] = 0;
   1152             }
   1153 
   1154         }
   1155         ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1156         ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1157 
   1158         ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1159         ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1160     }
   1161     /* Since any input bitstream buffer that contains slice data will be sent to output(even in
   1162      * case of error, this buffer is added to display queue and next buffer in the display queue
   1163      * will be returned as the display buffer.
   1164      * Note: If format conversion (or frame copy) is used and is scheduled
   1165      * in a different thread then it has to check if the processing for the current row is complete before
   1166      * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
   1167      * returned, which requires a status check to ensure that the current row is reconstructed before copying.
   1168      */
   1169     /* Add current picture to display manager */
   1170     {
   1171         WORD32 abs_poc;
   1172         slice_header_t *ps_slice_hdr;
   1173         ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
   1174         abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
   1175         ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
   1176                            ps_codec->as_process[0].i4_cur_pic_buf_id,
   1177                            abs_poc,
   1178                            ps_codec->as_process[0].ps_cur_pic);
   1179     }
   1180     ps_codec->ps_disp_buf = NULL;
   1181     /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
   1182     /* Since the current will be decoded, check is fore >= instead of > */
   1183     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]) ||
   1184        ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder))
   1185 
   1186     {
   1187         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);
   1188         ps_codec->u4_disp_cnt++;
   1189     }
   1190 
   1191     ps_codec->s_fmt_conv.i4_cur_row = 0;
   1192     /* Set number of rows to be processed at a time */
   1193     ps_codec->s_fmt_conv.i4_num_rows = 4;
   1194 
   1195     if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
   1196     {
   1197         process_ctxt_t *ps_proc;
   1198 
   1199         /* i4_num_cores - 1 contexts are currently being used by other threads */
   1200         ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
   1201 
   1202         /* If the frame being decoded and displayed are different, schedule format conversion jobs
   1203          * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
   1204          * If the frame being decoded and displayed are same, then format conversion is scheduled later.
   1205          */
   1206         if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
   1207            ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
   1208         {
   1209 
   1210             for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
   1211             {
   1212                 proc_job_t s_job;
   1213                 IHEVCD_ERROR_T ret;
   1214                 s_job.i4_cmd = CMD_FMTCONV;
   1215                 s_job.i2_ctb_cnt = 0;
   1216                 s_job.i2_ctb_x = 0;
   1217                 s_job.i2_ctb_y = i;
   1218                 s_job.i2_slice_idx = 0;
   1219                 s_job.i4_tu_coeff_data_ofst = 0;
   1220                 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
   1221                                         &s_job, sizeof(proc_job_t), 1);
   1222                 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
   1223                     return ret;
   1224             }
   1225         }
   1226     }
   1227 
   1228 
   1229     return ret;
   1230 }
   1231 
   1232 
   1233