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