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