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