Home | History | Annotate | Download | only in encoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2018 The Android Open Source Project
      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  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 
     21 /**
     22 ******************************************************************************
     23 * @file
     24 *  ihevce_lap_interface.c
     25 *
     26 * @brief
     27 *  This file contains function definitions related to look-ahead processing
     28 *
     29 * @author
     30 *  ittiam
     31 *
     32 * @par List of Functions:
     33 *
     34 ******************************************************************************
     35 */
     36 
     37 /*****************************************************************************/
     38 /* File Includes                                                             */
     39 /*****************************************************************************/
     40 
     41 /* System Include Files */
     42 #include <stdio.h>
     43 #include <string.h>
     44 #include <stdlib.h>
     45 #include <assert.h>
     46 
     47 /* User Include Files */
     48 #include "ihevc_typedefs.h"
     49 #include "itt_video_api.h"
     50 #include "ihevce_api.h"
     51 
     52 #include "rc_cntrl_param.h"
     53 #include "rc_frame_info_collector.h"
     54 #include "rc_look_ahead_params.h"
     55 
     56 #include "ihevc_defs.h"
     57 #include "ihevc_macros.h"
     58 #include "ihevc_debug.h"
     59 #include "ihevc_structs.h"
     60 #include "ihevc_platform_macros.h"
     61 #include "ihevc_deblk.h"
     62 #include "ihevc_itrans_recon.h"
     63 #include "ihevc_chroma_itrans_recon.h"
     64 #include "ihevc_chroma_intra_pred.h"
     65 #include "ihevc_intra_pred.h"
     66 #include "ihevc_inter_pred.h"
     67 #include "ihevc_mem_fns.h"
     68 #include "ihevc_padding.h"
     69 #include "ihevc_weighted_pred.h"
     70 #include "ihevc_sao.h"
     71 #include "ihevc_resi_trans.h"
     72 #include "ihevc_quant_iquant_ssd.h"
     73 #include "ihevc_cabac_tables.h"
     74 
     75 #include "ihevce_defs.h"
     76 #include "ihevce_api.h"
     77 #include "ihevce_hle_interface.h"
     78 #include "ihevce_hle_q_func.h"
     79 #include "ihevce_lap_enc_structs.h"
     80 #include "ihevce_lap_interface.h"
     81 #include "ihevce_lap_structs.h"
     82 #include "ihevce_multi_thrd_structs.h"
     83 #include "ihevce_function_selector.h"
     84 #include "ihevce_me_common_defs.h"
     85 #include "ihevce_enc_structs.h"
     86 #include "ihevce_rc_enc_structs.h"
     87 #include "ihevce_rc_interface.h"
     88 #include "ihevce_buffer_que_interface.h"
     89 
     90 /*****************************************************************************/
     91 /* Globals                                                                   */
     92 /*****************************************************************************/
     93 WORD32 gau1_order_insert_pic_type[MAX_TEMPORAL_LAYERS][8] = {
     94     { P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC },
     95     { P_PIC, B_PIC, B1_PIC, B1_PIC, P_PIC, B_PIC, B1_PIC, B1_PIC },
     96     { P_PIC, B_PIC, B1_PIC, B2_PIC, B2_PIC, B1_PIC, B2_PIC, B2_PIC },
     97 };
     98 
     99 UWORD8 gau1_use_by_cur_pic_flag[MAX_REF_PICS] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
    100 
    101 /*****************************************************************************/
    102 /* Function Definitions                                                      */
    103 /*****************************************************************************/
    104 
    105 /*!
    106 ************************************************************************
    107 * \brief
    108 *    return number of records used by LAP
    109 *
    110 ************************************************************************
    111 */
    112 WORD32 ihevce_lap_get_num_mem_recs(void)
    113 {
    114     return (NUM_LAP_MEM_RECS);
    115 }
    116 
    117 /*!
    118 ************************************************************************
    119 * @brief
    120 *    return each record attributes of LAP
    121 ************************************************************************
    122 */
    123 WORD32 ihevce_lap_get_mem_recs(iv_mem_rec_t *ps_mem_tab, WORD32 i4_mem_space)
    124 {
    125     /* number of NODE memory */
    126     WORD32 max_nodes = MAX_SUB_GOP_SIZE - 1;
    127 
    128     ps_mem_tab[LAP_CTXT].i4_mem_size = sizeof(lap_struct_t);
    129     ps_mem_tab[LAP_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
    130     ps_mem_tab[LAP_CTXT].i4_mem_alignment = 8;
    131 
    132     /* Node memory for 2 sub-gops*/
    133     ps_mem_tab[LAP_NODE_MEM].i4_mem_size = (max_nodes * sizeof(ihevce_encode_node_t));
    134 
    135     ps_mem_tab[LAP_NODE_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
    136 
    137     ps_mem_tab[LAP_NODE_MEM].i4_mem_alignment = 8;
    138 
    139     return (NUM_LAP_MEM_RECS);
    140 }
    141 
    142 /*!
    143 ************************************************************************
    144 * @brief
    145 *    Init LAP structure
    146 ************************************************************************
    147 */
    148 void *ihevce_lap_init(
    149     iv_mem_rec_t *ps_mem_tab,
    150     ihevce_lap_static_params_t *ps_lap_params,
    151     ihevce_static_cfg_params_t *ps_static_cfg_prms)
    152 {
    153     WORD32 i4_src_interlace_field;
    154     WORD32 i4_max_temporal_layers;
    155     ihevce_encode_node_t *ps_encode_node_struct;
    156     lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_mem_tab[LAP_CTXT].pv_base;
    157     ihevce_lap_static_params_t *ps_lap_static_params = &ps_lap_struct->s_lap_static_params;
    158     ps_lap_struct->aps_encode_node[0] = (ihevce_encode_node_t *)ps_mem_tab[LAP_NODE_MEM].pv_base;
    159 
    160     memcpy(
    161         &ps_lap_struct->s_static_cfg_params,
    162         ps_static_cfg_prms,
    163         sizeof(ihevce_static_cfg_params_t));
    164     memmove(ps_lap_static_params, ps_lap_params, sizeof(ihevce_lap_static_params_t));
    165     ps_lap_static_params->e_arch_type = ps_static_cfg_prms->e_arch_type;
    166 
    167     /* Set the array to zero */
    168     memset(&ps_lap_struct->ai4_capture_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32));
    169     memset(&ps_lap_struct->ai4_encode_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32));
    170     memset(&ps_lap_struct->ref_poc_array[0], 0xFF, sizeof(ps_lap_struct->ref_poc_array));
    171     memset(&ps_lap_struct->ai4_pic_type_to_be_removed, 0, NUM_LAP2_LOOK_AHEAD * sizeof(WORD32));
    172 
    173     ps_lap_struct->i4_curr_poc = 0;
    174     ps_lap_struct->i4_cra_poc = 0;
    175 
    176     i4_max_temporal_layers = ps_lap_static_params->i4_max_temporal_layers;
    177     i4_src_interlace_field = ps_lap_static_params->i4_src_interlace_field;
    178     ps_lap_struct->i4_max_idr_period =
    179         ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period;
    180     ps_lap_struct->i4_min_idr_period =
    181         ps_static_cfg_prms->s_coding_tools_prms.i4_min_closed_gop_period;
    182     ps_lap_struct->i4_max_cra_period =
    183         ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period;
    184     ps_lap_struct->i4_max_i_period =
    185         ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period;
    186     ps_lap_struct->i4_idr_counter = 0;
    187     ps_lap_struct->i4_cra_counter = 0;
    188     ps_lap_struct->i4_i_counter = 0;
    189     ps_lap_struct->i4_idr_gop_num = -1;
    190     ps_lap_struct->i4_curr_ref_pics = 0;
    191     ps_lap_struct->i4_display_num = 0;
    192     ps_lap_struct->i4_num_frames_after_force_idr = 0;
    193     ps_lap_struct->i4_num_frm_type_decided = 0;
    194     ps_lap_struct->i4_next_start_ctr = 0;
    195     ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_IDR;
    196 
    197     ps_lap_struct->i4_enable_logo = ps_lap_static_params->i4_enable_logo;
    198     ps_lap_struct->i4_cra_i_pic_flag = 0;
    199     ps_lap_struct->i4_force_end_flag = 0;
    200     ps_lap_struct->i4_sub_gop_size = (1 << i4_max_temporal_layers);
    201     ps_lap_struct->i4_sub_gop_size_idr =
    202         ps_lap_struct->i4_sub_gop_size + (i4_max_temporal_layers > 0);
    203 
    204     ps_lap_struct->i4_is_all_i_pic_in_seq = 0;
    205 
    206     if(ps_lap_struct->i4_max_idr_period == 1 || ps_lap_struct->i4_max_cra_period == 1 ||
    207        ps_lap_struct->i4_max_i_period == 1)
    208     {
    209         ps_lap_struct->i4_is_all_i_pic_in_seq = 1;
    210     }
    211 
    212     if(1 == i4_src_interlace_field && (!ps_lap_struct->i4_is_all_i_pic_in_seq))
    213     {
    214         ps_lap_struct->i4_sub_gop_size <<= 1;
    215         ps_lap_struct->i4_sub_gop_size_idr <<= 1;
    216     }
    217 
    218     ps_lap_struct->i4_fixed_open_gop_period = 1;
    219     ps_lap_struct->i4_fixed_i_period = 1;
    220 
    221     if(ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period <=
    222        ps_lap_struct->i4_sub_gop_size)
    223     {
    224         ps_lap_struct->i4_min_idr_period =
    225             ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period;
    226     }
    227     if(ps_lap_struct->i4_max_idr_period)
    228     {
    229         if(ps_lap_struct->i4_max_cra_period)
    230         {
    231             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period;
    232         }
    233         else if(ps_lap_struct->i4_max_i_period)
    234         {
    235             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period;
    236         }
    237         else
    238         {
    239             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_idr_period;
    240         }
    241     }
    242     else
    243     {
    244         if(ps_lap_struct->i4_max_i_period)
    245         {
    246             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period;
    247         }
    248         else if(ps_lap_struct->i4_max_cra_period)
    249         {
    250             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period;
    251         }
    252     }
    253 
    254     if(!ps_lap_struct->i4_max_i_period)
    255     {
    256         ps_lap_struct->i4_max_i_period =
    257             2 * MAX(ps_lap_struct->i4_max_idr_period, ps_lap_struct->i4_max_cra_period);
    258     }
    259 
    260     ps_lap_struct->i4_no_back_to_back_i_avoidance = 0;
    261 
    262     /*Infinite GOP case*/
    263     if(!ps_lap_struct->i4_gop_period)
    264     {
    265         /*max signed 32 bit value which will be ~ 414 days considering 60frames/fields per second*/
    266         ps_lap_struct->i4_max_i_period = 0x7fffffff;
    267         ps_lap_struct->i4_gop_period =
    268             (INFINITE_GOP_CDR_TIME_S * (ps_static_cfg_prms->s_src_prms.i4_frm_rate_num /
    269                                         ps_static_cfg_prms->s_src_prms.i4_frm_rate_denom));
    270     }
    271 
    272     if(ps_lap_struct->i4_gop_period < (2 * ps_lap_struct->i4_sub_gop_size))
    273     {
    274         ps_lap_struct->i4_no_back_to_back_i_avoidance = 1;
    275     }
    276 
    277     ps_lap_struct->i4_rc_lap_period =
    278         ps_static_cfg_prms->s_lap_prms.i4_rc_look_ahead_pics + MIN_L1_L0_STAGGER_NON_SEQ;
    279     ps_lap_struct->pv_prev_inp_buf = NULL;
    280     ps_lap_struct->i4_buf_deq_idx = 0;
    281     ps_lap_struct->i4_deq_idx = 0;
    282     ps_lap_struct->i4_enq_idx = 0;
    283     ps_lap_struct->i4_lap2_counter = 0;
    284     ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size;
    285     ps_lap_struct->i4_buf_enq_idx = 0;
    286     ps_lap_struct->i4_lap_out_idx = 0;
    287     ps_lap_struct->i4_capture_idx = 0;
    288     ps_lap_struct->i4_idr_flag = 1;
    289     ps_lap_struct->i4_num_bufs_encode_order = 0;
    290     ps_lap_struct->end_flag = 0;
    291     ps_lap_struct->i4_immediate_idr_case = 0;
    292     ps_lap_struct->i4_max_buf_in_enc_order = 0;
    293     ps_lap_struct->i4_end_flag_pic_idx = 0;
    294     memset(
    295         &ps_lap_struct->api4_encode_order_array[0],
    296         0,
    297         sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES);
    298 
    299     {
    300         WORD32 node_offset, curr_layer;
    301         WORD32 i;
    302         /*intialization of aps_lap_inp_buf*/
    303         for(i = 0; i < MAX_QUEUE_LENGTH; i++)
    304         {
    305             ps_lap_struct->aps_lap_inp_buf[i] = NULL;
    306         }
    307 
    308         /* init capture order and encode order pointer */
    309         ps_lap_struct->pi4_capture_poc_ptr = &ps_lap_struct->ai4_capture_order_poc[0];
    310         ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
    311 
    312         /* init all the buffer status to default values */
    313         ps_encode_node_struct = ps_lap_struct->aps_encode_node[0];
    314 
    315         ps_encode_node_struct->pv_left_node = NULL;
    316         ps_encode_node_struct->pv_right_node = NULL;
    317 
    318         /* Initialise the tree */
    319         node_offset = 1;
    320         curr_layer = 0;
    321         ihevce_populate_tree_nodes(
    322             ps_encode_node_struct,
    323             ps_encode_node_struct,
    324             &node_offset,
    325             curr_layer,
    326             ps_lap_static_params->i4_max_temporal_layers);
    327     }
    328 
    329     ps_mem_tab += NUM_LAP_MEM_RECS;
    330 
    331     return ((void *)ps_lap_struct);
    332 }
    333 
    334 /*!
    335 ******************************************************************************
    336 * \if Function name : ihevce_populate_tree_nodes \endif
    337 *
    338 * \brief
    339 *    LAP populate nodes function
    340 *
    341 * \param[in] encode_parent_node_t node pointer to base
    342 *            encode_node_t        node pointer to current buffer
    343 *            loop_count                layer count
    344 *            hier_layer           total layers
    345 * \return
    346 *    None
    347 *
    348 * \author
    349 *  Ittiam
    350 *
    351 *****************************************************************************
    352 */
    353 void ihevce_populate_tree_nodes(
    354     ihevce_encode_node_t *encode_parent_node_t,
    355     ihevce_encode_node_t *encode_node_t,
    356     WORD32 *loop_count,
    357     WORD32 layer,
    358     WORD32 hier_layer)
    359 {
    360     /* If only I/P pictures, return NULL from the child nodes*/
    361     if(hier_layer == 0)
    362     {
    363         encode_node_t->pv_left_node = NULL;
    364         encode_node_t->pv_right_node = NULL;
    365         return;
    366     }
    367     if(layer == hier_layer)
    368         return;
    369 
    370     layer = layer + 1;
    371 
    372     /* If the layers are not exhausted */
    373     if(layer < hier_layer)
    374     {
    375         encode_node_t->pv_left_node = encode_parent_node_t + (*loop_count);
    376         encode_node_t->pv_right_node = encode_parent_node_t + (*loop_count + 1);
    377         (*loop_count) = (*loop_count) + 2;
    378     }
    379     else
    380     {
    381         encode_node_t->pv_left_node = NULL;
    382         encode_node_t->pv_right_node = NULL;
    383     }
    384 
    385     /* Populate Left tree nodes */
    386     ihevce_populate_tree_nodes(
    387         encode_parent_node_t,
    388         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
    389         loop_count,
    390         layer,
    391         hier_layer);
    392 
    393     /* Populate right tree nodes */
    394     ihevce_populate_tree_nodes(
    395         encode_parent_node_t,
    396         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
    397         loop_count,
    398         layer,
    399         hier_layer);
    400 }
    401 
    402 /*!
    403 ************************************************************************
    404 * \brief
    405 *    pad input when its dimensions are not aligned to LCU size
    406 ************************************************************************
    407 */
    408 void ihevce_lap_pad_input_bufs(
    409     ihevce_lap_enc_buf_t *ps_curr_inp, WORD32 align_pic_wd, WORD32 align_pic_ht)
    410 {
    411     /* local variables */
    412     WORD32 ctr_horz, ctr_vert;
    413 
    414     /* ------- Horizontal Right Padding ------ */
    415     if(align_pic_wd != ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd)
    416     {
    417         UWORD8 *pu1_inp;
    418         UWORD16 *pu2_inp;
    419         WORD32 pad_wd;
    420         WORD32 pad_ht;
    421 
    422         /* ------------- LUMA ----------------------------- */
    423         /* derive the pointers and dimensions to be padded */
    424         pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
    425         pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
    426         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
    427         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
    428 
    429         /* loops for padding the right region for entire pic */
    430         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
    431         {
    432             for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++)
    433             {
    434                 /* last pixel is replicated */
    435                 pu1_inp[ctr_horz] = pu1_inp[-1];
    436             }
    437 
    438             /* row level increments */
    439             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
    440         }
    441 
    442         /* ------------- CHROMA ---------------------------- */
    443         /* derive the pointers and dimensions to be padded */
    444         pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
    445         pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd;
    446         pad_wd >>= 1;
    447         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
    448         pu2_inp = (UWORD16 *)(pu1_inp + ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd);
    449 
    450         /* loops for padding the right region for entire pic */
    451         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
    452         {
    453             for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++)
    454             {
    455                 /* last pixel is replicated, cb and cr pixel interleaved */
    456                 pu2_inp[ctr_horz] = pu2_inp[-1];
    457             }
    458 
    459             /* row level increments */
    460             pu2_inp += (ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd >> 1);
    461         }
    462     }
    463 
    464     /* ------- Vertical Bottom Padding ------ */
    465     if(align_pic_ht != ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht)
    466     {
    467         UWORD8 *pu1_inp, *pu1_src;
    468         WORD32 pad_ht;
    469 
    470         /* ------------- LUMA ----------------------------- */
    471         /* derive the pointers and dimensions to be padded */
    472         pad_ht = align_pic_ht - ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
    473         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
    474         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
    475                    ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
    476 
    477         /* get the pointer of last row */
    478         pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
    479 
    480         /* loops for padding the bottom region for entire row */
    481         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
    482         {
    483             /* copy the eniter orw including horz padd region */
    484             memcpy(pu1_inp, pu1_src, align_pic_wd);
    485 
    486             /* row level increments */
    487             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
    488         }
    489 
    490         /* ------------- CHROMA ----------------------------- */
    491         /* derive the pointers and dimensions to be padded */
    492         pad_ht = (align_pic_ht >> 1) - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
    493         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
    494         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht *
    495                    ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
    496 
    497         /* get the pointer of last row */
    498         pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
    499 
    500         /* loops for padding the bottom region for entire row */
    501         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
    502         {
    503             /* copy the eniter orw including horz padd region */
    504             memcpy(pu1_inp, pu1_src, align_pic_wd);
    505 
    506             /* row level increments */
    507             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
    508         }
    509     }
    510     return;
    511 }
    512 
    513 /*!
    514 ************************************************************************
    515 * \brief
    516 *    check for last inp buf
    517 ************************************************************************
    518 */
    519 WORD32 ihevce_check_last_inp_buf(WORD32 *pi4_cmd_buf)
    520 {
    521     WORD32 cmd = (*pi4_cmd_buf) & (IHEVCE_COMMANDS_TAG_MASK);
    522 
    523     if(IHEVCE_SYNCH_API_FLUSH_TAG == cmd)
    524         return 1;
    525     return 0;
    526 }
    527 
    528 /*!
    529 ************************************************************************
    530 * \brief
    531 *    lap parse sync commands
    532 ************************************************************************
    533 */
    534 void ihevce_lap_parse_sync_cmd(
    535     ihevce_hle_ctxt_t *ps_hle_ctxt,
    536     ihevce_static_cfg_params_t *ps_static_cfg_prms,
    537     WORD32 *pi4_cmd_buf,
    538     ihevce_lap_enc_buf_t *ps_lap_inp_buf,
    539     WORD32 *pi4_flush_check,
    540     WORD32 *pi4_force_idr_check,
    541     WORD32 *pi4_set_res_check,
    542     WORD32 *pi4_num_frames_after_force_idr)
    543 {
    544     WORD32 *pi4_end;
    545     WORD32 i4_sub_gop_size_mul_2, i4_field_pic, i4_is_first_field;
    546     WORD32 *pi4_tag_parse, i4_end_flag = 0, *pi4_next_tag, i4_length, i4_buf_id, i4_next_tag;
    547     UWORD32 u4_num_sei = 0;
    548     i4_length = ps_lap_inp_buf->s_input_buf.i4_cmd_buf_size;
    549     i4_buf_id = ps_lap_inp_buf->s_input_buf.i4_buf_id;
    550     pi4_end = pi4_cmd_buf + (i4_length >> 2) - 1;
    551     i4_sub_gop_size_mul_2 = (1 << ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers)
    552                             << 1;
    553     i4_field_pic = ps_static_cfg_prms->s_src_prms.i4_field_pic;
    554     pi4_tag_parse = pi4_cmd_buf;
    555     i4_is_first_field = 1;
    556     if(i4_field_pic)
    557     {
    558         i4_is_first_field =
    559             (ps_lap_inp_buf->s_input_buf.i4_topfield_first ^
    560              ps_lap_inp_buf->s_input_buf.i4_bottom_field);
    561     }
    562 
    563     while(pi4_tag_parse != (pi4_end + 1))
    564     {
    565         switch((*pi4_tag_parse) & (IHEVCE_COMMANDS_TAG_MASK))
    566         {
    567         case IHEVCE_SYNCH_API_FLUSH_TAG:
    568             (*pi4_flush_check) = 1;
    569             if((*(pi4_tag_parse + 1)))
    570                 ps_hle_ctxt->ihevce_cmds_error_report(
    571                     ps_hle_ctxt->pv_cmd_err_cb_handle,
    572                     IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO,
    573                     1,
    574                     i4_buf_id);
    575             pi4_tag_parse += 2;
    576             u4_num_sei++;
    577             break;
    578         case IHEVCE_SYNCH_API_FORCE_IDR_TAG:
    579             if(0 == i4_field_pic)
    580             {
    581                 (*pi4_force_idr_check) = 1;
    582                 if((*(pi4_tag_parse + 1)))
    583                     ps_hle_ctxt->ihevce_cmds_error_report(
    584                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    585                         IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO,
    586                         1,
    587                         i4_buf_id);
    588                 if(*pi4_num_frames_after_force_idr < i4_sub_gop_size_mul_2)
    589                 {
    590                     ps_hle_ctxt->ihevce_cmds_error_report(
    591                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    592                         IHEVCE_SYNCH_ERR_FREQ_FORCE_IDR_RECEIVED,
    593                         1,
    594                         i4_buf_id);
    595                 }
    596                 *pi4_num_frames_after_force_idr = 0;
    597             }
    598             else
    599             {
    600                 if(i4_is_first_field)
    601                 {
    602                     (*pi4_force_idr_check) = 1;
    603                 }
    604                 if((*(pi4_tag_parse + 1)))
    605                     ps_hle_ctxt->ihevce_cmds_error_report(
    606                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    607                         IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO,
    608                         1,
    609                         i4_buf_id);
    610 
    611                 if((*pi4_num_frames_after_force_idr < (i4_sub_gop_size_mul_2 << 1)))
    612                 {
    613                     ps_hle_ctxt->ihevce_cmds_error_report(
    614                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    615                         IHEVCE_SYNCH_ERR_FREQ_FORCE_IDR_RECEIVED,
    616                         1,
    617                         i4_buf_id);
    618                 }
    619                 *pi4_num_frames_after_force_idr = 0;
    620             }
    621             pi4_tag_parse += 2;
    622             u4_num_sei++;
    623             break;
    624         case IHEVCE_SYNCH_API_SET_RES_TAG:
    625             (*pi4_set_res_check) = 0;
    626             ps_hle_ctxt->ihevce_cmds_error_report(
    627                 ps_hle_ctxt->pv_cmd_err_cb_handle,
    628                 IHEVCE_SYNCH_ERR_SET_RES_NOT_SUPPORTED,
    629                 1,
    630                 i4_buf_id);
    631             break;
    632         case IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG:
    633             pi4_next_tag =
    634                 pi4_tag_parse + 2 +
    635                 (((*(pi4_tag_parse + 1) - 1) >> 2) + 1);  //Logic to reach the next boundary of 4
    636             i4_next_tag = (*pi4_next_tag & IHEVCE_COMMANDS_TAG_MASK);
    637             if((i4_next_tag != IHEVCE_SYNCH_API_END_TAG) &&
    638                (i4_next_tag != IHEVCE_SYNCH_API_FLUSH_TAG) &&
    639                (i4_next_tag != IHEVCE_SYNCH_API_FORCE_IDR_TAG) &&
    640                (i4_next_tag != IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG) &&
    641                (i4_next_tag != IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG))
    642             {
    643                 if(*(pi4_tag_parse + 1) % 4)
    644                     ps_hle_ctxt->ihevce_cmds_error_report(
    645                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    646                         IHEVCE_SYNCH_ERR_NO_PADDING,
    647                         1,
    648                         i4_buf_id);
    649                 else
    650                     ps_hle_ctxt->ihevce_cmds_error_report(
    651                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    652                         IHEVCE_SYNCH_ERR_WRONG_LENGTH,
    653                         1,
    654                         i4_buf_id);
    655             }
    656             pi4_tag_parse = pi4_next_tag;
    657             u4_num_sei++;
    658             break;
    659         case IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG:
    660             pi4_next_tag =
    661                 pi4_tag_parse + 2 +
    662                 (((*(pi4_tag_parse + 1) - 1) >> 2) + 1);  //Logic to reach the next boundary of 4
    663             i4_next_tag = (*pi4_next_tag & IHEVCE_COMMANDS_TAG_MASK);
    664             if((i4_next_tag != IHEVCE_SYNCH_API_END_TAG) &&
    665                (i4_next_tag != IHEVCE_SYNCH_API_FLUSH_TAG) &&
    666                (i4_next_tag != IHEVCE_SYNCH_API_FORCE_IDR_TAG) &&
    667                (i4_next_tag != IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG) &&
    668                (i4_next_tag != IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG))
    669             {
    670                 if(*(pi4_tag_parse + 1) % 4)
    671                     ps_hle_ctxt->ihevce_cmds_error_report(
    672                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    673                         IHEVCE_SYNCH_ERR_NO_PADDING,
    674                         1,
    675                         i4_buf_id);
    676                 else
    677                     ps_hle_ctxt->ihevce_cmds_error_report(
    678                         ps_hle_ctxt->pv_cmd_err_cb_handle,
    679                         IHEVCE_SYNCH_ERR_WRONG_LENGTH,
    680                         1,
    681                         i4_buf_id);
    682             }
    683             pi4_tag_parse = pi4_next_tag;
    684             u4_num_sei++;
    685             break;
    686         case IHEVCE_SYNCH_API_END_TAG:
    687             i4_end_flag = 1;
    688             break;
    689         default:
    690             ps_hle_ctxt->ihevce_cmds_error_report(
    691                 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TLV_ERROR, 1, i4_buf_id);
    692         }
    693         if(i4_end_flag)
    694             break;
    695     }
    696     if(u4_num_sei > MAX_NUMBER_OF_SEI_PAYLOAD)  //Checking for max number of SEI messages.
    697         ps_hle_ctxt->ihevce_cmds_error_report(
    698             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TOO_MANY_SEI_MSG, 1, i4_buf_id);
    699 
    700     if(!i4_end_flag)
    701         ps_hle_ctxt->ihevce_cmds_error_report(
    702             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_NO_END_TAG, 1, i4_buf_id);
    703 }
    704 
    705 /*!
    706 ************************************************************************
    707 * \brief
    708 *    lap parse Async commands
    709 ************************************************************************
    710 */
    711 void ihevce_lap_parse_async_cmd(
    712     ihevce_hle_ctxt_t *ps_hle_ctxt,
    713     WORD32 *pi4_cmd_buf,
    714     WORD32 i4_length,
    715     WORD32 i4_buf_id,
    716     WORD32 *pi4_num_set_bitrate_cmds,
    717     ihevce_dyn_config_prms_t *ps_dyn_br)
    718 {
    719     WORD32 i4_end_flag = 0;
    720     WORD32 *pi4_end = pi4_cmd_buf + (i4_length >> 2) - 1;
    721     WORD32 *pi4_tag_parse = pi4_cmd_buf;
    722 
    723     while(pi4_tag_parse != pi4_end)
    724     {
    725         switch(*pi4_tag_parse)
    726         {
    727         case IHEVCE_ASYNCH_API_SETBITRATE_TAG:
    728             if((*(pi4_tag_parse + 1)) != sizeof(ihevce_dyn_config_prms_t))
    729                 ps_hle_ctxt->ihevce_cmds_error_report(
    730                     ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_BR_NOT_BYTE, 1, i4_buf_id);
    731 
    732             memcpy(
    733                 (void *)ps_dyn_br, (void *)(pi4_tag_parse + 2), sizeof(ihevce_dyn_config_prms_t));
    734             pi4_tag_parse += 2;
    735             pi4_tag_parse += (sizeof(ihevce_dyn_config_prms_t) >> 2);
    736             *pi4_num_set_bitrate_cmds = *pi4_num_set_bitrate_cmds + 1;
    737             ps_dyn_br++;
    738 
    739             break;
    740         case IHEVCE_ASYNCH_API_END_TAG:
    741             i4_end_flag = 1;
    742             break;
    743         default:
    744             ps_hle_ctxt->ihevce_cmds_error_report(
    745                 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_TLV_ERROR, 1, i4_buf_id);
    746         }
    747         if(i4_end_flag)
    748             break;
    749     }
    750     if(!i4_end_flag)
    751         ps_hle_ctxt->ihevce_cmds_error_report(
    752             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_NO_END_TAG, 1, i4_buf_id);
    753 }
    754 
    755 /*!
    756 ************************************************************************
    757 * \brief
    758 *    ref pics weight offset calculation
    759 ************************************************************************
    760 */
    761 void ref_pics_weight_offset_calc(ihevce_lap_output_params_t *ps_lap_out, lap_struct_t *ps_lap_struct)
    762 {
    763     WORD32 i, j;
    764     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
    765     WORD32 ai4_delta_poc[MAX_REF_PICS];
    766     WORD32 ref_poc_arr_sort[MAX_REF_PICS];
    767 
    768     /* Default weighted pred parameters populated for  now */
    769     ps_lap_out->i4_log2_luma_wght_denom = DENOM_DEFAULT;
    770     ps_lap_out->i4_log2_chroma_wght_denom = DENOM_DEFAULT;
    771 
    772     /* sort the ref_poc_array based on delta as
    773      * in case weighted pred dup pics are inserted and it should consider
    774      * the neighbors first for prediction than farthest */
    775     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
    776     {
    777         ai4_delta_poc[i] = ref_poc_array[i] - ps_lap_out->i4_poc;
    778     }
    779 
    780     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
    781     {
    782         WORD32 i4_min, temp;
    783         i4_min = i;
    784         for(j = i; j < ps_lap_struct->i4_curr_ref_pics; j++)
    785         {
    786             if(abs(ai4_delta_poc[j]) <= abs(ai4_delta_poc[i4_min]))
    787             {
    788                 i4_min = j;
    789             }
    790         }
    791         temp = ai4_delta_poc[i];
    792         ai4_delta_poc[i] = ai4_delta_poc[i4_min];
    793         ai4_delta_poc[i4_min] = temp;
    794         ref_poc_arr_sort[i] = ai4_delta_poc[i] + ps_lap_out->i4_poc;
    795     }
    796 
    797     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
    798     {
    799         ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc = ref_poc_arr_sort[i] - ps_lap_out->i4_poc;
    800         ASSERT(ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc);
    801 
    802         /* Enable flag for the reference pics to be used by curr pic */
    803         ps_lap_out->as_ref_pics[i].i4_used_by_cur_pic_flag = gau1_use_by_cur_pic_flag[i];
    804 
    805         /* Currently no weighted prediction offset added */
    806         ps_lap_out->as_ref_pics[i].i4_num_duplicate_entries_in_ref_list = 1;
    807     }
    808     return;
    809 }
    810 
    811 /*!
    812 ************************************************************************
    813 * \brief
    814 *    ref b picture population
    815 ************************************************************************
    816 */
    817 void ref_b_pic_population(
    818     WORD32 curr_layer, ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct)
    819 {
    820     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out;
    821     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
    822     WORD32 *p_ref_poc_array = ref_poc_array;
    823     WORD32 i4_interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
    824     WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames;
    825     WORD32 max_temporal_layers = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
    826 
    827     /* LAP output structure */
    828     ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0];
    829     ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num;
    830     ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc;
    831     ps_lap_out->i4_temporal_lyr_id = curr_layer;
    832     ps_lap_out->i4_pic_type = IV_B_FRAME;
    833 
    834     if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) &&
    835        (ref_poc_array[0] < ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag)
    836     {
    837         ref_poc_array[0] = ps_lap_struct->i4_cra_poc;
    838         ps_lap_struct->i4_curr_ref_pics = 1;
    839     }
    840 
    841     ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics;
    842 
    843     /* Default: Cur pic is ref pic*/
    844     ps_lap_out->i4_is_ref_pic = 1;
    845 
    846     if(1 == i4_interlace_field)
    847     {
    848         WORD32 i4_bottom_field = ps_lap_inp->s_input_buf.i4_bottom_field;
    849         WORD32 first_field = (ps_lap_inp->s_input_buf.i4_topfield_first ^ i4_bottom_field);
    850 
    851         /*If current pic is top field B picture and is present in top hierarchical layer */
    852         /* Dereference the curr pic */
    853         if(ps_lap_out->i4_temporal_lyr_id == max_temporal_layers)
    854         {
    855             if(0 == first_field)
    856                 ps_lap_out->i4_is_ref_pic = 0;
    857             else
    858                 ps_lap_out->i4_is_ref_pic = 2;
    859         }
    860     }
    861     else
    862     {
    863         /*If progressive B picture and is present in top hierarchical layer */
    864         if(ps_lap_out->i4_temporal_lyr_id >= max_temporal_layers)
    865         {
    866             ps_lap_out->i4_temporal_lyr_id = max_temporal_layers;
    867             ps_lap_out->i4_is_ref_pic = 0;
    868         }
    869     }
    870 
    871     ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct);
    872 
    873     /* Updating number of current reference Pictures for the Given Picture */
    874     /* If the current frame is n-layer B frame, donot increment*/
    875     if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics)
    876     {
    877         if(ps_lap_out->i4_is_ref_pic)
    878         {
    879             ps_lap_struct->i4_curr_ref_pics++;
    880         }
    881     }
    882 
    883     /* Arrange the reference array in ascending order */
    884     {
    885         WORD32 i, j, temp;
    886         for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++)
    887         {
    888             for(j = i + 1; j < ps_lap_struct->i4_curr_ref_pics; j++)
    889             {
    890                 if(ref_poc_array[i] > ref_poc_array[j])
    891                 {
    892                     temp = ref_poc_array[i];
    893                     ref_poc_array[i] = ref_poc_array[j];
    894                     ref_poc_array[j] = temp;
    895                 }
    896             }
    897         }
    898     }
    899 
    900     {
    901         WORD32 ref = ps_lap_out->i4_poc;
    902         if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array)
    903         {
    904             *p_ref_poc_array = ref;
    905         }
    906     }
    907 
    908     return;
    909 }
    910 
    911 /*!
    912 ************************************************************************
    913 * \brief
    914 *    ref i/p pic population
    915 ************************************************************************
    916 */
    917 void ref_pic_population(ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct)
    918 {
    919     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out;
    920     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
    921     WORD32 *p_ref_poc_array = ref_poc_array;
    922     WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames;
    923 
    924     /* Update the POC position */
    925     ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0];
    926 
    927     /* picture after CRA can't refer pic before CRA*/
    928     if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) &&
    929        (ref_poc_array[0] <= ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag)
    930     {
    931         ref_poc_array[0] = ps_lap_struct->i4_cra_poc;
    932         ps_lap_struct->i4_curr_ref_pics = 1;
    933     }
    934 
    935     /* For every IDR period, set pic type as IDR frame and reset reference POC array to 0*/
    936     if(IV_IDR_FRAME == ps_lap_out->i4_pic_type)
    937     {
    938         ps_lap_struct->i4_idr_gop_num++;
    939         ps_lap_struct->i4_curr_ref_pics = 0;
    940         ps_lap_out->i4_num_ref_pics = 0;
    941         ps_lap_struct->i4_cra_i_pic_flag = 1;
    942         ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc;
    943 
    944         memset(ps_lap_struct->ref_poc_array, 0xFF, sizeof(WORD32) * MAX_REF_PICS);
    945     }
    946     else if(IV_I_FRAME == ps_lap_out->i4_pic_type)
    947     {
    948         /* For the I-frames after CRA Frame, no pictures should be referenced */
    949         if((1 == ps_lap_struct->i4_cra_i_pic_flag) && ps_lap_out->i4_is_cra_pic)
    950         {
    951             ps_lap_struct->i4_curr_ref_pics = 0;
    952             ps_lap_out->i4_num_ref_pics = 0;
    953         }
    954         ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc;
    955         ps_lap_struct->i4_cra_i_pic_flag = ps_lap_out->i4_is_cra_pic;
    956     }
    957     else if(IV_P_FRAME == ps_lap_out->i4_pic_type)
    958     {
    959         /* If the current POC is the P POC after CRA I POC */
    960         if(1 == ps_lap_struct->i4_cra_i_pic_flag)
    961         {
    962             ps_lap_struct->i4_curr_ref_pics = 1;
    963             ps_lap_struct->i4_cra_i_pic_flag = 0;
    964         }
    965     }
    966 
    967     if(ps_lap_out->i4_pic_type == IV_IDR_FRAME ||
    968        (ps_lap_out->i4_pic_type == IV_I_FRAME && ps_lap_out->i4_is_cra_pic))
    969     {
    970         ps_lap_struct->i4_assoc_IRAP_poc = ps_lap_out->i4_poc;
    971     }
    972 
    973     /*Update ps_lap_out*/
    974     ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num;
    975     ps_lap_out->i4_is_ref_pic = 1;
    976     ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc;
    977 
    978     /* Reference POCS */
    979     ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics;
    980 
    981     /* I and P frames are always mapped to layer zero*/
    982     ps_lap_out->i4_temporal_lyr_id = 0;
    983 
    984     ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct);
    985 
    986     if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics)
    987     {
    988         if(ps_lap_out->i4_is_ref_pic)
    989         {
    990             ps_lap_struct->i4_curr_ref_pics++;
    991         }
    992     }
    993 
    994     /* Arrange the reference array in ascending order */
    995     {
    996         WORD32 i, j, temp;
    997         for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++)
    998         {
    999             for(j = i + 1; j < (ps_lap_struct->i4_curr_ref_pics); j++)
   1000             {
   1001                 if(ref_poc_array[i] > ref_poc_array[j])
   1002                 {
   1003                     temp = ref_poc_array[i];
   1004                     ref_poc_array[i] = ref_poc_array[j];
   1005                     ref_poc_array[j] = temp;
   1006                 }
   1007             }
   1008         }
   1009     }
   1010 
   1011     {
   1012         /* add the current pictute at the start of the reference queue */
   1013         /*For I and P pictures, all the previous frames are reference frames */
   1014         /* If the current ref POC is greater than the least POC in reference array*/
   1015         /* Then fill the reference array */
   1016 
   1017         WORD32 ref = ps_lap_out->i4_poc;
   1018 
   1019         if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array)
   1020         {
   1021             *p_ref_poc_array = ref;
   1022         }
   1023     }
   1024 
   1025     return;
   1026 }
   1027 
   1028 /*!
   1029 ************************************************************************
   1030 * \brief
   1031 *    determine next sub-gop state
   1032 ************************************************************************
   1033 */
   1034 void ihevce_determine_next_sub_gop_state(lap_struct_t *ps_lap_struct)
   1035 {
   1036     WORD32 i4_num_b_frames = -1;
   1037     WORD32 i4_sd = ps_lap_struct->i4_sub_gop_size;
   1038     WORD32 i4_sd_idr = ps_lap_struct->i4_sub_gop_size_idr;
   1039     WORD32 i4_Midr = ps_lap_struct->i4_max_idr_period;
   1040     WORD32 i4_midr = ps_lap_struct->i4_min_idr_period;
   1041     WORD32 i4_Mcra = ps_lap_struct->i4_max_cra_period;
   1042     WORD32 i4_Mi = ps_lap_struct->i4_max_i_period;
   1043     WORD32 i4_Cd = ps_lap_struct->i4_idr_counter;
   1044     WORD32 i4_Cc = ps_lap_struct->i4_cra_counter;
   1045     WORD32 i4_Ci = ps_lap_struct->i4_i_counter;
   1046 
   1047     if(i4_Midr)
   1048         ASSERT(i4_Cd < i4_Midr);
   1049 
   1050     if(i4_Mcra)
   1051         ASSERT(i4_Cc < i4_Mcra);
   1052 
   1053     if(i4_Mi)
   1054         ASSERT(i4_Ci < i4_Mi);
   1055 
   1056     /*if all are i pictures */
   1057     if((i4_Midr == 1) || (i4_Mcra == 1) || (i4_Mi == 1))
   1058     {
   1059         ps_lap_struct->i4_num_frm_type_decided = 1;
   1060         if((i4_Midr == 1) || ((i4_Cd + i4_sd) == i4_Midr))
   1061         {
   1062             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR;
   1063             ps_lap_struct->i4_idr_counter = 0;
   1064             ps_lap_struct->i4_cra_counter = 0;
   1065             ps_lap_struct->i4_i_counter = 0;
   1066         }
   1067         else if((i4_Mcra == 1) || ((i4_Cc + i4_sd) == i4_Mcra))
   1068         {
   1069             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_CRA;
   1070             ps_lap_struct->i4_idr_counter += 1;
   1071             ps_lap_struct->i4_cra_counter = 0;
   1072             ps_lap_struct->i4_i_counter = 0;
   1073         }
   1074         else
   1075         {
   1076             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_I;
   1077             ps_lap_struct->i4_idr_counter += 1;
   1078             ps_lap_struct->i4_cra_counter += 1;
   1079             ps_lap_struct->i4_i_counter = 0;
   1080         }
   1081         return;
   1082     }
   1083 
   1084     if((i4_Cd + i4_sd_idr >= i4_Midr) && i4_Midr)
   1085     {
   1086         /*if idr falls already on sub-gop aligned w.r.t Midr or if strict idr use case*/
   1087         if(i4_sd_idr != i4_sd)
   1088         {
   1089             i4_num_b_frames = i4_Midr - i4_Cd - 2;
   1090             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1091             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
   1092             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 2] = PIC_TYPE_IDR;
   1093             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 2;
   1094             ps_lap_struct->i4_idr_counter = 0;
   1095             ps_lap_struct->i4_cra_counter = 0;
   1096             ps_lap_struct->i4_i_counter = 0;
   1097         }
   1098         else
   1099         {
   1100             i4_num_b_frames = 0;
   1101             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR;
   1102             ps_lap_struct->i4_num_frm_type_decided = 1;
   1103             ps_lap_struct->i4_idr_counter = 0;
   1104             ps_lap_struct->i4_cra_counter = 0;
   1105             ps_lap_struct->i4_i_counter = 0;
   1106         }
   1107     }
   1108     /*if next sub gop is going to have CRA as Cc reaches Mcra*/
   1109     else if(((i4_Cc + i4_sd) >= i4_Mcra) && i4_Mcra)
   1110     {
   1111         if(((i4_Cc + i4_sd) == i4_Mcra) || (1 == ps_lap_struct->i4_fixed_open_gop_period))
   1112         {
   1113             i4_num_b_frames = i4_Mcra - i4_Cc - 1;
   1114             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1115             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_CRA;
   1116             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
   1117             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
   1118             ps_lap_struct->i4_cra_counter = 0;
   1119             ps_lap_struct->i4_i_counter = 0;
   1120         }
   1121         else
   1122         {
   1123             ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_CRA;
   1124             i4_num_b_frames = i4_sd - 1;
   1125             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1126             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
   1127             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
   1128             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
   1129             ps_lap_struct->i4_cra_counter = ps_lap_struct->i4_num_frm_type_decided;
   1130             ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided;
   1131         }
   1132     }
   1133     /*if next sub gop is going to have I_slice as Ci reaches Mi*/
   1134     else if((i4_Ci + i4_sd >= i4_Mi) && i4_Mi)
   1135     {
   1136         if(((i4_Ci + i4_sd) == i4_Mi) || (1 == ps_lap_struct->i4_fixed_i_period))
   1137         {
   1138             i4_num_b_frames = i4_Mi - i4_Ci - 1;
   1139             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1140             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_I;
   1141             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
   1142             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
   1143             ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
   1144             ps_lap_struct->i4_i_counter = 0;
   1145         }
   1146         else
   1147         {
   1148             ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_I;
   1149             i4_num_b_frames = i4_sd - 1;
   1150             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1151             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
   1152             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
   1153             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
   1154             ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
   1155             ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided;
   1156         }
   1157     }
   1158     /* if next sub-gop is not going to be idr,cra,I*/
   1159     else
   1160     {
   1161         i4_num_b_frames = i4_sd - 1;
   1162         memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
   1163         ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
   1164         ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
   1165         ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
   1166         ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
   1167         ps_lap_struct->i4_i_counter += ps_lap_struct->i4_num_frm_type_decided;
   1168     }
   1169     ASSERT(i4_num_b_frames != -1);
   1170 
   1171     return;
   1172 }
   1173 
   1174 /*!
   1175 ************************************************************************
   1176 * \brief
   1177 *    assign pic type to input buf
   1178 ************************************************************************
   1179 */
   1180 void ihevce_assign_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_inp_buf)
   1181 {
   1182     WORD8 pic_type = ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
   1183 
   1184     switch(pic_type)
   1185     {
   1186     case PIC_TYPE_I:
   1187     {
   1188         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME;
   1189         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
   1190         ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1;
   1191         break;
   1192     }
   1193     case PIC_TYPE_P:
   1194     {
   1195         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_P_FRAME;
   1196         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
   1197         break;
   1198     }
   1199     case PIC_TYPE_B:
   1200     {
   1201         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_B_FRAME;
   1202         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
   1203         break;
   1204     }
   1205     case PIC_TYPE_IDR:
   1206     {
   1207         ps_lap_struct->i4_curr_poc = 0;
   1208         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_IDR_FRAME;
   1209         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
   1210         break;
   1211     }
   1212     case PIC_TYPE_CRA:
   1213     {
   1214         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME;
   1215         ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1;
   1216         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 1;
   1217         break;
   1218     }
   1219     default:
   1220         ASSERT(0);
   1221     }
   1222     return;
   1223 }
   1224 
   1225 /*!
   1226 ************************************************************************
   1227 * \brief
   1228 *    capture order traversal nodes
   1229 ************************************************************************
   1230 */
   1231 void ihevce_encode_order_traversal_nodes(
   1232     ihevce_encode_node_t *encode_node_t,
   1233     ihevce_lap_enc_buf_t **encode_order,
   1234     WORD32 *loop_count,
   1235     WORD32 curr_layer,
   1236     lap_struct_t *ps_lap_struct)
   1237 {
   1238     if(encode_node_t == NULL)
   1239         return;
   1240 
   1241     encode_order[*loop_count] = (ihevce_lap_enc_buf_t *)encode_node_t->ps_lap_top_buff;
   1242 
   1243     if(encode_order[*loop_count] != NULL)
   1244     {
   1245         ihevce_lap_enc_buf_t *ps_lap_inp;
   1246 
   1247         ps_lap_struct->pi4_encode_poc_ptr[0] = encode_node_t->data;
   1248         ref_b_pic_population(curr_layer, encode_order[*loop_count], ps_lap_struct);
   1249 
   1250         ps_lap_inp = (ihevce_lap_enc_buf_t *)encode_order[*loop_count];
   1251         ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
   1252 
   1253         ps_lap_struct->pi4_encode_poc_ptr++;
   1254     }
   1255 
   1256     (*loop_count) = (*loop_count) + 1;
   1257 
   1258     /* Pre-order Left-node traversal*/
   1259     ihevce_encode_order_traversal_nodes(
   1260         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
   1261         encode_order,
   1262         loop_count,
   1263         curr_layer + 1,
   1264         ps_lap_struct);
   1265 
   1266     /* Pre-order Right-node traversal*/
   1267     ihevce_encode_order_traversal_nodes(
   1268         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
   1269         encode_order,
   1270         loop_count,
   1271         curr_layer + 1,
   1272         ps_lap_struct);
   1273 }
   1274 
   1275 /*!
   1276 ************************************************************************
   1277 * \brief
   1278 *    capture order traversal nodes
   1279 ************************************************************************
   1280 */
   1281 void ihevce_capture_order_traversal_nodes(
   1282     ihevce_encode_node_t *encode_node_t,
   1283     ihevce_lap_enc_buf_t **api4_capture_order_array,
   1284     WORD32 *capture_order_poc_array,
   1285     WORD32 *loop_count,
   1286     WORD32 i4_interlace_field)
   1287 {
   1288     if(encode_node_t == NULL)
   1289         return;
   1290 
   1291     /* Inorder Insertion for the left-child node */
   1292     ihevce_capture_order_traversal_nodes(
   1293         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
   1294         api4_capture_order_array,
   1295         capture_order_poc_array,
   1296         loop_count,
   1297         i4_interlace_field);
   1298 
   1299     if(i4_interlace_field)
   1300     {
   1301         encode_node_t->ps_lap_top_buff =
   1302             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count];
   1303         encode_node_t->data = capture_order_poc_array[*loop_count];
   1304         encode_node_t->ps_lap_bottom_buff =
   1305             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count + 1];
   1306     }
   1307     else
   1308     {
   1309         encode_node_t->ps_lap_top_buff =
   1310             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count];
   1311         encode_node_t->data = capture_order_poc_array[*loop_count];
   1312     }
   1313     if(i4_interlace_field)
   1314         (*loop_count) = (*loop_count) + 2;
   1315     else
   1316         (*loop_count) = (*loop_count) + 1;
   1317 
   1318     /* Inorder Insertion for the right-child node */
   1319     ihevce_capture_order_traversal_nodes(
   1320         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
   1321         api4_capture_order_array,
   1322         capture_order_poc_array,
   1323         loop_count,
   1324         i4_interlace_field);
   1325 }
   1326 
   1327 /*!
   1328 ************************************************************************
   1329 * \brief
   1330 *    I/P pic population
   1331 ************************************************************************
   1332 */
   1333 void ihevce_ip_pic_population(
   1334     ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct, WORD32 i4_first_gop)
   1335 {
   1336     ihevce_lap_enc_buf_t *ps_lap_inp = NULL;
   1337     WORD32 hier_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
   1338     WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size;
   1339     ihevce_lap_enc_buf_t **api4_capture_order_array = ps_lap_struct->api4_capture_order_array;
   1340     ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array;
   1341     WORD32 *ai4_capture_order_poc = ps_lap_struct->pi4_capture_poc_ptr;
   1342 
   1343     /* Populate the encode order POC dependent on IDR frames and Interlace Field*/
   1344     if(1 == ps_lap_struct->i4_idr_flag)
   1345     {
   1346         if(i4_first_gop)
   1347         {
   1348             api4_encode_order_array[0] = api4_capture_order_array[0];
   1349 
   1350             if(api4_encode_order_array[0] != NULL)
   1351             {
   1352                 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[0];
   1353                 ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
   1354 
   1355                 ps_lap_inp = api4_encode_order_array[0];
   1356                 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
   1357 
   1358                 ps_lap_struct->pi4_encode_poc_ptr++;
   1359             }
   1360 
   1361             if(ps_lap_struct->i4_immediate_idr_case != 1)
   1362             {
   1363                 api4_encode_order_array[1] = api4_capture_order_array[sub_gop_size];
   1364 
   1365                 if(api4_encode_order_array[1] != NULL)
   1366                 {
   1367                     ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size];
   1368                     ref_pic_population(api4_encode_order_array[1], ps_lap_struct);
   1369 
   1370                     ps_lap_inp = api4_encode_order_array[1];
   1371                     ihevce_rc_populate_common_params(
   1372                         &ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
   1373 
   1374                     ps_lap_struct->pi4_encode_poc_ptr++;
   1375                 }
   1376             }
   1377         }
   1378         else
   1379         {
   1380             api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1];
   1381 
   1382             if(api4_encode_order_array[0] != NULL)
   1383             {
   1384                 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1];
   1385                 ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
   1386 
   1387                 ps_lap_inp = api4_encode_order_array[0];
   1388                 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
   1389 
   1390                 ps_lap_struct->pi4_encode_poc_ptr++;
   1391             }
   1392         }
   1393     }
   1394     else
   1395     {
   1396         api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1];
   1397 
   1398         if(api4_encode_order_array[0] != NULL)
   1399         {
   1400             ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1];
   1401             ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
   1402 
   1403             ps_lap_inp = api4_encode_order_array[0];
   1404             ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
   1405 
   1406             ps_lap_struct->pi4_encode_poc_ptr++;
   1407         }
   1408     }
   1409     return;
   1410 }
   1411 
   1412 /*!
   1413 ************************************************************************
   1414 * \brief
   1415 *    B pic population
   1416 ************************************************************************
   1417 */
   1418 void ihevce_b_pic_population(ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct)
   1419 {
   1420     WORD32 interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
   1421     ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array;
   1422     WORD32 *capture_order_poc_array = ps_lap_struct->pi4_capture_poc_ptr;
   1423     WORD32 loop_count = 0;
   1424 
   1425     /* encoder_order offset changed dependent on IDR and Interlace Field */
   1426     if(ps_lap_struct->i4_idr_flag)
   1427         loop_count = 1 + interlace_field;
   1428 
   1429     /* Inorder Insertion of POC in tree, for capture order */
   1430     ihevce_capture_order_traversal_nodes(
   1431         ps_encode_node,
   1432         &ps_lap_struct->api4_capture_order_array[0],
   1433         capture_order_poc_array,
   1434         &loop_count,
   1435         interlace_field);
   1436 
   1437     /* encoder_order offset changed dependent on IDR and Interlace Field */
   1438     /* If the gop_size is multiple of CRA period , decrement loop count */
   1439     if(ps_lap_struct->i4_idr_flag)
   1440         loop_count = 2 + (interlace_field * 2);
   1441     else
   1442         loop_count = 1 + interlace_field;
   1443 
   1444     /* Pre-order traversal of the tree to get encode-order POCs*/
   1445     ihevce_encode_order_traversal_nodes(
   1446         ps_encode_node, api4_encode_order_array, &loop_count, 1, ps_lap_struct);
   1447 
   1448     return;
   1449 }
   1450 
   1451 /*!
   1452 ************************************************************************
   1453 * \brief
   1454 *    rc_update_model_control_by_lap_for_modified_sub_gop
   1455 ************************************************************************
   1456 */
   1457 void rc_update_model_control_by_lap_for_modified_sub_gop(
   1458     lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
   1459 {
   1460     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_out_buf->s_lap_out;
   1461 
   1462     /* model update flag for rc*/
   1463     if(ps_lap_out->i4_pic_type == IV_P_FRAME)
   1464     {
   1465         WORD32 i4_loop = 0;
   1466         WORD32 i4_min_delta_poc = 0x7FFFFFFF;
   1467 
   1468         for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++)
   1469         {
   1470             if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc))
   1471             {
   1472                 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc);
   1473             }
   1474         }
   1475     }
   1476 
   1477     if(ps_lap_out->i4_pic_type == IV_B_FRAME)
   1478     {
   1479         WORD32 i4_loop = 0;
   1480         WORD32 i4_min_delta_poc = 0x7FFFFFFF;
   1481         WORD32 i4_min_delta_poc_for_b =
   1482             (1 << ps_lap_struct->s_lap_static_params.i4_max_temporal_layers) /
   1483             (ps_lap_out->i4_temporal_lyr_id + 1);
   1484 
   1485         for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++)
   1486         {
   1487             if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc))
   1488             {
   1489                 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc);
   1490             }
   1491         }
   1492     }
   1493     return;
   1494 }
   1495 
   1496 /*!
   1497 ************************************************************************
   1498 * \brief
   1499 *    Update num of pic type for rc
   1500 ************************************************************************
   1501 */
   1502 void update_rc_num_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
   1503 {
   1504     WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
   1505     rc_lap_out_params_t *ps_rc_lap_out = &ps_lap_out_buf->s_rc_lap_out;
   1506 
   1507     ps_lap_struct->i4_lap2_counter++;
   1508 
   1509     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_I_FRAME ||
   1510        ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME)
   1511     {
   1512         ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = I_PIC;
   1513         GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1514     }
   1515     else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME)
   1516     {
   1517         if(ps_lap_out_buf->s_lap_out.i4_first_field)
   1518         {
   1519             ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P_PIC;
   1520         }
   1521         else
   1522         {
   1523             ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P1_PIC;
   1524         }
   1525         GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1526     }
   1527     else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME)
   1528     {
   1529         if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 1)
   1530         {
   1531             if(ps_lap_out_buf->s_lap_out.i4_first_field)
   1532             {
   1533                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B_PIC;
   1534             }
   1535             else
   1536             {
   1537                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = BB_PIC;
   1538             }
   1539             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1540         }
   1541         else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 2)
   1542         {
   1543             if(ps_lap_out_buf->s_lap_out.i4_first_field)
   1544             {
   1545                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B1_PIC;
   1546             }
   1547             else
   1548             {
   1549                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B11_PIC;
   1550             }
   1551             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1552         }
   1553         else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 3)
   1554         {
   1555             if(ps_lap_out_buf->s_lap_out.i4_first_field)
   1556             {
   1557                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B2_PIC;
   1558             }
   1559             else
   1560             {
   1561                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B22_PIC;
   1562             }
   1563             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1564         }
   1565         else
   1566         {
   1567             ASSERT(0);
   1568         }
   1569     }
   1570     else
   1571     {
   1572         ASSERT(0);
   1573     }
   1574 
   1575     if(!ps_lap_struct->i4_rc_lap_period)
   1576     {
   1577         if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period)
   1578         {
   1579             WORD32 i4_loop;
   1580             WORD32 idx = 0;
   1581             WORD32 i4_max_temporal_layer =
   1582                 ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
   1583 
   1584             for(i4_loop = 0;
   1585                 i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period);
   1586                 i4_loop++)
   1587             {
   1588                 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
   1589 
   1590                 if(i4_max_temporal_layer == 0)
   1591                 {
   1592                     if(ps_lap_struct->i4_is_all_i_pic_in_seq)
   1593                     {
   1594                         ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
   1595                     }
   1596                     else
   1597                     {
   1598                         /*second field*/
   1599                         if((i4_loop & 1) && i4_field_flag)
   1600                         {
   1601                             ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
   1602                         }
   1603                         else
   1604                         {
   1605                             ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
   1606                         }
   1607                     }
   1608                 }
   1609                 else
   1610                 {
   1611                     ps_rc_lap_out->ai4_num_pic_type
   1612                         [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
   1613 
   1614                     GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
   1615                 }
   1616             }
   1617         }
   1618     }
   1619     else
   1620     {
   1621         ASSERT(ps_lap_struct->i4_lap2_counter <= ps_lap_struct->i4_rc_lap_period);
   1622 
   1623         if(ps_lap_struct->i4_lap2_counter == ps_lap_struct->i4_rc_lap_period)
   1624         {
   1625             WORD32 i4_loop, i4_period, i4_next_i_pic = 0;
   1626             WORD32 i4_stop_count = 0;
   1627             WORD32 i4_temp_deq = ps_lap_struct->i4_deq_idx;
   1628             WORD32 i4_first_pic_type = ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq];
   1629 
   1630             if(ps_lap_struct->i4_rc_lap_period >= ps_lap_struct->i4_gop_period)
   1631             {
   1632                 i4_period = ps_lap_struct->i4_gop_period;
   1633             }
   1634             else
   1635             {
   1636                 i4_period = ps_lap_struct->i4_rc_lap_period;
   1637             }
   1638 
   1639             for(i4_loop = 0; i4_loop < i4_period; i4_loop++)
   1640             {
   1641                 if(ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq] == I_PIC && i4_loop &&
   1642                    i4_first_pic_type == I_PIC)
   1643                 {
   1644                     i4_stop_count = 1;
   1645                 }
   1646 
   1647                 if(!i4_stop_count)
   1648                 {
   1649                     ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
   1650                 }
   1651 
   1652                 ps_rc_lap_out
   1653                     ->ai4_num_pic_type[ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq]]++;
   1654 
   1655                 GET_IDX_CIRCULAR_BUF(i4_temp_deq, 1, NUM_LAP2_LOOK_AHEAD);
   1656             }
   1657             if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period)
   1658             {
   1659                 WORD32 i4_loop;
   1660                 WORD32 idx = 0;
   1661                 WORD32 i4_max_temporal_layer =
   1662                     ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
   1663 
   1664                 for(i4_loop = 0;
   1665                     i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period) &&
   1666                     (!i4_next_i_pic);
   1667                     i4_loop++)
   1668                 {
   1669                     if(!i4_stop_count)
   1670                     {
   1671                         ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
   1672                     }
   1673 
   1674                     if(i4_max_temporal_layer == 0)
   1675                     {
   1676                         if(ps_lap_struct->i4_is_all_i_pic_in_seq)
   1677                         {
   1678                             ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
   1679                         }
   1680                         else
   1681                         {
   1682                             /*second field*/
   1683                             if((i4_loop & 1) && i4_field_flag)
   1684                             {
   1685                                 ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
   1686                             }
   1687                             else
   1688                             {
   1689                                 ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
   1690                             }
   1691                         }
   1692                     }
   1693                     else
   1694                     {
   1695                         ps_rc_lap_out->ai4_num_pic_type
   1696                             [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
   1697                         GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
   1698                     }
   1699                 }
   1700             }
   1701             /*remove one pic type*/
   1702             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_deq_idx, 1, NUM_LAP2_LOOK_AHEAD);
   1703             ps_lap_struct->i4_lap2_counter--;
   1704         }
   1705     }
   1706 
   1707     {
   1708         WORD32 i4_loop;
   1709         WORD32 idx = 0;
   1710         WORD32 i4_max_temporal_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
   1711         WORD32 i4_num_pictype = 0;
   1712 
   1713         for(i4_loop = 0; i4_loop < MAX_PIC_TYPE; i4_loop++)
   1714         {
   1715             i4_num_pictype += ps_rc_lap_out->ai4_num_pic_type[i4_loop];
   1716         }
   1717 
   1718         if(!i4_num_pictype)
   1719         {
   1720             ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead = ps_lap_struct->i4_gop_period;
   1721 
   1722             for(i4_loop = 0; i4_loop < (ps_lap_struct->i4_gop_period); i4_loop++)
   1723             {
   1724                 if(i4_max_temporal_layer == 0)
   1725                 {
   1726                     if(ps_lap_struct->i4_is_all_i_pic_in_seq)
   1727                     {
   1728                         ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
   1729                     }
   1730                     else
   1731                     {
   1732                         /*second field*/
   1733                         if((i4_loop & 1) && i4_field_flag)
   1734                         {
   1735                             ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
   1736                         }
   1737                         else
   1738                         {
   1739                             ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
   1740                         }
   1741                     }
   1742                 }
   1743                 else
   1744                 {
   1745                     ps_rc_lap_out->ai4_num_pic_type
   1746                         [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
   1747 
   1748                     GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
   1749                 }
   1750             }
   1751         }
   1752     }
   1753     /*FOR RC : ensure  at least 1 I pic in the gop period at any case*/
   1754     if(!ps_rc_lap_out->ai4_num_pic_type[I_PIC])
   1755     {
   1756         ASSERT(ps_rc_lap_out->ai4_num_pic_type[P_PIC]);
   1757         ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[P_PIC]--;
   1758         ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[I_PIC]++;
   1759     }
   1760     return;
   1761 }
   1762 
   1763 /*!
   1764 ************************************************************************
   1765 * \brief
   1766 *    pre rel lap output update
   1767 ************************************************************************
   1768 */
   1769 void ihevce_pre_rel_lapout_update(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
   1770 {
   1771     WORD32 i4_first_field = 1;
   1772     WORD32 i4_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
   1773 
   1774     if(i4_field)
   1775     {
   1776         i4_first_field = ps_lap_out_buf->s_lap_out.i4_first_field;
   1777     }
   1778 
   1779     ps_lap_out_buf->s_lap_out.i4_used = 0;
   1780 
   1781     rc_update_model_control_by_lap_for_modified_sub_gop(ps_lap_struct, ps_lap_out_buf);
   1782     update_rc_num_pic_type(ps_lap_struct, ps_lap_out_buf);
   1783 
   1784     /* curr buf next is null, prev buf next is curr and prev buff equal to curr*/
   1785 
   1786     ps_lap_out_buf->s_rc_lap_out.ps_rc_lap_out_next_encode = NULL;
   1787     if(ps_lap_struct->pv_prev_inp_buf != NULL &&
   1788        ps_lap_struct->s_lap_static_params.s_lap_params.i4_rc_look_ahead_pics)
   1789     {
   1790         ((ihevce_lap_enc_buf_t *)ps_lap_struct->pv_prev_inp_buf)
   1791             ->s_rc_lap_out.ps_rc_lap_out_next_encode = (void *)&ps_lap_out_buf->s_rc_lap_out;
   1792     }
   1793 
   1794     ps_lap_struct->pv_prev_inp_buf = (void *)ps_lap_out_buf;
   1795     ps_lap_out_buf->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene = 0;
   1796 
   1797     /*with force idr below check is not valid*/
   1798 #if(!FORCE_IDR_TEST)
   1799     if(ps_lap_struct->i4_max_idr_period == ps_lap_struct->i4_min_idr_period)
   1800     {
   1801         if(!ps_lap_out_buf->s_lap_out.i4_poc)
   1802         {
   1803             ASSERT(ps_lap_struct->i4_max_prev_poc == (ps_lap_struct->i4_max_idr_period - 1));
   1804             ps_lap_struct->i4_max_prev_poc = 0;
   1805         }
   1806     }
   1807 #endif
   1808 
   1809     /*assert if num of reference frame is zero in case of P or B frame*/
   1810     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME ||
   1811        ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME)
   1812     {
   1813         ASSERT(ps_lap_out_buf->s_lap_out.i4_num_ref_pics != 0);
   1814     }
   1815 
   1816     /*assert if poc = 0 and pictype is not an idr*/
   1817     if(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
   1818        ps_lap_out_buf->s_lap_out.i4_poc == 0)
   1819     {
   1820         ASSERT(0);
   1821     }
   1822     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME &&
   1823        ps_lap_out_buf->s_lap_out.i4_poc != 0)
   1824     {
   1825         ASSERT(0);
   1826     }
   1827     if(ps_lap_out_buf->s_lap_out.i4_poc < 0)
   1828     {
   1829         ASSERT(0);
   1830     }
   1831 
   1832 #if(!FORCE_IDR_TEST)
   1833     if((!ps_lap_struct->i4_max_idr_period) && ps_lap_out_buf->s_lap_out.i4_display_num != 0)
   1834     {
   1835         ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME);
   1836     }
   1837 #endif
   1838     if(!ps_lap_struct->i4_max_cra_period)
   1839     {
   1840         ASSERT(ps_lap_out_buf->s_lap_out.i4_is_cra_pic != 1);
   1841     }
   1842 
   1843     if(ps_lap_out_buf->s_lap_out.i4_force_idr_flag)
   1844     {
   1845         ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME);
   1846     }
   1847     ps_lap_out_buf->s_lap_out.i4_curr_frm_qp = -1;
   1848 }
   1849 
   1850 /*!
   1851 ************************************************************************
   1852 * \brief
   1853 *    lap queue input
   1854 ************************************************************************
   1855 */
   1856 void ihevce_lap_queue_input(
   1857     lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_input_lap_enc_buf, WORD32 *pi4_tree_num)
   1858 {
   1859     ihevce_encode_node_t *ps_encode_node =
   1860         (ihevce_encode_node_t *)ps_lap_struct->aps_encode_node[*pi4_tree_num];
   1861 
   1862     WORD32 i4_capture_idx = ps_lap_struct->i4_capture_idx;
   1863 
   1864     /* Static Lap parameters */
   1865     ihevce_lap_static_params_t *ps_lap_static_params =
   1866         (ihevce_lap_static_params_t *)&ps_lap_struct->s_lap_static_params;
   1867 
   1868     WORD32 hier_layer = ps_lap_static_params->i4_max_temporal_layers;
   1869     WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size;
   1870 
   1871     /* queue the current input in capture array */
   1872     {
   1873         WORD32 first_gop_flag;
   1874 
   1875         if(!i4_capture_idx)
   1876         {
   1877             memset(
   1878                 &ps_lap_struct->api4_capture_order_array[0],
   1879                 0,
   1880                 sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES);
   1881         }
   1882         ps_lap_struct->api4_capture_order_array[i4_capture_idx] = ps_input_lap_enc_buf;
   1883 
   1884         if(ps_input_lap_enc_buf != NULL)
   1885         {
   1886             if(ps_input_lap_enc_buf->s_lap_out.i4_end_flag == 1)
   1887                 ps_lap_struct->i4_end_flag_pic_idx = i4_capture_idx;
   1888             ps_lap_struct->ai4_capture_order_poc[i4_capture_idx] = ps_lap_struct->i4_curr_poc++;
   1889         }
   1890         i4_capture_idx++;
   1891 
   1892         /* to take care of buffering 1 extra picture at start or at IDR interval*/
   1893         if(!ps_lap_struct->i4_is_all_i_pic_in_seq)
   1894         {
   1895             if(ps_lap_static_params->i4_src_interlace_field && sub_gop_size <= 2)
   1896             {
   1897                 first_gop_flag = 0;
   1898             }
   1899             else
   1900             {
   1901                 first_gop_flag = ps_lap_struct->i4_idr_flag
   1902                                  << ps_lap_static_params->i4_src_interlace_field;
   1903             }
   1904         }
   1905         else
   1906         {
   1907             first_gop_flag = ps_lap_struct->i4_idr_flag;
   1908         }
   1909 
   1910         /* For every IDR period, set idr_flag and reset POC value and gop_size to 0*/
   1911         if(ps_input_lap_enc_buf != NULL)
   1912         {
   1913             if((!first_gop_flag) && (ps_input_lap_enc_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME))
   1914             {
   1915                 ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
   1916                 ps_lap_struct->i4_idr_flag = 1;
   1917                 ps_lap_struct->i4_curr_poc = 0;
   1918                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] =
   1919                     ps_lap_struct->i4_curr_poc++;
   1920             }
   1921         }
   1922 
   1923         if(first_gop_flag &&
   1924            (ps_lap_struct->i4_is_all_i_pic_in_seq || ps_lap_struct->i4_immediate_idr_case))
   1925         {
   1926             sub_gop_size = 0;
   1927         }
   1928 
   1929         if(!first_gop_flag && ps_lap_struct->i4_immediate_idr_case &&
   1930            (i4_capture_idx != (sub_gop_size + first_gop_flag)))
   1931         {
   1932             sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field;
   1933             ps_lap_struct->i4_dyn_sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field;
   1934         }
   1935 
   1936         /* reset the queue idx end of every gop */
   1937         if(i4_capture_idx == (sub_gop_size + first_gop_flag))
   1938         {
   1939             if(ps_lap_struct->i4_end_flag_pic_idx)
   1940             {
   1941                 WORD32 i4_temp_poc = 0;
   1942                 ihevce_lap_enc_buf_t *ps_temp_lap_enc_buf = NULL;
   1943 
   1944                 /*swap the lap enc buf and poc*/
   1945                 ps_temp_lap_enc_buf =
   1946                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1];
   1947                 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1] =
   1948                     NULL;
   1949                 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 2] =
   1950                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx];
   1951 
   1952                 if((i4_capture_idx - 2) != ps_lap_struct->i4_end_flag_pic_idx)
   1953                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx] =
   1954                         NULL;
   1955 
   1956                 ps_temp_lap_enc_buf->s_lap_out.i4_pic_type = IV_P_FRAME;
   1957                 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 1] = ps_temp_lap_enc_buf;
   1958 
   1959                 i4_temp_poc =
   1960                     ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx - 1];
   1961                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 2] =
   1962                     ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx];
   1963 
   1964                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] = i4_temp_poc;
   1965             }
   1966             i4_capture_idx = 0;
   1967 
   1968             /* add the number of pics in sub gop to the gop counter */
   1969             /* Get reordered Buffer for encoder, wait till all sub-gop buffers are output */
   1970 
   1971             /* Popluate I/P pictures */
   1972             ihevce_ip_pic_population(ps_encode_node, ps_lap_struct, first_gop_flag);
   1973 
   1974             /* For hierarchical layers, Populate B picture */
   1975             if((hier_layer > 0) &&
   1976                sub_gop_size > (1 << ps_lap_static_params->i4_src_interlace_field))
   1977             {
   1978                 ihevce_b_pic_population(ps_encode_node, ps_lap_struct);
   1979             }
   1980 
   1981             ps_lap_struct->i4_num_bufs_encode_order = sub_gop_size + first_gop_flag;
   1982 
   1983             /* correction of encode order in case of multiple non reference B*/
   1984             if(ps_lap_struct->i4_dyn_sub_gop_size > ps_lap_struct->i4_sub_gop_size)
   1985             {
   1986                 WORD32 i4_loop;
   1987                 ihevce_lap_enc_buf_t *ps_lap_enc_buf, *ps_lap_enc_buf_tmp[MAX_NUM_ENC_NODES];
   1988                 WORD32 i4_enc_cnt, i4_cap_cnt;
   1989 
   1990                 i4_cap_cnt = first_gop_flag;
   1991                 i4_enc_cnt = 0;
   1992 
   1993                 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++)
   1994                 {
   1995                     ps_lap_enc_buf = ps_lap_struct->api4_encode_order_array[i4_loop];
   1996 
   1997                     if(ps_lap_enc_buf != NULL && !ps_lap_enc_buf->s_lap_out.i4_is_ref_pic &&
   1998                        (ps_lap_enc_buf->s_lap_out.i4_temporal_lyr_id ==
   1999                         ps_lap_struct->s_lap_static_params.i4_max_temporal_layers))
   2000                     {
   2001                         if(ps_lap_enc_buf != ps_lap_struct->api4_capture_order_array[i4_cap_cnt])
   2002                         {
   2003                             ps_lap_enc_buf_tmp[i4_enc_cnt] =
   2004                                 ps_lap_struct->api4_capture_order_array[i4_cap_cnt];
   2005                             i4_enc_cnt++;
   2006                             i4_loop++;
   2007                         }
   2008                         i4_cap_cnt += 2;
   2009                         ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf;
   2010                         i4_enc_cnt++;
   2011                         ps_lap_enc_buf_tmp[i4_enc_cnt] =
   2012                             ps_lap_struct->api4_capture_order_array[i4_cap_cnt];
   2013                         i4_enc_cnt++;
   2014                         i4_cap_cnt += 2;
   2015                         i4_loop++;
   2016                     }
   2017                     else
   2018                     {
   2019                         ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf;
   2020                         i4_enc_cnt++;
   2021                     }
   2022                 }
   2023                 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++)
   2024                 {
   2025                     ps_lap_struct->api4_encode_order_array[i4_loop] = ps_lap_enc_buf_tmp[i4_loop];
   2026                 }
   2027             }
   2028 
   2029             /* reset the IDR flag */
   2030             ps_lap_struct->i4_idr_flag = 0;
   2031             ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size;
   2032         }
   2033 
   2034         if(0 == ps_lap_struct->i4_lap_out_idx)
   2035             ps_lap_struct->i4_max_buf_in_enc_order = ps_lap_struct->i4_num_bufs_encode_order;
   2036 
   2037         /* store the capture index */
   2038         ps_lap_struct->i4_capture_idx = i4_capture_idx;
   2039         ps_lap_struct->i4_immediate_idr_case = 0;
   2040     }
   2041     return;
   2042 }
   2043 
   2044 /*!
   2045 ************************************************************************
   2046 * \brief
   2047 *    lap process
   2048 ************************************************************************
   2049 */
   2050 ihevce_lap_enc_buf_t *ihevce_lap_process(void *pv_interface_ctxt, ihevce_lap_enc_buf_t *ps_curr_inp)
   2051 {
   2052     lap_intface_t *ps_lap_interface = (lap_intface_t *)pv_interface_ctxt;
   2053     lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_lap_interface->pv_lap_module_ctxt;
   2054     ihevce_hle_ctxt_t *ps_hle_ctxt = (ihevce_hle_ctxt_t *)ps_lap_interface->pv_hle_ctxt;
   2055     ihevce_lap_enc_buf_t *ps_lap_inp_buf = ps_curr_inp;
   2056     ihevce_tgt_params_t *ps_tgt_params =
   2057         &ps_lap_struct->s_static_cfg_params.s_tgt_lyr_prms.as_tgt_params[0];
   2058     WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
   2059     WORD32 i4_num_frames_after_force_idr = ps_lap_struct->i4_num_frames_after_force_idr;
   2060     WORD32 i4_flush_check = 0;
   2061     WORD32 i4_force_idr_check = 0;
   2062     WORD32 i4_set_res_check = 0;
   2063     WORD32 i4_tree_num = 0;
   2064     iv_input_ctrl_buffs_t *ps_ctrl_buf = NULL;
   2065     WORD32 buf_id = 0;
   2066 
   2067     ps_lap_interface->i4_ctrl_in_que_blocking_mode = BUFF_QUE_NON_BLOCKING_MODE;
   2068 
   2069     /* ----------- LAP processing ----------- */
   2070     if(ps_lap_struct->end_flag != 1)
   2071     {
   2072         ASSERT(NULL != ps_curr_inp);
   2073 
   2074         /* ---------- get the filled control command buffer ------------ */
   2075         ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_filled_buff(
   2076             ps_hle_ctxt->apv_enc_hdl[0],
   2077             ps_lap_interface->i4_ctrl_in_que_id,
   2078             &buf_id,
   2079             ps_lap_interface->i4_ctrl_in_que_blocking_mode);
   2080 
   2081         /* ----------- check the command ---------------------- */
   2082         if(NULL != ps_ctrl_buf)
   2083         {
   2084             /* check for async errors */
   2085             ihevce_dyn_config_prms_t as_dyn_br[MAX_NUM_DYN_BITRATE_CMDS];
   2086             WORD32 i4_num_set_bitrate_cmds = 0;
   2087             WORD32 bitrt_ctr = 0;
   2088 
   2089             ihevce_lap_parse_async_cmd(
   2090                 ps_hle_ctxt,
   2091                 (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs,
   2092                 ps_ctrl_buf->i4_cmd_buf_size,
   2093                 ps_ctrl_buf->i4_buf_id,
   2094                 &i4_num_set_bitrate_cmds,
   2095                 &as_dyn_br[0]);
   2096 
   2097             /* Call the call back function to register the new bitrate */
   2098             for(bitrt_ctr = 0; bitrt_ctr < i4_num_set_bitrate_cmds; bitrt_ctr++)
   2099             {
   2100                 ps_lap_interface->ihevce_dyn_bitrate_cb(
   2101                     (void *)ps_hle_ctxt, (void *)&as_dyn_br[bitrt_ctr]);
   2102             }
   2103         }
   2104 
   2105         {
   2106             WORD32 *pi4_cmd_buf = (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs;
   2107 
   2108             /* check for sync cmd buffer error */
   2109             /* check FLUSH comand and Force IDR in the complete buffer */
   2110             i4_flush_check = 0;
   2111             i4_force_idr_check = 0;
   2112             i4_set_res_check = 0;
   2113             ihevce_lap_parse_sync_cmd(
   2114                 ps_hle_ctxt,
   2115                 &ps_lap_struct->s_static_cfg_params,
   2116                 pi4_cmd_buf,
   2117                 ps_lap_inp_buf,
   2118                 &i4_flush_check,
   2119                 &i4_force_idr_check,
   2120                 &i4_set_res_check,
   2121                 &i4_num_frames_after_force_idr);
   2122 
   2123             if(i4_flush_check)
   2124                 ps_lap_struct->end_flag = 1;
   2125 
   2126             ps_lap_inp_buf->s_lap_out.i4_out_flush_flag = 0;
   2127             ps_lap_inp_buf->s_lap_out.i4_end_flag = ps_lap_struct->end_flag;
   2128 
   2129             /* check if input buffer is a valid buffer */
   2130             if(1 == ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag)
   2131             {
   2132                 /* Initialise laps input buffer descriptors */
   2133                 memset(&ps_lap_inp_buf->s_lap_out, 0, sizeof(ihevce_lap_output_params_t));
   2134                 memset(&ps_lap_inp_buf->s_rc_lap_out, 0, sizeof(rc_lap_out_params_t));
   2135                 /* Default initialization of lapout parameters */
   2136                 ps_lap_inp_buf->s_lap_out.i4_scene_type = SCENE_TYPE_NORMAL;
   2137                 ps_lap_inp_buf->s_lap_out.u4_scene_num = 0;
   2138                 ps_lap_inp_buf->s_lap_out.i4_display_num = ps_lap_struct->i4_display_num;
   2139                 ps_lap_inp_buf->s_lap_out.i4_quality_preset = ps_tgt_params->i4_quality_preset;
   2140                 ps_lap_inp_buf->s_lap_out.i1_weighted_pred_flag = 0;
   2141                 ps_lap_inp_buf->s_lap_out.i1_weighted_bipred_flag = 0;
   2142                 ps_lap_inp_buf->s_lap_out.i4_log2_luma_wght_denom = DENOM_DEFAULT;
   2143                 ps_lap_inp_buf->s_lap_out.i4_log2_chroma_wght_denom = DENOM_DEFAULT;
   2144                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_num_duplicate_entries_in_ref_list = 1;
   2145                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_used_by_cur_pic_flag = 1;
   2146                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].as_wght_off[0].u1_luma_weight_enable_flag =
   2147                     0;
   2148                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0]
   2149                     .as_wght_off[0]
   2150                     .u1_chroma_weight_enable_flag = 0;
   2151                 ps_lap_inp_buf->s_lap_out.i4_first_field = 1;
   2152                 ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0;
   2153                 ps_lap_inp_buf->s_lap_out.i4_curr_frm_qp = ps_tgt_params->ai4_frame_qp[0];
   2154                 ps_lap_inp_buf->s_lap_out.i4_used = 1;
   2155                 if(i4_force_idr_check)
   2156                 {
   2157                     ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 1;
   2158                 }
   2159                 ASSERT(i4_set_res_check == 0);
   2160 
   2161                 /* Populate input params in lap out struct */
   2162                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_y_buf =
   2163                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_y_buf;
   2164                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_u_buf =
   2165                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_u_buf;
   2166                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_v_buf =
   2167                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_v_buf;
   2168                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_wd =
   2169                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_wd;
   2170                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_ht =
   2171                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_ht;
   2172                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_strd =
   2173                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_strd;
   2174                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_wd =
   2175                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_wd;
   2176                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_ht =
   2177                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_ht;
   2178                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_strd =
   2179                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_strd;
   2180 
   2181                 ps_lap_struct->i4_display_num++;
   2182                 i4_num_frames_after_force_idr++;
   2183 
   2184                 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf;
   2185                 /* update first field flag */
   2186                 ps_lap_inp_buf->s_lap_out.i4_first_field = 1;
   2187                 if(i4_field_flag)
   2188                 {
   2189                     ps_lap_inp_buf->s_lap_out.i4_first_field =
   2190                         (ps_lap_inp_buf->s_input_buf.i4_topfield_first ^
   2191                          ps_lap_inp_buf->s_input_buf.i4_bottom_field);
   2192                 }
   2193 
   2194                 /* force idr in case interlace input can be taken only for first field */
   2195                 if(!ps_lap_inp_buf->s_lap_out.i4_first_field)
   2196                 {
   2197                     ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0;
   2198                 }
   2199 
   2200                 /*to be filed*/
   2201                 if(0 ==
   2202                    ps_lap_struct->i4_num_frm_type_decided /*&& ps_lap_struct->i4_init_delay_over*/)
   2203                 {
   2204                     ps_lap_struct->ai1_pic_type[0] =
   2205                         ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
   2206 
   2207                     ihevce_determine_next_sub_gop_state(ps_lap_struct);
   2208 
   2209                     ps_lap_struct->i4_next_start_ctr = 0;
   2210                 }
   2211 
   2212                 if(/*ps_lap_struct->i4_init_delay_over &&*/ 0 !=
   2213                    ps_lap_struct->i4_num_frm_type_decided)
   2214                 {
   2215                     ihevce_assign_pic_type(
   2216                         ps_lap_struct,
   2217                         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]);
   2218 
   2219                     ps_lap_struct->i4_num_frm_type_decided--;
   2220 
   2221                     if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
   2222                     {
   2223                         /*special case of two consequetive idr at the start of encode or due to force idr*/
   2224                         ps_lap_struct->i4_immediate_idr_case =
   2225                             ps_lap_struct->i4_is_all_i_pic_in_seq;
   2226                         if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]
   2227                                ->s_lap_out.i4_pic_type == IV_IDR_FRAME)
   2228                         {
   2229                             ps_lap_struct->i4_immediate_idr_case = 1;
   2230                         }
   2231                         else
   2232                         {
   2233                             WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0
   2234                                                      ? ps_lap_struct->i4_buf_deq_idx - 1
   2235                                                      : ps_lap_struct->i4_buf_deq_idx;
   2236                             /*field case of single IDR field followed by P*/
   2237                             if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] &&
   2238                                i4_field_flag &&
   2239                                ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type ==
   2240                                    IV_IDR_FRAME &&
   2241                                !ps_lap_struct->i4_num_frm_type_decided)
   2242                             {
   2243                                 ps_lap_struct->i4_immediate_idr_case = 1;
   2244                             }
   2245                         }
   2246                     }
   2247 
   2248                     /* Queue in the current input Buffer to LAP que */
   2249                     ihevce_lap_queue_input(
   2250                         ps_lap_struct,
   2251                         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx],
   2252                         &i4_tree_num);
   2253 
   2254                     ps_lap_struct->i4_next_start_ctr++;
   2255                     ps_lap_struct->i4_buf_deq_idx++;
   2256                     if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH)
   2257                         ps_lap_struct->i4_buf_deq_idx = 0;
   2258                 }
   2259 
   2260                 ps_lap_struct->i4_buf_enq_idx++;
   2261                 if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH)
   2262                     ps_lap_struct->i4_buf_enq_idx = 0;
   2263             } /* end if for valid input buffer check*/
   2264         }
   2265 
   2266         /* source pixel padding if width/height is not aligned to 8 pixel */
   2267         if(ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag)
   2268         {
   2269             ihevce_src_params_t *ps_src_prms = &ps_lap_struct->s_static_cfg_params.s_src_prms;
   2270             WORD32 i4_align_wd = ps_src_prms->i4_width;
   2271             WORD32 i4_align_ht = ps_src_prms->i4_height;
   2272             WORD32 min_cu_size =
   2273                 (1 << ps_lap_struct->s_static_cfg_params.s_config_prms.i4_min_log2_cu_size);
   2274 
   2275             i4_align_wd += SET_CTB_ALIGN(ps_src_prms->i4_width, min_cu_size);
   2276             i4_align_ht += SET_CTB_ALIGN(ps_src_prms->i4_height, min_cu_size);
   2277 
   2278             ihevce_lap_pad_input_bufs(ps_lap_inp_buf, i4_align_wd, i4_align_ht);
   2279         }
   2280         {
   2281             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_width = 0;
   2282             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_height = 0;
   2283             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_x_offset = 0;
   2284             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_y_offset = 0;
   2285         }
   2286     }
   2287 
   2288     if(ps_lap_struct->end_flag == 1)
   2289     {
   2290         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf;
   2291 
   2292         /*to be filed*/
   2293         if(0 == ps_lap_struct->i4_num_frm_type_decided)
   2294         {
   2295             ps_lap_struct->ai1_pic_type[0] =
   2296                 ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
   2297 
   2298             ihevce_determine_next_sub_gop_state(ps_lap_struct);
   2299 
   2300             ps_lap_struct->i4_next_start_ctr = 0;
   2301         }
   2302 
   2303         if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
   2304         {
   2305             ihevce_assign_pic_type(
   2306                 ps_lap_struct, ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]);
   2307         }
   2308 
   2309         ps_lap_struct->i4_num_frm_type_decided--;
   2310 
   2311         if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
   2312         {
   2313             /*special case of two consequetive idr at the start of encode or due to force idr*/
   2314             ps_lap_struct->i4_immediate_idr_case = ps_lap_struct->i4_is_all_i_pic_in_seq;
   2315 
   2316             if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]
   2317                    ->s_lap_out.i4_pic_type == IV_IDR_FRAME)
   2318             {
   2319                 ps_lap_struct->i4_immediate_idr_case = 1;
   2320             }
   2321             else
   2322             {
   2323                 WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0
   2324                                          ? ps_lap_struct->i4_buf_deq_idx - 1
   2325                                          : ps_lap_struct->i4_buf_deq_idx;
   2326                 /*field case of single IDR field followed by P*/
   2327                 if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] && i4_field_flag &&
   2328                    ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type ==
   2329                        IV_IDR_FRAME &&
   2330                    !ps_lap_struct->i4_num_frm_type_decided)
   2331                 {
   2332                     ps_lap_struct->i4_immediate_idr_case = 1;
   2333                 }
   2334             }
   2335         }
   2336         /* Queue in the current input Buffer to LAP que */
   2337         ihevce_lap_queue_input(
   2338             ps_lap_struct,
   2339             ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx],
   2340             &i4_tree_num);
   2341 
   2342         ps_lap_struct->i4_next_start_ctr++;
   2343         ps_lap_struct->i4_buf_deq_idx++;
   2344 
   2345         if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH)
   2346             ps_lap_struct->i4_buf_deq_idx = 0;
   2347 
   2348         ps_lap_struct->i4_buf_enq_idx++;
   2349         if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH)
   2350             ps_lap_struct->i4_buf_enq_idx = 0;
   2351     }
   2352     ps_lap_struct->i4_num_frames_after_force_idr = i4_num_frames_after_force_idr;
   2353 
   2354     if(1 == ps_lap_struct->i4_force_end_flag)
   2355     {
   2356         ihevce_force_end(ps_hle_ctxt);
   2357     }
   2358 
   2359     /*return encode order pic to pre enc*/
   2360     ps_lap_inp_buf = NULL;
   2361 
   2362     if(NULL != ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx])
   2363     {
   2364         ps_lap_inp_buf = ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx];
   2365         ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx] = NULL;
   2366         if(!ps_lap_inp_buf->s_lap_out.i4_end_flag)
   2367             ihevce_pre_rel_lapout_update(ps_lap_struct, ps_lap_inp_buf);
   2368     }
   2369 
   2370     ps_lap_struct->i4_lap_out_idx++;
   2371     if(ps_lap_struct->i4_lap_out_idx == ps_lap_struct->i4_max_buf_in_enc_order)
   2372     {
   2373         ps_lap_struct->i4_lap_out_idx = 0;
   2374         ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
   2375     }
   2376 
   2377     return (ps_lap_inp_buf);
   2378 }
   2379 
   2380 /*!
   2381 ************************************************************************
   2382 * \brief
   2383 *    lap get input buffer requirement count
   2384 ************************************************************************
   2385 */
   2386 WORD32 ihevce_lap_get_num_ip_bufs(ihevce_lap_static_params_t *ps_lap_stat_prms)
   2387 {
   2388     WORD32 i4_lap_window_size = 1;
   2389     WORD32 gop_delay = 1 << ps_lap_stat_prms->i4_max_temporal_layers;
   2390 
   2391     if(ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics != 0)
   2392     {
   2393         i4_lap_window_size = 1 + ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics;
   2394     }
   2395 
   2396     gop_delay += (i4_lap_window_size);
   2397     return gop_delay;
   2398 }
   2399