Home | History | Annotate | Download | only in encoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2015 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 /* File Includes                                                             */
     23 /*****************************************************************************/
     24 
     25 /* System include files */
     26 #include "stdio.h"
     27 #include "string.h"
     28 
     29 /* User include files */
     30 #include "irc_datatypes.h"
     31 #include "irc_cntrl_param.h"
     32 #include "irc_mem_req_and_acq.h"
     33 #include "irc_picture_type.h"
     34 #include "irc_trace_support.h"
     35 
     36 #define MAX_INTER_FRM_INT   10
     37 
     38 /******************************Pic_details ************************************/
     39 typedef struct
     40 {
     41     /* The id sent by the codec */
     42     WORD32 i4_pic_id;
     43 
     44     /* The pics come in, in this order  */
     45     WORD32 i4_pic_disp_order_no;
     46 
     47     /* I,P,B */
     48     picture_type_e e_pic_type;
     49 
     50 } pic_details_t;
     51 
     52 /**************************Pic_handling structure *****************************/
     53 typedef struct pic_handling_t
     54 {
     55     /***************************************************************************
     56      * Inputs from the codec
     57      **************************************************************************/
     58 
     59     /* Number of frames after which an I frame will repeat in display order */
     60     WORD32 i4_intra_frm_int;
     61 
     62     /* (num_b_pics_in_subgop + 1) */
     63     WORD32 i4_inter_frm_int;
     64 
     65     /* After these many buffered frames, the pics are encoded */
     66     WORD32 i4_max_inter_frm_int;
     67 
     68     /* OPEN or CLOSED */
     69     WORD32 i4_is_gop_closed;
     70 
     71     /* The pic stack */
     72     /* Stack used to store the input pics in encode order */
     73     pic_details_t as_pic_stack[MAX_INTER_FRM_INT + 2];
     74 
     75     /***************************************************************************
     76      * Counters
     77      **************************************************************************/
     78 
     79     /* Decides whether a B or ref pic */
     80     WORD32 i4_buf_pic_no;
     81 
     82     /* Current pic's number in displayed, and gets reset after an I-frm */
     83     WORD32 i4_pic_disp_order_no;
     84 
     85     /* Number of P frms that have come, in the current gop, so far */
     86     WORD32 i4_p_count_in_gop;
     87 
     88     /* Number of B frms that have come, in the current gop, so far */
     89     WORD32 i4_b_count_in_gop;
     90 
     91     /* Number of B frms that have come, in the current subgop, so far */
     92     WORD32 i4_b_count_in_subgop;
     93 
     94     /***************************************************************************
     95      * Indices to the pic stack (Since we store the pics in the encode order,
     96      * these vars are modified to meet that)
     97      **************************************************************************/
     98 
     99     /* B_PIC index */
    100     WORD32 i4_b_pic_idx;
    101 
    102     /* I,P PIC index */
    103     WORD32 i4_ref_pic_idx;
    104 
    105     /***************************************************************************
    106      * Variables operating on the input pics
    107      **************************************************************************/
    108 
    109     /* Flag denoting whether it's the first gop or not */
    110     WORD32 i4_is_first_gop;
    111 
    112     /* Number of B_PICs in an incomplete subgop */
    113     WORD32 i4_b_in_incomp_subgop;
    114 
    115     /* In CLOSED_GOPs, even if inter_frm_int > 1, there can be 2 continous
    116      * P_PICs at the GOP end. This takes values of 0 or 1 */
    117     WORD32 i4_extra_p;
    118 
    119     /***************************************************************************
    120      * Arrays storing the number of frms in the gop
    121      **************************************************************************/
    122 
    123     /* In the steady state, what's the pic distribution in display order */
    124     WORD32 i4_frms_in_gop[MAX_PIC_TYPE];
    125 
    126     /*
    127      * In case of a change in inter frm int call, the pic distribution in
    128      * that gop in display order
    129      */
    130     WORD32 i4_frms_in_cur_gop[MAX_PIC_TYPE];
    131 
    132     /*
    133      * This is used to denote the number of frms remaining to be encoded in the
    134      * current gop
    135      */
    136     WORD32 i4_rem_frms_in_gop[MAX_PIC_TYPE];
    137 
    138     /***************************************************************************
    139      * Variables operating on the output pics
    140      **************************************************************************/
    141 
    142     /* Counts the frms encoded in a gop */
    143     WORD32 i4_coded_pic_no;
    144 
    145     /* Counts from the start of stack to the end repeatedly */
    146     WORD32 i4_stack_count;
    147 
    148     /***************************************************************************
    149      * Tracking a change in the inputs from the codec
    150      **************************************************************************/
    151 
    152     /* A flag that is set when the codec calls for a change in inter_frm_int */
    153     WORD32 i4_change_in_inter_frm_int;
    154 
    155     /*
    156      * When a change_in_inter_frm_int is called, this stores the new
    157      * inter_frm_int
    158      */
    159     WORD32 i4_new_inter_frm_int;
    160 
    161     /*
    162      * When a change_in_inter_frm_int is called in the middle of a gop,this
    163      * stores the B_PICs in the incomplete subgop of the mixed gop
    164      */
    165     WORD32 i4_b_in_incomp_subgop_mix_gop;
    166 
    167     /*
    168      * For a CLOSED GOP, when a change_in_inter_frm_int is called in the middle
    169      * of a gop,this is a flag denoting if there is an extra P_PIC in the mixed
    170      * gop
    171      */
    172     WORD32 i4_extra_p_mix_gop;
    173 
    174     /* A flag that is set when the codec calls for a change in intra_frm_int */
    175     WORD32 i4_change_in_intra_frm_int;
    176 
    177     /*
    178      * When a change_in_intra_frm_int is called, this stores the new
    179      * intra_frm_int
    180      */
    181     WORD32 i4_new_intra_frm_int;
    182 
    183     /***************************************************************************
    184      * Previous pic_stack_indices & details
    185      **************************************************************************/
    186     pic_details_t s_prev_pic_details;
    187 
    188     WORD32 i4_prev_b_pic_idx;
    189 
    190     WORD32 i4_last_frm_in_gop;
    191 
    192     WORD32 i4_first_gop_encoded;
    193 
    194     /* NITT TBR */
    195     picture_type_e e_previous_pic_type;
    196 
    197     WORD32 i4_force_I_frame;
    198 
    199     WORD32 i4_forced_I_frame_cur_frame;
    200 
    201     WORD32 i4_sum_remaining_frm_in_gop;
    202 
    203     WORD32 i4_mod_temp_ref_cnt;
    204 
    205     WORD32 i4_frames_in_fif_gop;
    206 
    207     WORD32 i4_prev_intra_frame_interval;
    208 
    209 } pic_handling_t;
    210 
    211 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling,
    212                                   WORD32 i4_intra_frm_int,
    213                                   WORD32 i4_inter_frm_int,
    214                                   WORD32 i4_gop_boundary);
    215 
    216 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE],
    217                                    WORD32 i4_intra_frm_int,
    218                                    WORD32 i4_inter_frm_int,
    219                                    WORD32 i4_is_gop_closed,
    220                                    WORD32 *pi4_b_in_incomp_subgop,
    221                                    WORD32 *pi4_extra_p);
    222 
    223 WORD32 irc_pic_handling_num_fill_use_free_memtab(pic_handling_t **pps_pic_handling,
    224                                                  itt_memtab_t *ps_memtab,
    225                                                  ITT_FUNC_TYPE_E e_func_type)
    226 {
    227     WORD32 i4_mem_tab_idx = 0;
    228     pic_handling_t s_pic_handling_temp;
    229 
    230     /*
    231      * Hack for al alloc, during which we dont have any state memory.
    232      * Dereferencing can cause issues
    233      */
    234     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
    235     {
    236         (*pps_pic_handling) = &s_pic_handling_temp;
    237     }
    238 
    239     /*for src rate control state structure*/
    240     if(e_func_type != GET_NUM_MEMTAB)
    241     {
    242         fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(pic_handling_t),
    243                     ALIGN_128_BYTE, PERSISTENT, DDR);
    244         use_or_fill_base(&ps_memtab[0], (void**)pps_pic_handling, e_func_type);
    245     }
    246     i4_mem_tab_idx++;
    247 
    248     return (i4_mem_tab_idx);
    249 }
    250 
    251 /******************************************************************************
    252  Description     : initializes the pic handling state struct
    253  *****************************************************************************/
    254 void irc_init_pic_handling(pic_handling_t *ps_pic_handling,
    255                            WORD32 i4_intra_frm_int,
    256                            WORD32 i4_inter_frm_int,
    257                            WORD32 i4_max_inter_frm_int,
    258                            WORD32 i4_is_gop_closed)
    259 {
    260     /* Declarations */
    261     WORD32 i;
    262 
    263     /* Checks */
    264     /* Codec Parameters */
    265     ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int;
    266     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
    267     ps_pic_handling->i4_max_inter_frm_int = i4_max_inter_frm_int;
    268     ps_pic_handling->i4_is_gop_closed = i4_is_gop_closed;
    269 
    270     /* Pic_stack */
    271     memset(ps_pic_handling->as_pic_stack, 0,
    272            sizeof(ps_pic_handling->as_pic_stack));
    273     memset(&ps_pic_handling->s_prev_pic_details, 0,
    274            sizeof(ps_pic_handling->s_prev_pic_details));
    275 
    276     /* Counters */
    277     ps_pic_handling->i4_buf_pic_no = 0;
    278     ps_pic_handling->i4_pic_disp_order_no = 0;
    279 
    280     /* Indices to the pic_stack */
    281     ps_pic_handling->i4_ref_pic_idx = 0;
    282     /*
    283      * B frame index should be ref_frame_num,
    284      * which is 2 in out case
    285      */
    286     ps_pic_handling->i4_b_pic_idx = 2;
    287     ps_pic_handling->i4_prev_b_pic_idx = 2;
    288 
    289     /* Variables working on the input frames */
    290     ps_pic_handling->i4_is_first_gop = 1;
    291     ps_pic_handling->i4_p_count_in_gop = 0;
    292     ps_pic_handling->i4_b_count_in_gop = 0;
    293     ps_pic_handling->i4_b_count_in_subgop = 0;
    294 
    295     /* Variables working on the output frames */
    296     ps_pic_handling->i4_coded_pic_no = -1;
    297     ps_pic_handling->i4_stack_count = -1;
    298 
    299     /* Tracks the changes in the Codec Parameters */
    300     ps_pic_handling->i4_change_in_inter_frm_int = 0;
    301     ps_pic_handling->i4_new_inter_frm_int = i4_max_inter_frm_int;
    302 
    303     /* Tracks the changes in the Codec Parameters */
    304     ps_pic_handling->i4_change_in_intra_frm_int = 0;
    305     ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int;
    306 
    307     /* Variables on which the bit allocation is dependent  */
    308     /* Get the pic distribution in the gop */
    309     find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int,
    310                            i4_inter_frm_int, i4_is_gop_closed,
    311                            &ps_pic_handling->i4_b_in_incomp_subgop,
    312                            &ps_pic_handling->i4_extra_p);
    313 
    314     for(i = 0; i < MAX_PIC_TYPE; i++)
    315     {
    316         ps_pic_handling->i4_frms_in_cur_gop[i] =
    317                         ps_pic_handling->i4_frms_in_gop[i];
    318         ps_pic_handling->i4_rem_frms_in_gop[i] =
    319                         ps_pic_handling->i4_frms_in_gop[i];
    320     }
    321 
    322     ps_pic_handling->e_previous_pic_type = I_PIC;
    323     ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int;
    324     ps_pic_handling->i4_force_I_frame = 0;
    325     ps_pic_handling->i4_forced_I_frame_cur_frame = 0;
    326     ps_pic_handling->i4_sum_remaining_frm_in_gop = 0;
    327     ps_pic_handling->i4_mod_temp_ref_cnt = 0;
    328 
    329     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
    330                     ps_pic_handling->i4_b_in_incomp_subgop;
    331     ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
    332 
    333     ps_pic_handling->i4_last_frm_in_gop = 0;
    334     ps_pic_handling->i4_first_gop_encoded = 0;
    335     ps_pic_handling->i4_frames_in_fif_gop = 0;
    336 
    337 }
    338 
    339 /*******************************************************************************
    340  * @brief registers the new intra frame interval value
    341  ******************************************************************************/
    342 void irc_pic_handling_register_new_int_frm_interval(pic_handling_t *ps_pic_handling,
    343                                                     WORD32 i4_intra_frm_int)
    344 {
    345     ps_pic_handling->i4_change_in_intra_frm_int = 1;
    346     ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int;
    347 }
    348 
    349 void irc_pic_handling_register_new_inter_frm_interval(pic_handling_t *ps_pic_handling,
    350                                                       WORD32 i4_inter_frm_int)
    351 {
    352     /* Update the state structure with the latest values */
    353     ps_pic_handling->i4_change_in_inter_frm_int = 1;
    354     ps_pic_handling->i4_new_inter_frm_int = i4_inter_frm_int;
    355 }
    356 
    357 static void start_new_gop(pic_handling_t *ps_pic_handling)
    358 {
    359     WORD32 i;
    360     WORD32 i4_sum_remaining_frm_in_gop = 0;
    361 
    362     /* Now, the end of gop updates */
    363     ps_pic_handling->i4_pic_disp_order_no = 0;
    364     ps_pic_handling->i4_buf_pic_no = 0;
    365     ps_pic_handling->i4_is_first_gop = 0;
    366     ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
    367 
    368     if(ps_pic_handling->i4_is_gop_closed)
    369     {
    370         ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
    371                         ps_pic_handling->i4_b_in_incomp_subgop;
    372     }
    373     /*
    374      * Store the number of frames in the gop that is encoded till now
    375      * just before Force I frame call is made
    376      */
    377     ps_pic_handling->i4_frames_in_fif_gop = ps_pic_handling->i4_b_count_in_gop
    378                     + ps_pic_handling->i4_p_count_in_gop + 1;
    379     for(i = 0; i < MAX_PIC_TYPE; i++)
    380     {
    381         i4_sum_remaining_frm_in_gop += ps_pic_handling->i4_rem_frms_in_gop[i];
    382     }
    383     ps_pic_handling->i4_sum_remaining_frm_in_gop = i4_sum_remaining_frm_in_gop;
    384     for(i = 0; i < MAX_PIC_TYPE; i++)
    385     {
    386         ps_pic_handling->i4_frms_in_cur_gop[i] =
    387                         ps_pic_handling->i4_frms_in_gop[i];
    388         ps_pic_handling->i4_rem_frms_in_gop[i] =
    389                         ps_pic_handling->i4_frms_in_cur_gop[i];
    390     }
    391 }
    392 
    393 /*******************************************************************************
    394  * @brief Fills the pic_stack with the incoming pics in encode order
    395  ******************************************************************************/
    396 void irc_add_pic_to_stack(pic_handling_t *ps_pic_handling, WORD32 i4_enc_pic_id)
    397 {
    398     /* Declarations */
    399     WORD32 i4_inter_frm_int, i4_max_inter_frm_int,
    400            i4_intra_frm_int, i4_new_inter_frm_int;
    401     WORD32 i4_is_gop_closed;
    402     WORD32 i4_buf_pic_no, i4_pic_disp_order_no;
    403     WORD32 i4_b_pic_idx, i4_ref_pic_idx;
    404     WORD32 i4_is_first_gop, i4_b_in_incomp_subgop, i4_p_count_in_gop,
    405            i4_b_count_in_gop, i4_b_count_in_subgop;
    406     WORD32 i, i4_p_frms_in_prd, i4_b_frms_in_prd,
    407            i4_num_b_in_subgop, i4_extra_p;
    408     WORD32 i4_condn_for_change_in_inter_frm_int;
    409     picture_type_e e_previous_pic_type, e_cur_pic_type;
    410     WORD32 i4_force_I_frame;
    411 
    412     /*
    413      * Initialize the local vars with the state struct values needed by the
    414      * change calls
    415      */
    416     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
    417     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
    418     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
    419     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
    420 
    421     i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no;
    422     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
    423     i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop;
    424     i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC];
    425     i4_is_first_gop = ps_pic_handling->i4_is_first_gop;
    426     i4_new_inter_frm_int = ps_pic_handling->i4_new_inter_frm_int;
    427     e_previous_pic_type = ps_pic_handling->e_previous_pic_type;
    428     i4_force_I_frame = ps_pic_handling->i4_force_I_frame;
    429 
    430     /*  Force I frame :
    431      *  Two different cases
    432      *  1)OPEN_GOP: New GOP is started after number of B pictures in the last
    433      *              sub gop of a gop to mimic the GOP structure.
    434      *  2)Closed GOP:Wait till P frame at input and The frame after a P frame
    435      *               a new GOP is started to mimic the GOP structure.
    436      */
    437     if(i4_force_I_frame)
    438     {
    439         WORD32 i4_temp_is_gop_closed;
    440         WORD32 i4_codn = 0;
    441         /* A special case of Open GOP where the it behaves like Closed GOP*/
    442         if((i4_intra_frm_int % i4_inter_frm_int) == 1)
    443         {
    444             i4_temp_is_gop_closed = 1;
    445         }
    446         else
    447         {
    448             i4_temp_is_gop_closed = i4_is_gop_closed;
    449         }
    450         /* Get the current picture type to aid decision to force an I frame*/
    451         if((i4_buf_pic_no % i4_inter_frm_int)
    452            && !(i4_is_gop_closed&& (i4_b_count_in_gop == i4_b_frms_in_prd)))
    453         {
    454             e_cur_pic_type = B_PIC;
    455         }
    456         else
    457         {
    458             if(i4_pic_disp_order_no == 0)
    459             {
    460                 e_cur_pic_type = I_PIC;
    461             }
    462             else
    463             {
    464                 e_cur_pic_type = P_PIC;
    465             }
    466         }
    467         if((i4_intra_frm_int % i4_inter_frm_int) == 0)
    468         {
    469             i4_codn = (e_cur_pic_type == P_PIC);
    470         }
    471         else
    472         {
    473             i4_codn = (ps_pic_handling->i4_b_count_in_subgop
    474                             == ps_pic_handling->i4_b_in_incomp_subgop);
    475         }
    476         if(e_cur_pic_type == I_PIC)
    477         {
    478             /*
    479              * Don't do anything. Resetting the force I frame flag
    480              * since the current picture type is already a I frame
    481              */
    482             i4_force_I_frame = 0;
    483         }
    484         else if(i4_inter_frm_int == 1)
    485         {
    486             /*IPP case , Force I frame immediately*/
    487             start_new_gop(ps_pic_handling);
    488         }
    489         else if((!i4_temp_is_gop_closed) && i4_codn)
    490         {
    491             start_new_gop(ps_pic_handling);
    492             if(ps_pic_handling->i4_b_count_in_subgop)
    493             {
    494                 ps_pic_handling->i4_b_pic_idx += 1;
    495                 ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
    496             }
    497         }
    498         else if(i4_temp_is_gop_closed && (e_previous_pic_type == P_PIC)
    499                         && (e_cur_pic_type != P_PIC))
    500         {
    501             start_new_gop(ps_pic_handling);
    502             ps_pic_handling->i4_b_pic_idx++;
    503             ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
    504         }
    505         i4_is_first_gop = ps_pic_handling->i4_is_first_gop;
    506     }
    507 
    508 
    509      /***********************CHANGE_INTRA_FRM_INTERVAL**************************
    510      *
    511      * Call the irc_update_pic_distbn if
    512      *      1)Change in intra frm interval flag is set
    513      *      2)It's the first B_PIC of a gop
    514      */
    515     if((ps_pic_handling->i4_change_in_intra_frm_int == 1)
    516                     && ((i4_pic_disp_order_no == 1)))
    517     {
    518         irc_update_pic_distbn(ps_pic_handling,
    519                               ps_pic_handling->i4_new_intra_frm_int,
    520                               ps_pic_handling->i4_inter_frm_int, 1);
    521 
    522         ps_pic_handling->i4_change_in_intra_frm_int = 0;
    523 
    524         if(ps_pic_handling->i4_new_intra_frm_int == 1)
    525         {
    526             ps_pic_handling->i4_pic_disp_order_no = 0;
    527         }
    528     }
    529     /*********************CHANGE_INTER_FRM_INTERVAL****************************/
    530     /* Call irc_update_pic_distbn if
    531      *      1)Change in inter frm interval flag is set
    532      *      2)It's the first B_PIC after gop/subgop start, and
    533      *      3)The new inter-frm-interval won't cross the intra_frm_interval
    534      */
    535     if((ps_pic_handling->i4_change_in_inter_frm_int == 1)
    536        && ((i4_buf_pic_no % i4_inter_frm_int == 1)|| (i4_pic_disp_order_no == 1) || (i4_inter_frm_int == 1)))
    537     {
    538         /*
    539          * Condition which checks if the new inter_frm_int will cross the
    540          * intra_frm_int
    541          */
    542         i4_condn_for_change_in_inter_frm_int = ((i4_pic_disp_order_no
    543                         + i4_new_inter_frm_int - 1) < i4_intra_frm_int);
    544 
    545         if(i4_condn_for_change_in_inter_frm_int)
    546         {
    547             /*
    548              * If there is a change in inter frame interval. We should set the b
    549              * frame IDX to the (num ref frame - num ref frame in buf)+ i4_ref_pic_idx
    550              * Since our case we have a structure of I B P or I B...B P only
    551              * we have three cases
    552              * 1) current incoming frame is I. Then we have to leave space for
    553              *    current I and next P hence write b idx as to ref idx + 2
    554              * 2) Current incoming frame is B. In that case, we have I in buffer.
    555              *    Only one P needs space hence write b idx as ref idx +1
    556              * 3) Current incoming frame is P. In that case we are at the end of
    557              *    gop [sub gop?] and we have to leave space for next gops I and P.
    558              *    Thus b idx = ref idx + 2
    559              *
    560              *  In case of an closed Gop. The last frame has to be forced to be a P.
    561              *  Hence we may have problems in that case.
    562              *
    563              *  Also this has the implicit assumption of only 2 ref frames
    564              */
    565             WORD32 i4_is_curr_frm_b =  (i4_buf_pic_no % i4_new_inter_frm_int)&&
    566                             !(i4_is_gop_closed && (i4_b_count_in_gop == i4_b_frms_in_prd));
    567 
    568             /*If the inter_frm_int = 1, then the b_pic_idx needs to be modified */
    569             if(i4_inter_frm_int == 1)
    570             {
    571                 ps_pic_handling->i4_b_pic_idx = ((i4_is_curr_frm_b ? 1 : 2)
    572                                 + ps_pic_handling->i4_ref_pic_idx)
    573                                 % (i4_max_inter_frm_int + 1);
    574             }
    575 
    576             /*
    577              * Depending on the gop/subgop boundary, call the change_inter_frm_int
    578              *
    579              * TO DO: make a single call, change the name of the fxn to
    580              * update_state,
    581              * where state = frms_in_gop + b_incomp_subgop + extra_p
    582              */
    583 
    584             /* GOP boundary */
    585             if(i4_pic_disp_order_no == 1)
    586             {
    587                 irc_update_pic_distbn(ps_pic_handling,
    588                                       ps_pic_handling->i4_intra_frm_int,
    589                                       ps_pic_handling->i4_new_inter_frm_int, 1);
    590             }
    591             /* Subgop boundary */
    592             else
    593             {
    594                 irc_update_pic_distbn(ps_pic_handling,
    595                                       ps_pic_handling->i4_intra_frm_int,
    596                                       ps_pic_handling->i4_new_inter_frm_int, 0);
    597             }
    598 
    599             ps_pic_handling->i4_change_in_inter_frm_int = 0;
    600             ps_pic_handling->i4_new_inter_frm_int =
    601                             ps_pic_handling->i4_inter_frm_int;
    602         }
    603 
    604     }
    605 
    606     /* Initialize the local vars with the state struct values */
    607     i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no;
    608     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
    609     i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
    610     i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
    611     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
    612     i4_p_count_in_gop = ps_pic_handling->i4_p_count_in_gop;
    613     i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop;
    614     i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop;
    615     i4_p_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[P_PIC];
    616     i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC];
    617     i4_extra_p = ps_pic_handling->i4_extra_p_mix_gop;
    618     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
    619     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
    620 
    621     /* Initializing the prev_state vars */
    622     ps_pic_handling->i4_prev_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
    623 
    624     i4_num_b_in_subgop = (i4_inter_frm_int - 1);
    625 
    626     /*********************** Fill the stack ***********************************/
    627     /* The next part of the code is organized as
    628      *
    629      * if(B_PIC conditions satisfied)
    630      * {
    631      *  Fill the pic_stack using the b_pic_index
    632      *  Update the b_pic_index and the other b_pic related vars for the
    633      *      next B_PIC
    634      * }
    635      *  else
    636      * {
    637      *  if(I_PIC conditions are satisfied)
    638      * {
    639      *  Fill the pic_stack using the ref_pic_index
    640      *  Update the ref_pic_index and the other ref_pic related vars for the next
    641      *      I_PIC/P_PIC
    642      * }
    643      *  else
    644      * {
    645      *  Fill the pic_stack using the ref_pic_index
    646      *  Update the ref_pic_index and the other ref_pic related vars for the next
    647      *      I_PIC/P_PIC
    648      * }
    649      * }
    650      */
    651     /*
    652      * Condition for a B_PIC -
    653      * 1) Other than the first I_PIC and the periodically appearing P_PICs, after
    654      *    every inter_frm_int, rest all pics are B_PICs
    655      * 2) In case of CLOSED_GOP, the last frame of the gop has to be a P_PIC
    656      */
    657 
    658     if((i4_buf_pic_no % i4_inter_frm_int)&& !(i4_is_gop_closed
    659        && (i4_b_count_in_gop == i4_b_frms_in_prd))) /**** B_PIC ****/
    660     {
    661         /* Fill the pic_stack */
    662         ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = i4_enc_pic_id;
    663         ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type = B_PIC;
    664         ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no =
    665                         i4_pic_disp_order_no;
    666 
    667         /* Store Pic type*/
    668         e_previous_pic_type = B_PIC;
    669 
    670         /* Update the prev_pic_details */
    671         memcpy(&ps_pic_handling->s_prev_pic_details,
    672                &ps_pic_handling->as_pic_stack[i4_b_pic_idx],
    673                sizeof(pic_details_t));
    674 
    675         i4_b_count_in_gop++;
    676         i4_b_count_in_subgop++;
    677 
    678         /* Update the i4_b_pic_idx */
    679         if(!i4_is_gop_closed)
    680         {
    681             /* If this B_PIC features in one of the complete subgops */
    682             if((i4_b_count_in_subgop < i4_num_b_in_subgop)
    683                             && !(i4_b_count_in_gop == i4_b_frms_in_prd))
    684             {
    685                 i4_b_pic_idx++;
    686             }
    687             else /* Else if this B_PIC is the last one in a subgop or gop  */
    688             {
    689                 /*
    690                  * If this is the last B_PIC of a GOP, depending on the number
    691                  * of incomp B_pics in the subgop, there can be either only I
    692                  * or I,P pics between this and the next B_PIC
    693                  */
    694                 if(i4_b_count_in_gop == i4_b_frms_in_prd)
    695                 {
    696                     i4_b_pic_idx += (2 + (!i4_b_in_incomp_subgop)); /*Prev*/
    697                     i4_b_count_in_gop = 0;
    698                 }
    699                 /*
    700                  * For the last B_PIC of a subgop, there's always a P b/w
    701                  * this & the next B_PIC
    702                  */
    703                 else
    704                 {
    705                     i4_b_pic_idx += 2;
    706                 }
    707                 i4_b_count_in_subgop = 0;
    708             }
    709         }
    710         else
    711         {
    712             /* For the last B_PIC of a gop
    713              * Normally,there will be 3 pics (P,I,P) between this and the next
    714              * B_PIC for a CLOSED gop, except when
    715              *  1)Number of P_pics in the gop = 1
    716              *  2)There is an extra P at the end of the gop
    717              */
    718             if(i4_b_count_in_gop == i4_b_frms_in_prd)
    719             {
    720                 i4_b_pic_idx += (3 + ((i4_b_in_incomp_subgop == 0)
    721                                  && (i4_p_frms_in_prd> 1)
    722                                  && (i4_pic_disp_order_no
    723                                  != (i4_p_frms_in_prd+ i4_b_frms_in_prd- 1))));
    724 
    725                 i4_b_count_in_subgop = 0;
    726             }
    727             /* For a B_PIC which is not the last one in a subgop */
    728             else if(i4_b_count_in_subgop < i4_num_b_in_subgop)
    729             {
    730                 i4_b_pic_idx++;
    731             }
    732             else /* For the last B_PIC of a subgop */
    733             {
    734                 i4_b_pic_idx += 2;
    735                 i4_b_count_in_subgop = 0;
    736             }
    737         }
    738         i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
    739     }
    740     /*********** I or P pic *********/
    741     else
    742     {
    743         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = i4_enc_pic_id;
    744         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no =
    745                         i4_pic_disp_order_no;
    746         /* Store Pic type*/
    747         e_previous_pic_type = I_PIC;
    748 
    749         /**** I_PIC ****/
    750         if(i4_pic_disp_order_no == 0)
    751         {
    752             ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = I_PIC;
    753 
    754             /* Update the prev_pic_details */
    755             memcpy(&ps_pic_handling->s_prev_pic_details,
    756                    &ps_pic_handling->as_pic_stack[i4_ref_pic_idx],
    757                    sizeof(pic_details_t));
    758             /*
    759              * In case of an I-frame depending on OPEN or CLOSED gop,
    760              * the ref_pic_idx changes
    761              */
    762             if((!i4_is_gop_closed) && (i4_is_first_gop == 0))
    763             {
    764                 if((i4_p_frms_in_prd <= 1) && (i4_b_in_incomp_subgop == 0))
    765                 {
    766                     i4_ref_pic_idx++;
    767                 }
    768                 /*
    769                  * From the 2nd gop onwards, the I and first P frame are
    770                  * separated by the num_b_in_incomp_subgop
    771                  */
    772                 else
    773                 {
    774                     i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1);
    775                 }
    776 
    777                 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
    778                                 ps_pic_handling->i4_b_in_incomp_subgop;
    779             }
    780             else
    781             {
    782                 i4_ref_pic_idx++;
    783             }
    784 
    785             i4_b_count_in_gop = 0;
    786             i4_p_count_in_gop = 0;
    787             i4_b_count_in_subgop = 0;
    788 
    789         }
    790         /**** P_PIC ****/
    791         else
    792         {
    793             ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC;
    794             /* Store Pic type*/
    795             e_previous_pic_type = P_PIC;
    796 
    797             /* Update the prev_pic_details */
    798             memcpy(&ps_pic_handling->s_prev_pic_details,
    799                    &ps_pic_handling->as_pic_stack[i4_ref_pic_idx],
    800                    sizeof(pic_details_t));
    801 
    802             i4_p_count_in_gop++;
    803             ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int;
    804 
    805             /*
    806              * In case of an P-frame depending on OPEN or CLOSED gop, the
    807              * ref_pic_idx changes
    808              */
    809             if(i4_is_gop_closed && (i4_p_count_in_gop == i4_p_frms_in_prd))
    810             {
    811                 /*
    812                  * For the last P_PIC in a gop, if extra_p or incomp_b are
    813                  * present, the number of such pics between this and the next
    814                  * ref_pic is (i4_b_in_incomp_subgop + 1)
    815                  */
    816                 if((i4_p_count_in_gop > 1)
    817                                 && (i4_b_in_incomp_subgop || i4_extra_p))
    818                 {
    819                     i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1);
    820                 }
    821                 else
    822                 {
    823                     i4_ref_pic_idx += i4_inter_frm_int;
    824                 }
    825             }
    826             else
    827             {
    828                 i4_ref_pic_idx += i4_inter_frm_int;
    829             }
    830         }
    831 
    832         i4_ref_pic_idx %= (i4_max_inter_frm_int + 1);
    833     }
    834 
    835     /* Update those variables working on the input frames  */
    836     i4_pic_disp_order_no++;
    837     i4_buf_pic_no++;
    838 
    839 #if 0
    840     /* For any gop */
    841      /* BUG FIX
    842       *  This piece of code resets the gop upon I frame(?)
    843       *  This introduces a problem of GOP getting reset not at I frames as it should be
    844       *  The reason AFAIK is that
    845       *  1) This code uses i4_pic_disp_order_no to reset GOP. I assume it computes
    846       *      if are at GOP boundary and does it, but not sure
    847       *  2) The frames rmainign in GOP is done in post enc as it should be.
    848       *
    849       *  Also ps_pic_handling->i4_pic_disp_order_no is incremented when a pic is added
    850       *  to stack becuase the additon is in disp order while poping is in encode order
    851       *
    852       *  SUppose there is a deay od 1 frame between queue and encode.
    853       *  then he timing will be. Assume a GOP of IPPIPP
    854       *
    855       *      Input buff    Input to qu     Output buf/encode buff      remaining pic in gop
    856       *    1  I             I                 NA                          rest to 1 2
    857       *    2  P             P                 I                           0 2
    858       *    3  P             P                 P                           0 1
    859       *    4  I             I                 P                           reset to 1 2
    860       *    5  P             P                 I                           1 1
    861       *    6  P             P                 P                           1 0
    862       *    7  NA            NA                P
    863       *
    864       *  Hence our gop gets reset at I(1)  and I(4) in the RC.thus the reaming pic in gop
    865       *  count will be as shown. We can clearly see that the GOP gets reset at I(4) .Hence
    866       *  for the correpondinng QP for output buf p(4) will be that of an I frame.
    867       *
    868       *  By hiding this I hope to fix this problem. But Iam not sure exaclty.
    869       *  This needs to be investigated further
    870       *
    871       *  By hiding this most likely we are in effect disabling the dynanic
    872       *  update of gop params.
    873       */
    874 
    875     if(ps_pic_handling->i4_pic_disp_order_no
    876                     == (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed)
    877                         * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop)))
    878     {
    879         for(i = 0; i < MAX_PIC_TYPE; i++)
    880         {
    881             ps_pic_handling->i4_rem_frms_in_gop[i] =
    882                             ps_pic_handling->i4_frms_in_cur_gop[i];
    883         }
    884 
    885         if((!i4_is_gop_closed) && (i4_is_first_gop)
    886                         && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC]
    887                                         > ps_pic_handling->i4_b_in_incomp_subgop_mix_gop))
    888         {
    889             ps_pic_handling->i4_rem_frms_in_gop[B_PIC] =
    890                             ps_pic_handling->i4_frms_in_cur_gop[B_PIC]
    891                                             - ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
    892         }
    893     }
    894 #endif
    895 
    896     /* End of GOP updates */
    897     if(i4_pic_disp_order_no == (i4_p_frms_in_prd + i4_b_frms_in_prd + 1))
    898     {
    899         /* Now, the end of gop updates */
    900         i4_pic_disp_order_no = 0;
    901         i4_buf_pic_no = 0;
    902         i4_is_first_gop = 0;
    903         ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
    904 
    905         if(i4_is_gop_closed)
    906         {
    907             ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
    908                             ps_pic_handling->i4_b_in_incomp_subgop;
    909         }
    910 
    911         for(i = 0; i < MAX_PIC_TYPE; i++)
    912         {
    913             ps_pic_handling->i4_frms_in_cur_gop[i] =
    914                             ps_pic_handling->i4_frms_in_gop[i];
    915         }
    916     }
    917 
    918     /* Updating the vars which work on the encoded pics */
    919     /* For the first gop */
    920     if ((ps_pic_handling->i4_is_first_gop)
    921                     && (ps_pic_handling->i4_pic_disp_order_no == 0))
    922     {
    923         ps_pic_handling->i4_coded_pic_no = 0;
    924         ps_pic_handling->i4_stack_count = 0;
    925     }
    926 
    927     /* Update the state struct with the modifiable local vars */
    928     ps_pic_handling->i4_buf_pic_no = i4_buf_pic_no;
    929     ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no;
    930     ps_pic_handling->i4_b_pic_idx = i4_b_pic_idx;
    931     ps_pic_handling->i4_ref_pic_idx = i4_ref_pic_idx;
    932     ps_pic_handling->i4_is_first_gop = i4_is_first_gop;
    933     ps_pic_handling->i4_p_count_in_gop = i4_p_count_in_gop;
    934     ps_pic_handling->i4_b_count_in_gop = i4_b_count_in_gop;
    935     ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop;
    936     ps_pic_handling->e_previous_pic_type = e_previous_pic_type;
    937     ps_pic_handling->i4_force_I_frame = i4_force_I_frame;
    938 }
    939 
    940 /*******************************************************************************
    941  * @brief Returns the picture type, ip and display order number for the frame to
    942  *        be encoded
    943  ******************************************************************************/
    944 void irc_get_pic_from_stack(pic_handling_t *ps_pic_handling,
    945                             WORD32 *pi4_pic_id,
    946                             WORD32 *pi4_pic_disp_order_no,
    947                             picture_type_e *pe_pic_type)
    948 {
    949     pic_details_t s_pic_details;
    950     pic_details_t *ps_pic_details = &s_pic_details;
    951 
    952     if(ps_pic_handling->i4_stack_count < 0)
    953     {
    954         ps_pic_details->e_pic_type = BUF_PIC;
    955         ps_pic_details->i4_pic_disp_order_no = -1;
    956         ps_pic_details->i4_pic_id = -1;
    957     }
    958     else
    959     {
    960         memcpy(ps_pic_details,
    961                &ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count],
    962                sizeof(pic_details_t));
    963 
    964         /* Force I frame updations */
    965         if((ps_pic_handling->i4_force_I_frame == 1)
    966                         && (ps_pic_details->e_pic_type == I_PIC))
    967         {
    968             /* Flag to signal change in remaining bits*/
    969             ps_pic_handling->i4_forced_I_frame_cur_frame = 1;
    970             ps_pic_handling->i4_force_I_frame = 0;
    971             /*
    972              * Indicates count for no. of Pictures whose temporal reference
    973              * has to be modified
    974              * in the new GOP
    975              */
    976             ps_pic_handling->i4_mod_temp_ref_cnt =
    977                             ps_pic_handling->i4_b_in_incomp_subgop + 1;
    978             ps_pic_handling->i4_first_gop_encoded = 1;
    979         }
    980 
    981         /*
    982          * In MPEG2, the temporal reference of the first displayed frame in a
    983          * gop is 0.In case of an OPEN_GOP, the B_PICs of the last subgop in a
    984          * gop, maybe coded as a part of the next gop. Hence, in such conditions
    985          * the pic_disp_order needs to be modified so that it gives an
    986          * indication of the temporal reference
    987          */
    988         if((!ps_pic_handling->i4_is_gop_closed)
    989                         && (ps_pic_handling->i4_first_gop_encoded))
    990         {
    991             if(!ps_pic_handling->i4_mod_temp_ref_cnt)
    992             {
    993                 ps_pic_details->i4_pic_disp_order_no =
    994                                 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no
    995                                                 + ps_pic_handling->i4_b_in_incomp_subgop)
    996                                                 % (ps_pic_handling->i4_prev_intra_frame_interval);
    997 
    998             }
    999             else
   1000             {
   1001                 /*
   1002                  * due to force I frame First frame will have only
   1003                  * ps_pic_handling->i4_frames_in_fif_gop number of frames
   1004                  */
   1005                 ps_pic_details->i4_pic_disp_order_no =
   1006                                 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no
   1007                                                 + ps_pic_handling->i4_b_in_incomp_subgop)
   1008                                                 % (ps_pic_handling->i4_frames_in_fif_gop);
   1009                 ps_pic_handling->i4_mod_temp_ref_cnt--;
   1010             }
   1011         }
   1012     }
   1013 
   1014     /* Giving this to the Codec */
   1015     *pi4_pic_id = s_pic_details.i4_pic_id;
   1016     *pi4_pic_disp_order_no = s_pic_details.i4_pic_disp_order_no;
   1017     *pe_pic_type = s_pic_details.e_pic_type;
   1018 }
   1019 
   1020 /*******************************************************************************
   1021  * @brief Updates the picture handling state whenever there is changes in input
   1022  *        parameter
   1023  *
   1024  ******************************************************************************/
   1025 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling,
   1026                                   WORD32 i4_intra_frm_int,
   1027                                   WORD32 i4_inter_frm_int,
   1028                                   WORD32 i4_gop_boundary)
   1029 {
   1030     /* Declarations */
   1031     WORD32 i4_is_gop_closed;
   1032     WORD32 i, i4_prev_inter_frm_int, i4_max_inter_frm_int, i4_pic_disp_order_no;
   1033     WORD32 i4_b_in_incomp_subgop, i4_extra_p,
   1034            i4_b_in_incomp_subgop_mix_gop,i4_extra_p_mix_gop;
   1035     WORD32 i4_pb_frms_till_prev_p;
   1036     WORD32 ai4_diff_in_frms[MAX_PIC_TYPE];
   1037 
   1038     /* Initialize the local vars from the state struct */
   1039     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
   1040     i4_prev_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
   1041     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
   1042     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop;
   1043     i4_extra_p = ps_pic_handling->i4_extra_p;
   1044     i4_b_in_incomp_subgop_mix_gop =
   1045                     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
   1046     i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p_mix_gop;
   1047     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
   1048 
   1049     i4_pb_frms_till_prev_p = (ps_pic_handling->i4_p_count_in_gop
   1050                               * i4_prev_inter_frm_int);
   1051 
   1052     /* Check for the validity of the intra_frm_int */
   1053     if(i4_intra_frm_int <= 0)
   1054     {
   1055         i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
   1056     }
   1057     /* Check for the validity of the inter_frm_int */
   1058     if((i4_inter_frm_int > i4_max_inter_frm_int) || (i4_inter_frm_int < 0))
   1059     {
   1060         i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
   1061     }
   1062 
   1063     /* Keep a copy of the older frms_in_gop */
   1064     for(i = 0; i < MAX_PIC_TYPE; i++)
   1065     {
   1066         ai4_diff_in_frms[i] = ps_pic_handling->i4_frms_in_cur_gop[i];
   1067     }
   1068 
   1069     /* Update all the variables which are calculated from the inter_frm_int */
   1070 
   1071     /* Get the new pic distribution in the gop */
   1072     find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int,
   1073                            i4_inter_frm_int, i4_is_gop_closed,
   1074                            &i4_b_in_incomp_subgop, &i4_extra_p);
   1075 
   1076     /* Find the other related variables */
   1077     if(i4_gop_boundary == 0)
   1078     {
   1079         /*
   1080          * Since, the inter frame interval has changed between a gop the
   1081          * current gop will be a mixed gop. So, we need to find the values of
   1082          * the related variables
   1083          */
   1084         find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_cur_gop,
   1085                                (i4_intra_frm_int - i4_pb_frms_till_prev_p),
   1086                                i4_inter_frm_int, i4_is_gop_closed,
   1087                                &i4_b_in_incomp_subgop_mix_gop,
   1088                                &i4_extra_p_mix_gop);
   1089 
   1090         ps_pic_handling->i4_frms_in_cur_gop[P_PIC] +=
   1091                         ps_pic_handling->i4_p_count_in_gop;
   1092         ps_pic_handling->i4_frms_in_cur_gop[B_PIC] +=
   1093                         ps_pic_handling->i4_b_count_in_gop;
   1094     }
   1095     else
   1096     {
   1097         /*
   1098          * Since, the inter_frm_interval has changed at a gop boundary, the
   1099          * new gop will have all the subgops with the new inter_frm_interval
   1100          */
   1101         for(i = 0; i < MAX_PIC_TYPE; i++)
   1102         {
   1103             ps_pic_handling->i4_frms_in_cur_gop[i] =
   1104                             ps_pic_handling->i4_frms_in_gop[i];
   1105         }
   1106 
   1107         i4_b_in_incomp_subgop_mix_gop = i4_b_in_incomp_subgop;
   1108         i4_extra_p_mix_gop = i4_extra_p;
   1109     }
   1110 
   1111     /* For bit-allocation the rem_frms_in_gop need to be updated */
   1112     /* Checks needed:
   1113      1) If the encoding is happening on the same gop as that of the buffering */
   1114     if(ps_pic_handling->i4_pic_disp_order_no
   1115                     >= (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed)
   1116                        * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop)))
   1117     {
   1118         for(i = 0; i < MAX_PIC_TYPE; i++)
   1119         {
   1120             ps_pic_handling->i4_rem_frms_in_gop[i] +=
   1121                             (ps_pic_handling->i4_frms_in_cur_gop[i]
   1122                                             - ai4_diff_in_frms[i]);
   1123         }
   1124     }
   1125 
   1126     /* Update the vars which will affect the proper filling of the pic_stack */
   1127     if(i4_pic_disp_order_no == 0) /*Check if redundant*/
   1128     {
   1129         ps_pic_handling->i4_buf_pic_no = 0;
   1130     }
   1131     else
   1132     {
   1133         ps_pic_handling->i4_buf_pic_no = 1;
   1134     }
   1135 
   1136     ps_pic_handling->i4_b_count_in_subgop = 0;
   1137 
   1138     /* Update the state struct with the new inter_frm_int */
   1139     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
   1140     ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int;
   1141     ps_pic_handling->i4_b_in_incomp_subgop = i4_b_in_incomp_subgop;
   1142     ps_pic_handling->i4_extra_p = i4_extra_p;
   1143     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
   1144                     i4_b_in_incomp_subgop_mix_gop;
   1145     ps_pic_handling->i4_extra_p_mix_gop = i4_extra_p_mix_gop;
   1146 
   1147 }
   1148 
   1149 /* *****************************************************************************
   1150  * @brief Distributes the frames as I, P and B based on intra/inter frame interval.
   1151  *  Along with it it fills the number of frames in sub-gop and extra p frame
   1152  *
   1153  ******************************************************************************/
   1154 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE],
   1155                                    WORD32 i4_intra_frm_int,
   1156                                    WORD32 i4_inter_frm_int,
   1157                                    WORD32 i4_is_gop_closed,
   1158                                    WORD32 *pi4_b_in_incomp_subgop,
   1159                                    WORD32 *pi4_extra_p)
   1160 {
   1161     /*
   1162      * Find the pic distribution in the gop depending on the inter and intra
   1163      * frm intervals
   1164      */
   1165     i4_frms_in_gop[I_PIC] = 1;
   1166 
   1167     /* All I frames */
   1168     if(i4_intra_frm_int == 1)
   1169     {
   1170         i4_frms_in_gop[P_PIC] = 0;
   1171         i4_frms_in_gop[B_PIC] = 0;
   1172         *pi4_b_in_incomp_subgop = 0;
   1173         *pi4_extra_p = 0;
   1174     }
   1175     else
   1176     {
   1177         if(i4_is_gop_closed)
   1178         {
   1179             i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 2) / i4_inter_frm_int)
   1180                             + 1;
   1181 
   1182             if((((i4_intra_frm_int - 2) / i4_inter_frm_int) * i4_inter_frm_int)
   1183                             == (i4_intra_frm_int - 2))
   1184             {
   1185                 *pi4_extra_p = 1;
   1186             }
   1187             else
   1188             {
   1189                 *pi4_extra_p = 0;
   1190             }
   1191         }
   1192         else
   1193         {
   1194             i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 1) / i4_inter_frm_int);
   1195 
   1196             *pi4_extra_p = 0;
   1197         }
   1198 
   1199         i4_frms_in_gop[B_PIC] = (i4_intra_frm_int - 1 - i4_frms_in_gop[P_PIC]);
   1200 
   1201         *pi4_b_in_incomp_subgop = (i4_frms_in_gop[B_PIC] - (i4_inter_frm_int - 1)
   1202                                    * ((i4_intra_frm_int - 1)/ i4_inter_frm_int));
   1203     }
   1204 }
   1205 
   1206 WORD32 irc_pic_type_get_intra_frame_interval(pic_handling_t *ps_pic_handling)
   1207 {
   1208 
   1209     return (ps_pic_handling->i4_intra_frm_int);
   1210 }
   1211 
   1212 WORD32 irc_pic_type_get_inter_frame_interval(pic_handling_t *ps_pic_handling)
   1213 {
   1214     return (ps_pic_handling->i4_inter_frm_int);
   1215 }
   1216 
   1217 void irc_pic_type_get_rem_frms_in_gop(pic_handling_t *ps_pic_handling,
   1218                                       WORD32 ai4_rem_frms_in_gop[MAX_PIC_TYPE])
   1219 {
   1220     memcpy(ai4_rem_frms_in_gop, ps_pic_handling->i4_rem_frms_in_gop,
   1221            sizeof(ps_pic_handling->i4_rem_frms_in_gop));
   1222 }
   1223 
   1224 WORD32 irc_pic_type_get_frms_in_gop_force_I_frm(pic_handling_t *ps_pic_handling)
   1225 {
   1226     return (ps_pic_handling->i4_frames_in_fif_gop);
   1227 }
   1228 
   1229 void irc_pic_type_get_frms_in_gop(pic_handling_t *ps_pic_handling,
   1230                                   WORD32 ai4_frms_in_gop[MAX_PIC_TYPE])
   1231 {
   1232     memcpy(ai4_frms_in_gop, ps_pic_handling->i4_frms_in_cur_gop,
   1233            sizeof(ps_pic_handling->i4_frms_in_cur_gop));
   1234 }
   1235 
   1236 WORD32 irc_pic_type_get_disp_order_no(pic_handling_t *ps_pic_handling)
   1237 {
   1238     return (ps_pic_handling->i4_pic_disp_order_no);
   1239 }
   1240 
   1241 void irc_set_force_I_frame_flag(pic_handling_t *ps_pic_handling)
   1242 {
   1243     ps_pic_handling->i4_force_I_frame = 1;
   1244 }
   1245 WORD32 irc_get_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling)
   1246 {
   1247     return (ps_pic_handling->i4_forced_I_frame_cur_frame);
   1248 }
   1249 void irc_reset_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling)
   1250 {
   1251     ps_pic_handling->i4_forced_I_frame_cur_frame = 0;
   1252 }
   1253 
   1254 /******************************************************************************/
   1255 /* Functions that work on the encoded frames */
   1256 /******************************************************************************/
   1257 
   1258 /******************************************************************************
   1259  Function Name   : irc_update_pic_handling
   1260  Description     : Will be called only for the frames to be encoded
   1261  *****************************************************************************/
   1262 void irc_update_pic_handling(pic_handling_t *ps_pic_handling,
   1263                              picture_type_e e_pic_type)
   1264 {
   1265 
   1266     WORD32 i4_max_inter_frm_int;
   1267     WORD32 i;
   1268 
   1269     /* Initializing the local vars with that of the state struct */
   1270     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
   1271 
   1272     /* Update the variables working on the output frames */
   1273     /* Update the stack count */
   1274     ps_pic_handling->i4_stack_count++;
   1275 
   1276     if(ps_pic_handling->i4_stack_count == (i4_max_inter_frm_int + 1))
   1277     {
   1278         ps_pic_handling->i4_stack_count = 0;
   1279     }
   1280 
   1281     /* Update the rem_frms_in_gop */
   1282     ps_pic_handling->i4_rem_frms_in_gop[e_pic_type]--;
   1283 
   1284     /* Assumption : Rem_frms_in_gop needs to be taken care of, for every change in frms */
   1285     ps_pic_handling->i4_last_frm_in_gop = 0;
   1286     if((ps_pic_handling->i4_rem_frms_in_gop[I_PIC] <= 0)
   1287                     && (ps_pic_handling->i4_rem_frms_in_gop[P_PIC] <= 0)
   1288                     && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC] <= 0))
   1289     {
   1290         /* Copy the cur_frms_in_gop to the rem_frm_in_gop */
   1291         for(i = 0; i < MAX_PIC_TYPE; i++)
   1292         {
   1293             ps_pic_handling->i4_rem_frms_in_gop[i] =
   1294                             ps_pic_handling->i4_frms_in_cur_gop[i];
   1295         }
   1296 
   1297         ps_pic_handling->i4_last_frm_in_gop = 1;
   1298         ps_pic_handling->i4_first_gop_encoded = 1;
   1299     }
   1300 }
   1301 
   1302 WORD32 irc_is_last_frame_in_gop(pic_handling_handle ps_pic_handling)
   1303 {
   1304     return (ps_pic_handling->i4_last_frm_in_gop);
   1305 }
   1306 
   1307 /******************************************************************************
   1308  Function Name   : irc_skip_encoded_frame
   1309  Description     : Needs to go to the current pic in the pic_stack.
   1310                    If it's B_PIC don't do anything
   1311                    If it's a reference picture, push all but the last B_PICs
   1312                    in the current subgop one place down (i.e. just copy their
   1313                    pic_details) and move the last B_PIC in that subgop to the
   1314                    next slot of the skipped picture and convert it's pic_type
   1315                    to that of the reference picture
   1316  *****************************************************************************/
   1317 void irc_skip_encoded_frame(pic_handling_t *ps_pic_handling,
   1318                             picture_type_e e_pic_type)
   1319 {
   1320     pic_details_t s_pic_details;
   1321     WORD32 i4_stack_count, i4_next_ref_pic_idx, i4_pic_idx;
   1322     WORD32 i4_max_inter_frm_int, i4_last_b_pic_idx, i4_first_b_pic_idx;
   1323     WORD32 i4_next_pic_idx;
   1324 
   1325     /* State variables used to initialize the local vars (Not to be changed) */
   1326     i4_stack_count = ps_pic_handling->i4_stack_count;
   1327     i4_next_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
   1328     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
   1329 
   1330     i4_next_pic_idx = ((i4_stack_count + 1) % (i4_max_inter_frm_int + 1));
   1331 
   1332     /*
   1333      * Check what is the encoded frm_type
   1334      * Changing a B_PIC to a ref_pic is not reqd if
   1335      * there are no B_PICs referring from the skipped ref_pic
   1336      */
   1337     if(((e_pic_type == P_PIC) || (e_pic_type == I_PIC))
   1338                     && (i4_next_pic_idx != i4_next_ref_pic_idx))
   1339     {
   1340         /* Go to the last B_PIC before the next_ref_pic */
   1341         if(i4_next_ref_pic_idx == 0)
   1342         {
   1343             i4_last_b_pic_idx = i4_max_inter_frm_int;
   1344         }
   1345         else
   1346         {
   1347             i4_last_b_pic_idx = (i4_next_ref_pic_idx - 1);
   1348         }
   1349 
   1350         /* Keep a copy of the last B_PIC pic_details */
   1351         memcpy(&s_pic_details,
   1352                &ps_pic_handling->as_pic_stack[i4_last_b_pic_idx],
   1353                sizeof(pic_details_t));
   1354 
   1355         i4_pic_idx = i4_last_b_pic_idx;
   1356         i4_first_b_pic_idx = (i4_stack_count + 1) % (i4_max_inter_frm_int + 1);
   1357 
   1358         /*
   1359          * All the B_PICs other than the last one, need to be shifted one place
   1360          * in the stack
   1361          */
   1362         while((i4_pic_idx != i4_stack_count)
   1363                         && (i4_first_b_pic_idx != i4_last_b_pic_idx))
   1364         {
   1365             if(i4_pic_idx == 0)
   1366             {
   1367                 i4_pic_idx = i4_max_inter_frm_int;
   1368             }
   1369             else
   1370             {
   1371                 i4_pic_idx--;
   1372             }
   1373 
   1374             memcpy(&ps_pic_handling->as_pic_stack[(i4_pic_idx + 1)
   1375                                    % (i4_max_inter_frm_int + 1)],
   1376                    &ps_pic_handling->as_pic_stack[i4_pic_idx],
   1377                    sizeof(pic_details_t));
   1378 
   1379         }
   1380 
   1381         /*
   1382          * Copy the last B_PIC pic_details to the first B_PIC place and change
   1383          * it's pic type to the ref_PIC
   1384          */
   1385         /*e_ref_pic_type*/
   1386         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].e_pic_type = P_PIC;
   1387 
   1388         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_disp_order_no =
   1389                         s_pic_details.i4_pic_disp_order_no;
   1390         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_id =
   1391                         s_pic_details.i4_pic_id;
   1392 
   1393         /* Change the rem_frms_in_prd so that the update works properly */
   1394         if(ps_pic_handling->i4_rem_frms_in_gop[B_PIC] > 0)
   1395         {
   1396             ps_pic_handling->i4_rem_frms_in_gop[B_PIC]--;
   1397             ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++;
   1398         }
   1399     }
   1400 
   1401 }
   1402 
   1403 /******************************************************************************
   1404  Function Name   : flush_frame
   1405  Description     : Since when a flush frame is called, there will be no valid
   1406                    frames after it, the last frame cannot be a B_PIC, as there
   1407                    will be no reference frame for it (Input in display order)
   1408 
   1409                    So,this fxn needs to go to the last added pic in the pic_stack.
   1410                    If it's reference pic don't do anything
   1411                    If it's a B_PIC, copy it's pic_details and put it in the
   1412                    place of the next reference pic, changing the pic_type to
   1413                    P_PIC
   1414  *****************************************************************************/
   1415 void irc_flush_frame_from_pic_stack(pic_handling_t *ps_pic_handling)
   1416 {
   1417 
   1418     pic_details_t s_prev_pic_details;
   1419 
   1420     /* Get the last entered pic_details (not to be modified here) */
   1421     WORD32 i4_prev_b_pic_idx = ps_pic_handling->i4_prev_b_pic_idx;
   1422     WORD32 i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
   1423     WORD32 i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
   1424 
   1425     memcpy(&s_prev_pic_details, &ps_pic_handling->s_prev_pic_details,
   1426            sizeof(pic_details_t));
   1427 
   1428     if(s_prev_pic_details.e_pic_type == B_PIC)
   1429     {
   1430         /* Copy the last B_PIC details to the next reference pic in display order */
   1431         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no =
   1432                         s_prev_pic_details.i4_pic_disp_order_no;
   1433         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id =
   1434                         s_prev_pic_details.i4_pic_id;
   1435         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC;
   1436 
   1437         /*
   1438          * Modify the last B_PIC pic_type, so that codec gets to know when
   1439          * all the buffered frames
   1440          * are flushed
   1441          */
   1442         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].e_pic_type =
   1443                         MAX_PIC_TYPE;
   1444         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_id = -1;
   1445         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_disp_order_no =
   1446                         -1;
   1447     }
   1448     else
   1449     {
   1450         /*
   1451          * Modify the next pic_type details in the stack, so that codec gets to
   1452          * know when all the
   1453          * buffered frames are flushed
   1454          */
   1455         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = MAX_PIC_TYPE;
   1456         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = -1;
   1457         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no = -1;
   1458 
   1459         if(ps_pic_handling->i4_inter_frm_int != 1)
   1460         {
   1461             ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type =
   1462                             MAX_PIC_TYPE;
   1463             ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = -1;
   1464             ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no =
   1465                             -1;
   1466         }
   1467     }
   1468 }
   1469 
   1470 /******************************************************************************
   1471  Function Name   : irc_add_pic_to_stack_re_enc
   1472  Description     : In case of a re-enc, we can assume the pictures to be coming
   1473                    in the encode order.
   1474                    In case of re-encoder basically, there are 2 problematic cases.
   1475                    1)Inter_frm_int is not known to start with
   1476                    2)Inter_frm_int can keep changing
   1477                    3)Intra_frm_int set by the application and that actually in the
   1478                     decoded bitstream may be different
   1479  *****************************************************************************/
   1480 WORD32 irc_add_pic_to_stack_re_enc(pic_handling_t *ps_pic_handling,
   1481                                    WORD32 i4_enc_pic_id,
   1482                                    picture_type_e e_pic_type)
   1483 {
   1484     WORD32 i4_b_count_in_subgop;
   1485     WORD32 i4_max_inter_frm_int, i4_inter_frm_int, i4_intra_frm_int;
   1486     WORD32 i4_pic_disp_order_no;
   1487     WORD32 i4_is_gop_closed;
   1488     picture_type_e e_out_pic_type;
   1489     WORD32 i4_b_in_incomp_subgop;
   1490 
   1491     /* Check if a change in intra_frm_int call has been made */
   1492     if(ps_pic_handling->i4_change_in_intra_frm_int == 1)
   1493     {
   1494         irc_update_pic_distbn(ps_pic_handling,
   1495                               ps_pic_handling->i4_new_intra_frm_int,
   1496                               ps_pic_handling->i4_inter_frm_int, 1);
   1497         ps_pic_handling->i4_change_in_intra_frm_int = 0;
   1498     }
   1499 
   1500     /* Check if a change in inter_frm_int call has been made */
   1501     if(ps_pic_handling->i4_change_in_inter_frm_int == 1)
   1502     {
   1503         irc_update_pic_distbn(ps_pic_handling,
   1504                               ps_pic_handling->i4_intra_frm_int,
   1505                               ps_pic_handling->i4_new_inter_frm_int, 1);
   1506 
   1507         ps_pic_handling->i4_change_in_inter_frm_int = 0;
   1508     }
   1509 
   1510     /* Initialize the local vars with the state vars */
   1511     i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop;
   1512     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
   1513     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
   1514     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
   1515     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
   1516     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
   1517     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop;
   1518 
   1519     e_out_pic_type = e_pic_type;
   1520 
   1521     /* Initially the rate_control assumes an IPP sequence */
   1522     if(e_pic_type == B_PIC)
   1523     {
   1524         /* Update the number of B_PICs in a subgop */
   1525         i4_b_count_in_subgop++;
   1526 
   1527         if(i4_b_count_in_subgop > i4_max_inter_frm_int)
   1528         {
   1529             return (-1);
   1530         }
   1531 
   1532         /* If the number of B_PICs exceed the set inter_frm_int then
   1533          change the inter_frm_int */
   1534         if(i4_b_count_in_subgop > (i4_inter_frm_int - 1))
   1535         {
   1536             i4_inter_frm_int = (i4_b_count_in_subgop + 1);
   1537 
   1538             irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int,
   1539                                   i4_inter_frm_int, 0);
   1540         }
   1541     }
   1542     else if((e_pic_type == I_PIC) || (e_pic_type == P_PIC))
   1543     {
   1544         /* If the B_PICs in the prev subgop were fewer than the current
   1545          * (inter_frm_int-1) and none of these conditions occur, it'll mean the
   1546          *  decrease in the inter_frm_int
   1547          *    1)End of a GOP
   1548          *    2)Beginning of an OPEN_GOP
   1549          */
   1550         if((i4_b_count_in_subgop < (i4_inter_frm_int - 1))
   1551                         && !((!i4_is_gop_closed)
   1552                                         && (i4_b_count_in_subgop
   1553                                                         >= i4_b_in_incomp_subgop))
   1554                         && !((i4_pic_disp_order_no
   1555                                         + (i4_inter_frm_int - 1
   1556                                                         - i4_b_count_in_subgop))
   1557                                         > i4_intra_frm_int))
   1558         {
   1559             i4_inter_frm_int = (i4_b_count_in_subgop + 1);
   1560 
   1561             irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int,
   1562                                   i4_inter_frm_int, 0);
   1563         }
   1564 
   1565         /* Reset the number of B_PICs in a subgop */
   1566         i4_b_count_in_subgop = 0;
   1567     }
   1568 
   1569     /* Updation of the frame level vars */
   1570     i4_pic_disp_order_no++;
   1571 
   1572     /* End of gop condition
   1573      *Two cases can arise :
   1574      *1) The intra_frm_int set by the application is greater than the actual
   1575      *   bitstream intra_frm_int (i.e. we will get an I frame before
   1576      *   pic_disp_order_no goes to intra_frm_int)
   1577      *2) The intra_frm_int set by the application is smaller than the actual bitstream intra_frm_int
   1578      *   (i.e. we won't get an I_PIC even if pic_disp_order_no goes to
   1579      *   intra_frm_int) Constraints :
   1580      *    1) I_PIC cannot be changed to B_PIC
   1581      *    2) B_PIC cannot be changed to I_PIC
   1582      */
   1583     if(i4_pic_disp_order_no >= i4_intra_frm_int)
   1584     {
   1585         if(e_pic_type != B_PIC)
   1586         {
   1587             e_out_pic_type = I_PIC;
   1588         }
   1589         else
   1590         {
   1591             e_out_pic_type = B_PIC;
   1592             ps_pic_handling->i4_rem_frms_in_gop[B_PIC]++;
   1593             ps_pic_handling->i4_frms_in_cur_gop[B_PIC]++;
   1594             ps_pic_handling->i4_frms_in_gop[B_PIC]++;
   1595         }
   1596     }
   1597     else
   1598     {
   1599         if((e_pic_type == I_PIC) && (!ps_pic_handling->i4_is_first_gop))
   1600         {
   1601             e_out_pic_type = P_PIC;
   1602             ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++;
   1603             ps_pic_handling->i4_frms_in_cur_gop[P_PIC]++;
   1604             ps_pic_handling->i4_frms_in_gop[P_PIC]++;
   1605         }
   1606         else
   1607         {
   1608             e_out_pic_type = e_pic_type;
   1609         }
   1610     }
   1611 
   1612     /* Update the frm_vars at the end of the gop */
   1613     if(i4_pic_disp_order_no
   1614                     == (ps_pic_handling->i4_frms_in_cur_gop[P_PIC]
   1615                                     + ps_pic_handling->i4_frms_in_cur_gop[B_PIC]
   1616                                     + 1))
   1617     {
   1618         i4_pic_disp_order_no = 0;
   1619         ps_pic_handling->i4_is_first_gop = 0;
   1620     }
   1621 
   1622     /* Update the vars working on the encoded pics */
   1623     if((ps_pic_handling->i4_is_first_gop)
   1624                     && (ps_pic_handling->i4_stack_count == -1))
   1625     {
   1626         ps_pic_handling->i4_coded_pic_no = 0;
   1627         ps_pic_handling->i4_stack_count = 0;
   1628     }
   1629 
   1630     /* Add the pic_details to the pic_stack */
   1631     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].e_pic_type =
   1632                     e_out_pic_type;
   1633     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no =
   1634                     ps_pic_handling->i4_pic_disp_order_no;
   1635     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_id =
   1636                     i4_enc_pic_id;
   1637 
   1638     /* Writing back those values which need to be updated */
   1639     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
   1640     ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no;
   1641     ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop;
   1642 
   1643     return (0);
   1644 }
   1645