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 /* Includes */
     22 /*****************************************************************************/
     23 
     24 /* System include files */
     25 #include <stdio.h>
     26 
     27 /* User include files */
     28 #include "irc_datatypes.h"
     29 #include "irc_cntrl_param.h"
     30 #include "irc_vbr_str_prms.h"
     31 
     32 /******************************************************************************
     33  Function Name   : irc_init_vbv_str_prms
     34  Description     : Initializes and calculates the number of I frame and P frames
     35                    in the delay period
     36  Return Values   : void
     37  *****************************************************************************/
     38 void irc_init_vbv_str_prms(vbr_str_prms_t *p_vbr_str_prms,
     39                            UWORD32 u4_intra_frm_interval,
     40                            UWORD32 u4_src_ticks,
     41                            UWORD32 u4_tgt_ticks,
     42                            UWORD32 u4_frms_in_delay_period)
     43 {
     44 
     45     UWORD32 i4_num_i_frms_in_delay_per, i4_num_p_frms_in_delay_per;
     46 
     47     p_vbr_str_prms->u4_frms_in_delay_prd = u4_frms_in_delay_period;
     48     p_vbr_str_prms->u4_src_ticks = u4_src_ticks;
     49     p_vbr_str_prms->u4_tgt_ticks = u4_tgt_ticks;
     50     p_vbr_str_prms->u4_intra_frame_int = u4_intra_frm_interval;
     51 
     52     /*
     53      * Finding the number of I frames and P frames in delay period. This
     54      * value along with the drain rates for the corresponding picture types will
     55      * be used to calculate the buffer sizes
     56      */
     57     i4_num_i_frms_in_delay_per = ((u4_frms_in_delay_period * u4_src_ticks)
     58                     / (u4_intra_frm_interval * u4_tgt_ticks));
     59 
     60     /* Ceiling the above result*/
     61     if((i4_num_i_frms_in_delay_per * u4_intra_frm_interval * u4_tgt_ticks)
     62                     < (u4_frms_in_delay_period * u4_src_ticks))
     63     {
     64         i4_num_i_frms_in_delay_per++;
     65 
     66     }
     67     i4_num_p_frms_in_delay_per = u4_frms_in_delay_period
     68                     - i4_num_i_frms_in_delay_per;
     69 
     70     p_vbr_str_prms->u4_num_pics_in_delay_prd[I_PIC] =
     71                     i4_num_i_frms_in_delay_per;
     72     p_vbr_str_prms->u4_num_pics_in_delay_prd[P_PIC] =
     73                     i4_num_p_frms_in_delay_per;
     74     p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks = (u4_intra_frm_interval
     75                     * (p_vbr_str_prms->u4_num_pics_in_delay_prd[I_PIC]))
     76                     * u4_tgt_ticks;
     77     p_vbr_str_prms->u4_pic_num = 0;
     78     p_vbr_str_prms->u4_cur_pos_in_src_ticks = 0;
     79 }
     80 
     81 WORD32 irc_get_vsp_num_pics_in_dly_prd(vbr_str_prms_t *p_vbr_str_prms,
     82                                        UWORD32 *pu4_num_pics_in_delay_prd)
     83 {
     84     pu4_num_pics_in_delay_prd[I_PIC] =
     85                     p_vbr_str_prms->u4_num_pics_in_delay_prd[I_PIC];
     86     pu4_num_pics_in_delay_prd[P_PIC] =
     87                     p_vbr_str_prms->u4_num_pics_in_delay_prd[P_PIC];
     88     return (p_vbr_str_prms->u4_frms_in_delay_prd);
     89 }
     90 
     91 /******************************************************************************
     92  Function Name   : irc_update_vbr_str_prms
     93  Description     : update the number of I frames and P/B frames in the delay period
     94                    for buffer size calculations
     95  *****************************************************************************/
     96 void irc_update_vbr_str_prms(vbr_str_prms_t *p_vbr_str_prms,
     97                              picture_type_e e_pic_type)
     98 {
     99     /*
    100      * Updating the number of I frames and P frames after encoding every
    101      * picture. These values along with the drain rates for the corresponding
    102      * picture  types will be used to calculate the CBR buffer size every frame
    103      */
    104 
    105     if(e_pic_type == I_PIC)
    106     {
    107         p_vbr_str_prms->u4_num_pics_in_delay_prd[I_PIC]--;
    108     }
    109     else
    110     {
    111         p_vbr_str_prms->u4_num_pics_in_delay_prd[P_PIC]--;
    112     }
    113 
    114     /* If the next I frame falls within the delay period, we need to increment
    115      * the number of I frames in the period, else increment the number of P
    116      * frames
    117      */
    118     if((p_vbr_str_prms->u4_cur_pos_in_src_ticks
    119                     + (p_vbr_str_prms->u4_frms_in_delay_prd
    120                                     * p_vbr_str_prms->u4_src_ticks))
    121                     >= p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks)
    122     {
    123         p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks -=
    124                         p_vbr_str_prms->u4_cur_pos_in_src_ticks;
    125         p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks +=
    126                         p_vbr_str_prms->u4_intra_frame_int
    127                                         * p_vbr_str_prms->u4_tgt_ticks;
    128         p_vbr_str_prms->u4_num_pics_in_delay_prd[I_PIC]++;
    129         p_vbr_str_prms->u4_pic_num = 0;
    130         p_vbr_str_prms->u4_cur_pos_in_src_ticks = 0;
    131     }
    132     else
    133     {
    134         p_vbr_str_prms->u4_num_pics_in_delay_prd[P_PIC]++;
    135     }
    136     p_vbr_str_prms->u4_pic_num++;
    137     p_vbr_str_prms->u4_cur_pos_in_src_ticks += p_vbr_str_prms->u4_src_ticks;
    138 }
    139 
    140 void irc_get_vsp_src_tgt_ticks(vbr_str_prms_t *p_vbr_str_prms,
    141                                UWORD32 *pu4_src_ticks,
    142                                UWORD32 *pu4_tgt_ticks)
    143 {
    144     pu4_src_ticks[0] = p_vbr_str_prms->u4_src_ticks;
    145     pu4_tgt_ticks[0] = p_vbr_str_prms->u4_tgt_ticks;
    146 }
    147 
    148 /*******************************************************************************
    149  Function Name   : change_vbr_str_prms
    150  Description     : Takes in changes of Intra frame interval, source and target
    151                    ticks and recalculates the position of the  next I frame
    152  ******************************************************************************/
    153 void irc_change_vsp_ifi(vbr_str_prms_t *p_vbr_str_prms,
    154                         UWORD32 u4_intra_frame_int)
    155 {
    156     irc_init_vbv_str_prms(p_vbr_str_prms, u4_intra_frame_int,
    157                           p_vbr_str_prms->u4_src_ticks,
    158                           p_vbr_str_prms->u4_tgt_ticks,
    159                           p_vbr_str_prms->u4_frms_in_delay_prd);
    160 }
    161 
    162 void irc_change_vsp_tgt_ticks(vbr_str_prms_t *p_vbr_str_prms,
    163                               UWORD32 u4_tgt_ticks)
    164 {
    165     UWORD32 u4_rem_intra_per_scaled;
    166     UWORD32 u4_prev_tgt_ticks = p_vbr_str_prms->u4_tgt_ticks;
    167 
    168     /*
    169      * If the target frame rate is changed, recalculate the position of the next
    170      * I frame based on the new target frame rate
    171      * LIMITATIONS :
    172      * Currently no support is available for dynamic change in source frame rate
    173      */
    174 
    175     u4_rem_intra_per_scaled = ((p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks
    176                     - p_vbr_str_prms->u4_cur_pos_in_src_ticks)
    177                     / u4_prev_tgt_ticks) * u4_tgt_ticks;
    178 
    179     p_vbr_str_prms->u4_intra_prd_pos_in_tgt_ticks = u4_rem_intra_per_scaled
    180                     + p_vbr_str_prms->u4_cur_pos_in_src_ticks;
    181 
    182 }
    183 
    184 void irc_change_vsp_src_ticks(vbr_str_prms_t *p_vbr_str_prms,
    185                               UWORD32 u4_src_ticks)
    186 {
    187     irc_init_vbv_str_prms(p_vbr_str_prms, p_vbr_str_prms->u4_intra_frame_int,
    188                           u4_src_ticks, p_vbr_str_prms->u4_tgt_ticks,
    189                           p_vbr_str_prms->u4_frms_in_delay_prd);
    190 }
    191 
    192 void irc_change_vsp_fidp(vbr_str_prms_t *p_vbr_str_prms,
    193                          UWORD32 u4_frms_in_delay_period)
    194 {
    195     irc_init_vbv_str_prms(p_vbr_str_prms, p_vbr_str_prms->u4_intra_frame_int,
    196                           p_vbr_str_prms->u4_src_ticks,
    197                           p_vbr_str_prms->u4_tgt_ticks,
    198                           u4_frms_in_delay_period);
    199 }
    200