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  *****************************************************************************/
irc_init_vbv_str_prms(vbr_str_prms_t * p_vbr_str_prms,UWORD32 u4_intra_frm_interval,UWORD32 u4_src_ticks,UWORD32 u4_tgt_ticks,UWORD32 u4_frms_in_delay_period)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 
irc_get_vsp_num_pics_in_dly_prd(vbr_str_prms_t * p_vbr_str_prms,UWORD32 * pu4_num_pics_in_delay_prd)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  *****************************************************************************/
irc_update_vbr_str_prms(vbr_str_prms_t * p_vbr_str_prms,picture_type_e e_pic_type)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 
irc_get_vsp_src_tgt_ticks(vbr_str_prms_t * p_vbr_str_prms,UWORD32 * pu4_src_ticks,UWORD32 * pu4_tgt_ticks)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  ******************************************************************************/
irc_change_vsp_ifi(vbr_str_prms_t * p_vbr_str_prms,UWORD32 u4_intra_frame_int)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 
irc_change_vsp_tgt_ticks(vbr_str_prms_t * p_vbr_str_prms,UWORD32 u4_tgt_ticks)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 
irc_change_vsp_src_ticks(vbr_str_prms_t * p_vbr_str_prms,UWORD32 u4_src_ticks)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 
irc_change_vsp_fidp(vbr_str_prms_t * p_vbr_str_prms,UWORD32 u4_frms_in_delay_period)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