xref: /aosp_15_r20/external/libavc/encoder/irc_bit_allocation.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /** Includes */
22*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
23*495ae853SAndroid Build Coastguard Worker #include <string.h>
24*495ae853SAndroid Build Coastguard Worker #include "irc_datatypes.h"
25*495ae853SAndroid Build Coastguard Worker #include "irc_mem_req_and_acq.h"
26*495ae853SAndroid Build Coastguard Worker #include "irc_common.h"
27*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
28*495ae853SAndroid Build Coastguard Worker #include "irc_fixed_point_error_bits.h"
29*495ae853SAndroid Build Coastguard Worker #include "irc_rd_model.h"
30*495ae853SAndroid Build Coastguard Worker #include "irc_est_sad.h"
31*495ae853SAndroid Build Coastguard Worker #include "irc_picture_type.h"
32*495ae853SAndroid Build Coastguard Worker #include "irc_bit_allocation.h"
33*495ae853SAndroid Build Coastguard Worker #include "irc_trace_support.h"
34*495ae853SAndroid Build Coastguard Worker 
35*495ae853SAndroid Build Coastguard Worker /** Macros **/
36*495ae853SAndroid Build Coastguard Worker #define MIN(x,y)  ((x) < (y))? (x) : (y)
37*495ae853SAndroid Build Coastguard Worker 
38*495ae853SAndroid Build Coastguard Worker /* State structure for bit allocation */
39*495ae853SAndroid Build Coastguard Worker typedef struct
40*495ae853SAndroid Build Coastguard Worker {
41*495ae853SAndroid Build Coastguard Worker     /* using var_q number as it can cross 31 bits for large intra frameinterval */
42*495ae853SAndroid Build Coastguard Worker     number_t vq_rem_bits_in_period;
43*495ae853SAndroid Build Coastguard Worker 
44*495ae853SAndroid Build Coastguard Worker     /* Storing inputs */
45*495ae853SAndroid Build Coastguard Worker     WORD32 i4_tot_frms_in_gop;
46*495ae853SAndroid Build Coastguard Worker 
47*495ae853SAndroid Build Coastguard Worker     WORD32 i4_num_intra_frm_interval;
48*495ae853SAndroid Build Coastguard Worker 
49*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bits_per_frm;
50*495ae853SAndroid Build Coastguard Worker 
51*495ae853SAndroid Build Coastguard Worker } rem_bit_in_prd_t;
52*495ae853SAndroid Build Coastguard Worker 
53*495ae853SAndroid Build Coastguard Worker typedef struct bit_allocation_t
54*495ae853SAndroid Build Coastguard Worker {
55*495ae853SAndroid Build Coastguard Worker     rem_bit_in_prd_t s_rbip;
56*495ae853SAndroid Build Coastguard Worker 
57*495ae853SAndroid Build Coastguard Worker     /* A universal constant giving the relative complexity between pictures */
58*495ae853SAndroid Build Coastguard Worker     WORD32 i2_K[MAX_PIC_TYPE];
59*495ae853SAndroid Build Coastguard Worker 
60*495ae853SAndroid Build Coastguard Worker     /* To get a estimate of the header bits consumed */
61*495ae853SAndroid Build Coastguard Worker     WORD32 i4_prev_frm_header_bits[MAX_PIC_TYPE];
62*495ae853SAndroid Build Coastguard Worker 
63*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bits_per_frm;
64*495ae853SAndroid Build Coastguard Worker 
65*495ae853SAndroid Build Coastguard Worker     WORD32 i4_num_gops_in_period;
66*495ae853SAndroid Build Coastguard Worker 
67*495ae853SAndroid Build Coastguard Worker     /* Num gops as set by rate control module */
68*495ae853SAndroid Build Coastguard Worker     WORD32 i4_actual_num_gops_in_period;
69*495ae853SAndroid Build Coastguard Worker 
70*495ae853SAndroid Build Coastguard Worker     number_t vq_saved_bits;
71*495ae853SAndroid Build Coastguard Worker 
72*495ae853SAndroid Build Coastguard Worker     WORD32 i4_max_bits_per_frm[MAX_NUM_DRAIN_RATES];
73*495ae853SAndroid Build Coastguard Worker 
74*495ae853SAndroid Build Coastguard Worker     WORD32 i4_min_bits_per_frm;
75*495ae853SAndroid Build Coastguard Worker 
76*495ae853SAndroid Build Coastguard Worker     /* Error bits module */
77*495ae853SAndroid Build Coastguard Worker     error_bits_handle ps_error_bits;
78*495ae853SAndroid Build Coastguard Worker 
79*495ae853SAndroid Build Coastguard Worker     /* Storing frame rate */
80*495ae853SAndroid Build Coastguard Worker     WORD32 i4_frame_rate;
81*495ae853SAndroid Build Coastguard Worker 
82*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bit_rate;
83*495ae853SAndroid Build Coastguard Worker 
84*495ae853SAndroid Build Coastguard Worker     WORD32 ai4_peak_bit_rate[MAX_NUM_DRAIN_RATES];
85*495ae853SAndroid Build Coastguard Worker 
86*495ae853SAndroid Build Coastguard Worker } bit_allocation_t;
87*495ae853SAndroid Build Coastguard Worker 
get_number_of_frms_in_a_gop(pic_handling_handle ps_pic_handling)88*495ae853SAndroid Build Coastguard Worker static WORD32 get_number_of_frms_in_a_gop(pic_handling_handle ps_pic_handling)
89*495ae853SAndroid Build Coastguard Worker {
90*495ae853SAndroid Build Coastguard Worker     WORD32 i4_tot_frms_in_gop = 0, i;
91*495ae853SAndroid Build Coastguard Worker     WORD32 ai4_frms_in_gop[MAX_PIC_TYPE];
92*495ae853SAndroid Build Coastguard Worker 
93*495ae853SAndroid Build Coastguard Worker     /* Query the pic_handling struct for the rem frames in the period */
94*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_frms_in_gop(ps_pic_handling, ai4_frms_in_gop);
95*495ae853SAndroid Build Coastguard Worker 
96*495ae853SAndroid Build Coastguard Worker     /* Get the total frms in the gop */
97*495ae853SAndroid Build Coastguard Worker     i4_tot_frms_in_gop = 0;
98*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
99*495ae853SAndroid Build Coastguard Worker     {
100*495ae853SAndroid Build Coastguard Worker         i4_tot_frms_in_gop += ai4_frms_in_gop[i];
101*495ae853SAndroid Build Coastguard Worker     }
102*495ae853SAndroid Build Coastguard Worker     return (i4_tot_frms_in_gop);
103*495ae853SAndroid Build Coastguard Worker }
104*495ae853SAndroid Build Coastguard Worker 
init_rbip(rem_bit_in_prd_t * ps_rbip,pic_handling_handle ps_pic_handling,WORD32 i4_bits_per_frm,WORD32 i4_num_intra_frm_interval)105*495ae853SAndroid Build Coastguard Worker static void init_rbip(rem_bit_in_prd_t *ps_rbip,
106*495ae853SAndroid Build Coastguard Worker                       pic_handling_handle ps_pic_handling,
107*495ae853SAndroid Build Coastguard Worker                       WORD32 i4_bits_per_frm,
108*495ae853SAndroid Build Coastguard Worker                       WORD32 i4_num_intra_frm_interval)
109*495ae853SAndroid Build Coastguard Worker {
110*495ae853SAndroid Build Coastguard Worker     WORD32 i4_tot_frms_in_gop = get_number_of_frms_in_a_gop(ps_pic_handling);
111*495ae853SAndroid Build Coastguard Worker 
112*495ae853SAndroid Build Coastguard Worker     /* rem_bits_in_period = bits_per_frm * tot_frms_in_gop * num_intra_frm_interval */
113*495ae853SAndroid Build Coastguard Worker     {
114*495ae853SAndroid Build Coastguard Worker         number_t vq_bits_per_frm, vq_tot_frms_in_gop, vq_num_intra_frm_interval;
115*495ae853SAndroid Build Coastguard Worker         number_t *pvq_rem_bits_in_period = &ps_rbip->vq_rem_bits_in_period;
116*495ae853SAndroid Build Coastguard Worker 
117*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_bits_per_frm, i4_bits_per_frm, 0);
118*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_tot_frms_in_gop, i4_tot_frms_in_gop, 0);
119*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_num_intra_frm_interval, i4_num_intra_frm_interval, 0);
120*495ae853SAndroid Build Coastguard Worker 
121*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period = bits_per_frm * tot_frms_in_gop */
122*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_bits_per_frm, vq_tot_frms_in_gop,
123*495ae853SAndroid Build Coastguard Worker                      pvq_rem_bits_in_period);
124*495ae853SAndroid Build Coastguard Worker 
125*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period *= num_intra_frm_interval */
126*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_num_intra_frm_interval, pvq_rem_bits_in_period[0],
127*495ae853SAndroid Build Coastguard Worker                      pvq_rem_bits_in_period);
128*495ae853SAndroid Build Coastguard Worker     }
129*495ae853SAndroid Build Coastguard Worker 
130*495ae853SAndroid Build Coastguard Worker     /*
131*495ae853SAndroid Build Coastguard Worker      * Store the total number of frames in GOP value which is
132*495ae853SAndroid Build Coastguard Worker      * used from module A
133*495ae853SAndroid Build Coastguard Worker      */
134*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_tot_frms_in_gop = i4_tot_frms_in_gop;
135*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_num_intra_frm_interval = i4_num_intra_frm_interval;
136*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_bits_per_frm = i4_bits_per_frm;
137*495ae853SAndroid Build Coastguard Worker }
138*495ae853SAndroid Build Coastguard Worker 
check_update_rbip(rem_bit_in_prd_t * ps_rbip,pic_handling_handle ps_pic_handling)139*495ae853SAndroid Build Coastguard Worker static void check_update_rbip(rem_bit_in_prd_t *ps_rbip,
140*495ae853SAndroid Build Coastguard Worker                               pic_handling_handle ps_pic_handling)
141*495ae853SAndroid Build Coastguard Worker {
142*495ae853SAndroid Build Coastguard Worker     /*
143*495ae853SAndroid Build Coastguard Worker      * NOTE: Intra frame interval changes after the first I frame that is
144*495ae853SAndroid Build Coastguard Worker      * encoded in a GOP
145*495ae853SAndroid Build Coastguard Worker      */
146*495ae853SAndroid Build Coastguard Worker     WORD32 i4_new_tot_frms_in_gop = get_number_of_frms_in_a_gop(
147*495ae853SAndroid Build Coastguard Worker                     ps_pic_handling);
148*495ae853SAndroid Build Coastguard Worker 
149*495ae853SAndroid Build Coastguard Worker     if(i4_new_tot_frms_in_gop != ps_rbip->i4_tot_frms_in_gop)
150*495ae853SAndroid Build Coastguard Worker     {
151*495ae853SAndroid Build Coastguard Worker         WORD32 i4_rem_frames_in_period =
152*495ae853SAndroid Build Coastguard Worker                         ps_rbip->i4_num_intra_frm_interval
153*495ae853SAndroid Build Coastguard Worker                                         * (i4_new_tot_frms_in_gop
154*495ae853SAndroid Build Coastguard Worker                                                         - ps_rbip->i4_tot_frms_in_gop);
155*495ae853SAndroid Build Coastguard Worker 
156*495ae853SAndroid Build Coastguard Worker         number_t vq_rem_frms_in_period, s_bits_per_frm, vq_delta_bits_in_period;
157*495ae853SAndroid Build Coastguard Worker 
158*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_rem_frms_in_period, i4_rem_frames_in_period, 0);
159*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(s_bits_per_frm, ps_rbip->i4_bits_per_frm, 0);
160*495ae853SAndroid Build Coastguard Worker 
161*495ae853SAndroid Build Coastguard Worker         /* delta_bits_in_period = bits_per_frm * rem_frms_in_period */
162*495ae853SAndroid Build Coastguard Worker         mult32_var_q(s_bits_per_frm, vq_rem_frms_in_period,
163*495ae853SAndroid Build Coastguard Worker                      &vq_delta_bits_in_period);
164*495ae853SAndroid Build Coastguard Worker 
165*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period += delta_bits_in_period */
166*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_delta_bits_in_period, ps_rbip->vq_rem_bits_in_period,
167*495ae853SAndroid Build Coastguard Worker                     &ps_rbip->vq_rem_bits_in_period);
168*495ae853SAndroid Build Coastguard Worker     }
169*495ae853SAndroid Build Coastguard Worker     /* Updated the new values */
170*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_tot_frms_in_gop = i4_new_tot_frms_in_gop;
171*495ae853SAndroid Build Coastguard Worker }
172*495ae853SAndroid Build Coastguard Worker 
irc_ba_update_rbip(rem_bit_in_prd_t * ps_rbip,pic_handling_handle ps_pic_handling,number_t vq_num_bits)173*495ae853SAndroid Build Coastguard Worker static void irc_ba_update_rbip(rem_bit_in_prd_t *ps_rbip,
174*495ae853SAndroid Build Coastguard Worker                                pic_handling_handle ps_pic_handling,
175*495ae853SAndroid Build Coastguard Worker                                number_t vq_num_bits)
176*495ae853SAndroid Build Coastguard Worker {
177*495ae853SAndroid Build Coastguard Worker     check_update_rbip(ps_rbip, ps_pic_handling);
178*495ae853SAndroid Build Coastguard Worker 
179*495ae853SAndroid Build Coastguard Worker     /* rem_bits_in_period += num_of_bits */
180*495ae853SAndroid Build Coastguard Worker     add32_var_q(vq_num_bits, ps_rbip->vq_rem_bits_in_period,
181*495ae853SAndroid Build Coastguard Worker                 &ps_rbip->vq_rem_bits_in_period);
182*495ae853SAndroid Build Coastguard Worker }
183*495ae853SAndroid Build Coastguard Worker 
irc_ba_change_rbip(rem_bit_in_prd_t * ps_rbip,pic_handling_handle ps_pic_handling,WORD32 i4_new_bits_per_frm,WORD32 i4_new_num_intra_frm_interval)184*495ae853SAndroid Build Coastguard Worker static void irc_ba_change_rbip(rem_bit_in_prd_t *ps_rbip,
185*495ae853SAndroid Build Coastguard Worker                                pic_handling_handle ps_pic_handling,
186*495ae853SAndroid Build Coastguard Worker                                WORD32 i4_new_bits_per_frm,
187*495ae853SAndroid Build Coastguard Worker                                WORD32 i4_new_num_intra_frm_interval)
188*495ae853SAndroid Build Coastguard Worker {
189*495ae853SAndroid Build Coastguard Worker     WORD32 ai4_rem_frms_in_period[MAX_PIC_TYPE], i4_rem_frms_in_gop, i;
190*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_rem_frms_in_gop(ps_pic_handling, ai4_rem_frms_in_period);
191*495ae853SAndroid Build Coastguard Worker 
192*495ae853SAndroid Build Coastguard Worker     i4_rem_frms_in_gop = 0;
193*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
194*495ae853SAndroid Build Coastguard Worker         i4_rem_frms_in_gop += ai4_rem_frms_in_period[i];
195*495ae853SAndroid Build Coastguard Worker 
196*495ae853SAndroid Build Coastguard Worker     if(i4_new_bits_per_frm != ps_rbip->i4_bits_per_frm)
197*495ae853SAndroid Build Coastguard Worker     {
198*495ae853SAndroid Build Coastguard Worker         WORD32 i4_rem_frms_in_period = (ps_rbip->i4_num_intra_frm_interval - 1)
199*495ae853SAndroid Build Coastguard Worker                         * ps_rbip->i4_tot_frms_in_gop + i4_rem_frms_in_gop;
200*495ae853SAndroid Build Coastguard Worker 
201*495ae853SAndroid Build Coastguard Worker         number_t vq_rem_frms_in_period, vq_delta_bits_per_frm,
202*495ae853SAndroid Build Coastguard Worker                         vq_delta_bits_in_period;
203*495ae853SAndroid Build Coastguard Worker 
204*495ae853SAndroid Build Coastguard Worker         /* delta_bits_per_frm = new_bits_per_frm - old_bits_per_frm */
205*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_delta_bits_per_frm,
206*495ae853SAndroid Build Coastguard Worker                   (i4_new_bits_per_frm - ps_rbip->i4_bits_per_frm), 0);
207*495ae853SAndroid Build Coastguard Worker 
208*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_rem_frms_in_period, i4_rem_frms_in_period, 0);
209*495ae853SAndroid Build Coastguard Worker 
210*495ae853SAndroid Build Coastguard Worker         /* delta_bits_in_period = delta_bits_per_frm * rem_frms_in_period */
211*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_delta_bits_per_frm, vq_rem_frms_in_period,
212*495ae853SAndroid Build Coastguard Worker                      &vq_delta_bits_in_period);
213*495ae853SAndroid Build Coastguard Worker 
214*495ae853SAndroid Build Coastguard Worker         /* ps_rbip->rem_bits_in_period += delta_bits_in_period */
215*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_delta_bits_in_period, ps_rbip->vq_rem_bits_in_period,
216*495ae853SAndroid Build Coastguard Worker                     &ps_rbip->vq_rem_bits_in_period);
217*495ae853SAndroid Build Coastguard Worker     }
218*495ae853SAndroid Build Coastguard Worker 
219*495ae853SAndroid Build Coastguard Worker     if(i4_new_num_intra_frm_interval != ps_rbip->i4_num_intra_frm_interval)
220*495ae853SAndroid Build Coastguard Worker     {
221*495ae853SAndroid Build Coastguard Worker         WORD32 i4_rem_frms_in_period = ps_rbip->i4_tot_frms_in_gop
222*495ae853SAndroid Build Coastguard Worker                         * (i4_new_num_intra_frm_interval
223*495ae853SAndroid Build Coastguard Worker                                         - ps_rbip->i4_num_intra_frm_interval);
224*495ae853SAndroid Build Coastguard Worker 
225*495ae853SAndroid Build Coastguard Worker         number_t vq_rem_frms_in_period, vq_new_bits_per_frm,
226*495ae853SAndroid Build Coastguard Worker                         vq_delta_bits_in_period;
227*495ae853SAndroid Build Coastguard Worker 
228*495ae853SAndroid Build Coastguard Worker         /* new_bits_per_frm = new_new_bits_per_frm - old_new_bits_per_frm */
229*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_new_bits_per_frm, i4_new_bits_per_frm, 0);
230*495ae853SAndroid Build Coastguard Worker 
231*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_rem_frms_in_period, i4_rem_frms_in_period, 0);
232*495ae853SAndroid Build Coastguard Worker 
233*495ae853SAndroid Build Coastguard Worker         /* delta_bits_in_period = new_bits_per_frm * rem_frms_in_period */
234*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_new_bits_per_frm, vq_rem_frms_in_period,
235*495ae853SAndroid Build Coastguard Worker                      &vq_delta_bits_in_period);
236*495ae853SAndroid Build Coastguard Worker 
237*495ae853SAndroid Build Coastguard Worker         /* ps_rbip->rem_bits_in_period += delta_bits_in_period */
238*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_delta_bits_in_period, ps_rbip->vq_rem_bits_in_period,
239*495ae853SAndroid Build Coastguard Worker                     &ps_rbip->vq_rem_bits_in_period);
240*495ae853SAndroid Build Coastguard Worker     }
241*495ae853SAndroid Build Coastguard Worker     /* Update the new value */
242*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_num_intra_frm_interval = i4_new_num_intra_frm_interval;
243*495ae853SAndroid Build Coastguard Worker     ps_rbip->i4_bits_per_frm = i4_new_bits_per_frm;
244*495ae853SAndroid Build Coastguard Worker }
245*495ae853SAndroid Build Coastguard Worker 
irc_ba_num_fill_use_free_memtab(bit_allocation_t ** pps_bit_allocation,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)246*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_num_fill_use_free_memtab(bit_allocation_t **pps_bit_allocation,
247*495ae853SAndroid Build Coastguard Worker                                        itt_memtab_t *ps_memtab,
248*495ae853SAndroid Build Coastguard Worker                                        ITT_FUNC_TYPE_E e_func_type)
249*495ae853SAndroid Build Coastguard Worker {
250*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mem_tab_idx = 0;
251*495ae853SAndroid Build Coastguard Worker     bit_allocation_t s_bit_allocation_temp;
252*495ae853SAndroid Build Coastguard Worker 
253*495ae853SAndroid Build Coastguard Worker     /*
254*495ae853SAndroid Build Coastguard Worker      * Hack for all alloc, during which we don't have any state memory.
255*495ae853SAndroid Build Coastguard Worker      * Dereferencing can cause issues
256*495ae853SAndroid Build Coastguard Worker      */
257*495ae853SAndroid Build Coastguard Worker     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
258*495ae853SAndroid Build Coastguard Worker         (*pps_bit_allocation) = &s_bit_allocation_temp;
259*495ae853SAndroid Build Coastguard Worker 
260*495ae853SAndroid Build Coastguard Worker     /*for src rate control state structure*/
261*495ae853SAndroid Build Coastguard Worker     if(e_func_type != GET_NUM_MEMTAB)
262*495ae853SAndroid Build Coastguard Worker     {
263*495ae853SAndroid Build Coastguard Worker         fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(bit_allocation_t),
264*495ae853SAndroid Build Coastguard Worker                     ALIGN_128_BYTE, PERSISTENT, DDR);
265*495ae853SAndroid Build Coastguard Worker         use_or_fill_base(&ps_memtab[0], (void**)pps_bit_allocation,
266*495ae853SAndroid Build Coastguard Worker                          e_func_type);
267*495ae853SAndroid Build Coastguard Worker     }
268*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx++;
269*495ae853SAndroid Build Coastguard Worker 
270*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_error_bits_num_fill_use_free_memtab(
271*495ae853SAndroid Build Coastguard Worker                     &pps_bit_allocation[0]->ps_error_bits,
272*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
273*495ae853SAndroid Build Coastguard Worker 
274*495ae853SAndroid Build Coastguard Worker     return (i4_mem_tab_idx);
275*495ae853SAndroid Build Coastguard Worker }
276*495ae853SAndroid Build Coastguard Worker 
277*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
278*495ae853SAndroid Build Coastguard Worker  Function Name : irc_ba_init_bit_allocation
279*495ae853SAndroid Build Coastguard Worker  Description   : Initialize the bit_allocation structure.
280*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_ba_init_bit_allocation(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling,WORD32 i4_num_intra_frm_interval,WORD32 i4_bit_rate,WORD32 i4_frm_rate,WORD32 * i4_peak_bit_rate,WORD32 i4_min_bitrate)281*495ae853SAndroid Build Coastguard Worker void irc_ba_init_bit_allocation(bit_allocation_t *ps_bit_allocation,
282*495ae853SAndroid Build Coastguard Worker                                 pic_handling_handle ps_pic_handling,
283*495ae853SAndroid Build Coastguard Worker                                 WORD32 i4_num_intra_frm_interval,
284*495ae853SAndroid Build Coastguard Worker                                 WORD32 i4_bit_rate,
285*495ae853SAndroid Build Coastguard Worker                                 WORD32 i4_frm_rate,
286*495ae853SAndroid Build Coastguard Worker                                 WORD32 *i4_peak_bit_rate,
287*495ae853SAndroid Build Coastguard Worker                                 WORD32 i4_min_bitrate)
288*495ae853SAndroid Build Coastguard Worker {
289*495ae853SAndroid Build Coastguard Worker     WORD32 i;
290*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bits_per_frm, i4_max_bits_per_frm[MAX_NUM_DRAIN_RATES];
291*495ae853SAndroid Build Coastguard Worker 
292*495ae853SAndroid Build Coastguard Worker     /* Calculate the bits per frame */
293*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(i4_bit_rate, 1000, i4_frm_rate, i4_bits_per_frm);
294*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
295*495ae853SAndroid Build Coastguard Worker     {
296*495ae853SAndroid Build Coastguard Worker         X_PROD_Y_DIV_Z(i4_peak_bit_rate[i], 1000, i4_frm_rate,
297*495ae853SAndroid Build Coastguard Worker                        i4_max_bits_per_frm[i]);
298*495ae853SAndroid Build Coastguard Worker     }
299*495ae853SAndroid Build Coastguard Worker     /* Initialize the bits_per_frame */
300*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_bits_per_frm = i4_bits_per_frm;
301*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
302*495ae853SAndroid Build Coastguard Worker     {
303*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->i4_max_bits_per_frm[i] = i4_max_bits_per_frm[i];
304*495ae853SAndroid Build Coastguard Worker     }
305*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(i4_min_bitrate, 1000, i4_frm_rate,
306*495ae853SAndroid Build Coastguard Worker                    ps_bit_allocation->i4_min_bits_per_frm);
307*495ae853SAndroid Build Coastguard Worker 
308*495ae853SAndroid Build Coastguard Worker     /*
309*495ae853SAndroid Build Coastguard Worker      * Initialize the rem_bits in period
310*495ae853SAndroid Build Coastguard Worker      * The first gop in case of an OPEN GOP may have fewer B_PICs,
311*495ae853SAndroid Build Coastguard Worker      * That condition is not taken care of
312*495ae853SAndroid Build Coastguard Worker      */
313*495ae853SAndroid Build Coastguard Worker     init_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, i4_bits_per_frm,
314*495ae853SAndroid Build Coastguard Worker               i4_num_intra_frm_interval);
315*495ae853SAndroid Build Coastguard Worker 
316*495ae853SAndroid Build Coastguard Worker     /* Initialize the num_gops_in_period */
317*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_num_gops_in_period = i4_num_intra_frm_interval;
318*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_actual_num_gops_in_period = i4_num_intra_frm_interval;
319*495ae853SAndroid Build Coastguard Worker 
320*495ae853SAndroid Build Coastguard Worker     /* Relative complexity between I and P frames */
321*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i2_K[I_PIC] = (1 << K_Q);
322*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i2_K[P_PIC] = I_TO_P_RATIO;
323*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i2_K[B_PIC] = (P_TO_B_RATIO * I_TO_P_RATIO) >> K_Q;
324*495ae853SAndroid Build Coastguard Worker 
325*495ae853SAndroid Build Coastguard Worker     /* Initialize the saved bits to 0*/
326*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(ps_bit_allocation->vq_saved_bits, 0, 0);
327*495ae853SAndroid Build Coastguard Worker 
328*495ae853SAndroid Build Coastguard Worker     /* Update the error bits module with average bits */
329*495ae853SAndroid Build Coastguard Worker     irc_init_error_bits(ps_bit_allocation->ps_error_bits, i4_frm_rate,
330*495ae853SAndroid Build Coastguard Worker                         i4_bit_rate);
331*495ae853SAndroid Build Coastguard Worker     /* Store the input for implementing change in values */
332*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_frame_rate = i4_frm_rate;
333*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_bit_rate = i4_bit_rate;
334*495ae853SAndroid Build Coastguard Worker 
335*495ae853SAndroid Build Coastguard Worker     memset(ps_bit_allocation->i4_prev_frm_header_bits, 0, sizeof(ps_bit_allocation->i4_prev_frm_header_bits));
336*495ae853SAndroid Build Coastguard Worker     for(i=0;i<MAX_NUM_DRAIN_RATES;i++)
337*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->ai4_peak_bit_rate[i] = i4_peak_bit_rate[i];
338*495ae853SAndroid Build Coastguard Worker }
339*495ae853SAndroid Build Coastguard Worker 
340*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
341*495ae853SAndroid Build Coastguard Worker  Function Name : get_cur_frm_est_bits
342*495ae853SAndroid Build Coastguard Worker  Description   : Based on remaining bits in period and rd_model
343*495ae853SAndroid Build Coastguard Worker  the number of bits required for the current frame is estimated.
344*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_ba_get_cur_frm_est_texture_bits(bit_allocation_t * ps_bit_allocation,rc_rd_model_handle * pps_rd_model,est_sad_handle ps_est_sad,pic_handling_handle ps_pic_handling,picture_type_e e_pic_type)345*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_get_cur_frm_est_texture_bits(bit_allocation_t *ps_bit_allocation,
346*495ae853SAndroid Build Coastguard Worker                                            rc_rd_model_handle *pps_rd_model,
347*495ae853SAndroid Build Coastguard Worker                                            est_sad_handle ps_est_sad,
348*495ae853SAndroid Build Coastguard Worker                                            pic_handling_handle ps_pic_handling,
349*495ae853SAndroid Build Coastguard Worker                                            picture_type_e e_pic_type)
350*495ae853SAndroid Build Coastguard Worker {
351*495ae853SAndroid Build Coastguard Worker     WORD32 i, j;
352*495ae853SAndroid Build Coastguard Worker     WORD32 i4_est_texture_bits_for_frm;
353*495ae853SAndroid Build Coastguard Worker     number_t vq_rem_texture_bits;
354*495ae853SAndroid Build Coastguard Worker     number_t vq_complexity_estimate[MAX_PIC_TYPE];
355*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rem_frms_in_period[MAX_PIC_TYPE], i4_frms_in_period[MAX_PIC_TYPE];
356*495ae853SAndroid Build Coastguard Worker     number_t vq_max_consumable_bits;
357*495ae853SAndroid Build Coastguard Worker     number_t vq_rem_frms_in_period[MAX_PIC_TYPE], vq_est_texture_bits_for_frm;
358*495ae853SAndroid Build Coastguard Worker     number_t vq_prev_hdr_bits[MAX_PIC_TYPE];
359*495ae853SAndroid Build Coastguard Worker     number_t vq_num_bits;
360*495ae853SAndroid Build Coastguard Worker     WORD32 complexity_est = 0;
361*495ae853SAndroid Build Coastguard Worker 
362*495ae853SAndroid Build Coastguard Worker     /* Get the rem_frms_in_gop & the frms_in_gop from the pic_type state struct */
363*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_rem_frms_in_gop(ps_pic_handling, i4_rem_frms_in_period);
364*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_frms_in_gop(ps_pic_handling, i4_frms_in_period);
365*495ae853SAndroid Build Coastguard Worker 
366*495ae853SAndroid Build Coastguard Worker     /* Depending on the number of gops in a period, find the num_frms_in_prd */
367*495ae853SAndroid Build Coastguard Worker     for(j = 0; j < MAX_PIC_TYPE; j++)
368*495ae853SAndroid Build Coastguard Worker     {
369*495ae853SAndroid Build Coastguard Worker         i4_rem_frms_in_period[j] += (i4_frms_in_period[j]
370*495ae853SAndroid Build Coastguard Worker                         * (ps_bit_allocation->i4_num_gops_in_period - 1));
371*495ae853SAndroid Build Coastguard Worker         i4_frms_in_period[j] *= ps_bit_allocation->i4_num_gops_in_period;
372*495ae853SAndroid Build Coastguard Worker     }
373*495ae853SAndroid Build Coastguard Worker 
374*495ae853SAndroid Build Coastguard Worker     /* Remove the header bits from the remaining bits to find how many bits you
375*495ae853SAndroid Build Coastguard Worker      can transfer.*/
376*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_num_bits, 0, 0);
377*495ae853SAndroid Build Coastguard Worker     irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits);
378*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
379*495ae853SAndroid Build Coastguard Worker     {
380*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_rem_frms_in_period[i], i4_rem_frms_in_period[i], 0);
381*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_prev_hdr_bits[i],
382*495ae853SAndroid Build Coastguard Worker                   ps_bit_allocation->i4_prev_frm_header_bits[i], 0);
383*495ae853SAndroid Build Coastguard Worker     }
384*495ae853SAndroid Build Coastguard Worker     {
385*495ae853SAndroid Build Coastguard Worker         /*
386*495ae853SAndroid Build Coastguard Worker          *rem_texture_bits = rem_bits_in_period -
387*495ae853SAndroid Build Coastguard Worker          *(rem_frms_in_period[I_PIC] * prev_frm_header_bits[I_PIC]) -
388*495ae853SAndroid Build Coastguard Worker          *(rem_frms_in_period[P_PIC] * prev_frm_header_bits[P_PIC]) -
389*495ae853SAndroid Build Coastguard Worker          *(rem_frms_in_period[B_PIC] * prev_frm_header_bits[B_PIC]);
390*495ae853SAndroid Build Coastguard Worker          */
391*495ae853SAndroid Build Coastguard Worker         number_t vq_rem_hdr_bits;
392*495ae853SAndroid Build Coastguard Worker         vq_rem_texture_bits = ps_bit_allocation->s_rbip.vq_rem_bits_in_period;
393*495ae853SAndroid Build Coastguard Worker 
394*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_prev_hdr_bits[I_PIC], vq_rem_frms_in_period[I_PIC],
395*495ae853SAndroid Build Coastguard Worker                      &vq_rem_hdr_bits);
396*495ae853SAndroid Build Coastguard Worker         sub32_var_q(vq_rem_texture_bits, vq_rem_hdr_bits, &vq_rem_texture_bits);
397*495ae853SAndroid Build Coastguard Worker 
398*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_prev_hdr_bits[P_PIC], vq_rem_frms_in_period[P_PIC],
399*495ae853SAndroid Build Coastguard Worker                      &vq_rem_hdr_bits);
400*495ae853SAndroid Build Coastguard Worker         sub32_var_q(vq_rem_texture_bits, vq_rem_hdr_bits, &vq_rem_texture_bits);
401*495ae853SAndroid Build Coastguard Worker 
402*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_prev_hdr_bits[B_PIC], vq_rem_frms_in_period[B_PIC],
403*495ae853SAndroid Build Coastguard Worker                      &vq_rem_hdr_bits);
404*495ae853SAndroid Build Coastguard Worker         sub32_var_q(vq_rem_texture_bits, vq_rem_hdr_bits, &vq_rem_texture_bits);
405*495ae853SAndroid Build Coastguard Worker     }
406*495ae853SAndroid Build Coastguard Worker     {
407*495ae853SAndroid Build Coastguard Worker         /* max_consumable_bits =
408*495ae853SAndroid Build Coastguard Worker          *(frms_in_period[I_PIC] * max_bits_per_frm[0] ) +
409*495ae853SAndroid Build Coastguard Worker          *(frms_in_period[P_PIC] + frms_in_period[B_PIC] ) * max_bits_per_frm[1];
410*495ae853SAndroid Build Coastguard Worker          */
411*495ae853SAndroid Build Coastguard Worker         number_t vq_max_bits, vq_max_bits_per_frm[2];
412*495ae853SAndroid Build Coastguard Worker 
413*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_max_bits_per_frm[0],
414*495ae853SAndroid Build Coastguard Worker                   ps_bit_allocation->i4_max_bits_per_frm[0], 0);
415*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_max_bits_per_frm[1],
416*495ae853SAndroid Build Coastguard Worker                   ps_bit_allocation->i4_max_bits_per_frm[1], 0);
417*495ae853SAndroid Build Coastguard Worker 
418*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_rem_frms_in_period[I_PIC], vq_max_bits_per_frm[0],
419*495ae853SAndroid Build Coastguard Worker                      &vq_max_bits);
420*495ae853SAndroid Build Coastguard Worker         vq_max_consumable_bits = vq_max_bits;
421*495ae853SAndroid Build Coastguard Worker 
422*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_rem_frms_in_period[P_PIC], vq_max_bits_per_frm[1],
423*495ae853SAndroid Build Coastguard Worker                      &vq_max_bits);
424*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_max_bits, vq_max_consumable_bits,
425*495ae853SAndroid Build Coastguard Worker                     &vq_max_consumable_bits);
426*495ae853SAndroid Build Coastguard Worker 
427*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_rem_frms_in_period[B_PIC], vq_max_bits_per_frm[1],
428*495ae853SAndroid Build Coastguard Worker                      &vq_max_bits);
429*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_max_bits, vq_max_consumable_bits,
430*495ae853SAndroid Build Coastguard Worker                     &vq_max_consumable_bits);
431*495ae853SAndroid Build Coastguard Worker     }
432*495ae853SAndroid Build Coastguard Worker 
433*495ae853SAndroid Build Coastguard Worker     /* rem_texture_bits = MIN(rem_texture_bits, max_consumable_bits) */
434*495ae853SAndroid Build Coastguard Worker     MIN_VARQ(vq_max_consumable_bits, vq_rem_texture_bits, vq_rem_texture_bits);
435*495ae853SAndroid Build Coastguard Worker 
436*495ae853SAndroid Build Coastguard Worker     /* The bits are then allocated based on the relative complexity of the
437*495ae853SAndroid Build Coastguard Worker      current frame with respect to that of the rest of the frames in period */
438*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
439*495ae853SAndroid Build Coastguard Worker     {
440*495ae853SAndroid Build Coastguard Worker         number_t vq_lin_mod_coeff, vq_est_sad, vq_K;
441*495ae853SAndroid Build Coastguard Worker 
442*495ae853SAndroid Build Coastguard Worker         /* Getting the linear model coefficient */
443*495ae853SAndroid Build Coastguard Worker         vq_lin_mod_coeff = irc_get_linear_coefficient(pps_rd_model[i]);
444*495ae853SAndroid Build Coastguard Worker 
445*495ae853SAndroid Build Coastguard Worker         /* Getting the estimated SAD */
446*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_est_sad, irc_get_est_sad(ps_est_sad,i), 0);
447*495ae853SAndroid Build Coastguard Worker 
448*495ae853SAndroid Build Coastguard Worker         /* Making K factor a var Q format */
449*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_K, ps_bit_allocation->i2_K[i], K_Q);
450*495ae853SAndroid Build Coastguard Worker 
451*495ae853SAndroid Build Coastguard Worker         /* Complexity_estimate = [ (lin_mod_coeff * estimated_sad) / K factor ]  */
452*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_lin_mod_coeff, vq_est_sad, &vq_lin_mod_coeff);
453*495ae853SAndroid Build Coastguard Worker         div32_var_q(vq_lin_mod_coeff, vq_K, &vq_complexity_estimate[i]);
454*495ae853SAndroid Build Coastguard Worker     }
455*495ae853SAndroid Build Coastguard Worker 
456*495ae853SAndroid Build Coastguard Worker     /*
457*495ae853SAndroid Build Coastguard Worker      * For simple cases, one of the complexities go to zero and in those cases
458*495ae853SAndroid Build Coastguard Worker      * distribute the bits evenly among frames based on I_TO_P_RATIO
459*495ae853SAndroid Build Coastguard Worker      */
460*495ae853SAndroid Build Coastguard Worker 
461*495ae853SAndroid Build Coastguard Worker     /* Also check the B-pictures complexity only in case they are present*/
462*495ae853SAndroid Build Coastguard Worker     if(i4_frms_in_period[B_PIC] == 0)
463*495ae853SAndroid Build Coastguard Worker     {
464*495ae853SAndroid Build Coastguard Worker         complexity_est = (vq_complexity_estimate[I_PIC]
465*495ae853SAndroid Build Coastguard Worker                         && vq_complexity_estimate[P_PIC]);
466*495ae853SAndroid Build Coastguard Worker     }
467*495ae853SAndroid Build Coastguard Worker     else
468*495ae853SAndroid Build Coastguard Worker     {
469*495ae853SAndroid Build Coastguard Worker         complexity_est = (vq_complexity_estimate[I_PIC]
470*495ae853SAndroid Build Coastguard Worker                         && vq_complexity_estimate[P_PIC]
471*495ae853SAndroid Build Coastguard Worker                         && vq_complexity_estimate[B_PIC]);
472*495ae853SAndroid Build Coastguard Worker     }
473*495ae853SAndroid Build Coastguard Worker 
474*495ae853SAndroid Build Coastguard Worker     if(complexity_est)
475*495ae853SAndroid Build Coastguard Worker     {
476*495ae853SAndroid Build Coastguard Worker         /*
477*495ae853SAndroid Build Coastguard Worker          * Estimated texture bits =
478*495ae853SAndroid Build Coastguard Worker          * (remaining bits) * (cur frm complexity)
479*495ae853SAndroid Build Coastguard Worker          * ---------------------------------------
480*495ae853SAndroid Build Coastguard Worker          * (num_i_frm*i_frm_complexity) + (num_p_frm*pfrm_complexity)
481*495ae853SAndroid Build Coastguard Worker          *  + (b_frm * b_frm_cm)
482*495ae853SAndroid Build Coastguard Worker          */
483*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_rem_texture_bits, vq_complexity_estimate[e_pic_type],
484*495ae853SAndroid Build Coastguard Worker                      &vq_rem_texture_bits);
485*495ae853SAndroid Build Coastguard Worker 
486*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < MAX_PIC_TYPE; i++)
487*495ae853SAndroid Build Coastguard Worker         {
488*495ae853SAndroid Build Coastguard Worker             mult32_var_q(vq_rem_frms_in_period[i], vq_complexity_estimate[i],
489*495ae853SAndroid Build Coastguard Worker                          &vq_rem_frms_in_period[i]);
490*495ae853SAndroid Build Coastguard Worker         }
491*495ae853SAndroid Build Coastguard Worker 
492*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_rem_frms_in_period[I_PIC], vq_rem_frms_in_period[P_PIC],
493*495ae853SAndroid Build Coastguard Worker                     &vq_rem_frms_in_period[I_PIC]);
494*495ae853SAndroid Build Coastguard Worker 
495*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_rem_frms_in_period[I_PIC], vq_rem_frms_in_period[B_PIC],
496*495ae853SAndroid Build Coastguard Worker                     &vq_rem_frms_in_period[I_PIC]);
497*495ae853SAndroid Build Coastguard Worker 
498*495ae853SAndroid Build Coastguard Worker         div32_var_q(vq_rem_texture_bits, vq_rem_frms_in_period[I_PIC],
499*495ae853SAndroid Build Coastguard Worker                     &vq_est_texture_bits_for_frm);
500*495ae853SAndroid Build Coastguard Worker 
501*495ae853SAndroid Build Coastguard Worker         number_t_to_word32(vq_est_texture_bits_for_frm,
502*495ae853SAndroid Build Coastguard Worker                            &i4_est_texture_bits_for_frm);
503*495ae853SAndroid Build Coastguard Worker     }
504*495ae853SAndroid Build Coastguard Worker     else
505*495ae853SAndroid Build Coastguard Worker     {
506*495ae853SAndroid Build Coastguard Worker         number_t vq_i_to_p_bit_ratio, vq_rem_frms;
507*495ae853SAndroid Build Coastguard Worker 
508*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_i_to_p_bit_ratio, I_TO_P_BIT_RATIO, 0);
509*495ae853SAndroid Build Coastguard Worker 
510*495ae853SAndroid Build Coastguard Worker         /* rem_frms = ((I_TO_P_BIT_RATIO * rem_frms_in_period[I_PIC]) +
511*495ae853SAndroid Build Coastguard Worker          * rem_frms_in_period[P_PIC]  +  rem_frms_in_period[B_PIC]);
512*495ae853SAndroid Build Coastguard Worker          */
513*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_rem_frms_in_period[I_PIC], vq_i_to_p_bit_ratio,
514*495ae853SAndroid Build Coastguard Worker                      &vq_rem_frms);
515*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_rem_frms_in_period[P_PIC], vq_rem_frms, &vq_rem_frms);
516*495ae853SAndroid Build Coastguard Worker         add32_var_q(vq_rem_frms_in_period[B_PIC], vq_rem_frms, &vq_rem_frms);
517*495ae853SAndroid Build Coastguard Worker 
518*495ae853SAndroid Build Coastguard Worker         /* est_texture_bits_for_frm = rem_texture_bits / rem_frms */
519*495ae853SAndroid Build Coastguard Worker         div32_var_q(vq_rem_texture_bits, vq_rem_frms,
520*495ae853SAndroid Build Coastguard Worker                     &vq_est_texture_bits_for_frm);
521*495ae853SAndroid Build Coastguard Worker         number_t_to_word32(vq_est_texture_bits_for_frm,
522*495ae853SAndroid Build Coastguard Worker                            &i4_est_texture_bits_for_frm);
523*495ae853SAndroid Build Coastguard Worker 
524*495ae853SAndroid Build Coastguard Worker         i4_est_texture_bits_for_frm =
525*495ae853SAndroid Build Coastguard Worker                         (I_PIC == e_pic_type) ?
526*495ae853SAndroid Build Coastguard Worker                                         (i4_est_texture_bits_for_frm
527*495ae853SAndroid Build Coastguard Worker                                                         * I_TO_P_BIT_RATIO) :
528*495ae853SAndroid Build Coastguard Worker                                         i4_est_texture_bits_for_frm;
529*495ae853SAndroid Build Coastguard Worker     }
530*495ae853SAndroid Build Coastguard Worker 
531*495ae853SAndroid Build Coastguard Worker     /*
532*495ae853SAndroid Build Coastguard Worker      * If the remaining bits in the period becomes negative then the estimated
533*495ae853SAndroid Build Coastguard Worker      * texture bits would also become negative. This would send a feedback to
534*495ae853SAndroid Build Coastguard Worker      * the model which may go for a toss. Thus sending the minimum possible
535*495ae853SAndroid Build Coastguard Worker      * value = 0
536*495ae853SAndroid Build Coastguard Worker      */
537*495ae853SAndroid Build Coastguard Worker     if(i4_est_texture_bits_for_frm < 0)
538*495ae853SAndroid Build Coastguard Worker     {
539*495ae853SAndroid Build Coastguard Worker         i4_est_texture_bits_for_frm = 0;
540*495ae853SAndroid Build Coastguard Worker     }
541*495ae853SAndroid Build Coastguard Worker 
542*495ae853SAndroid Build Coastguard Worker     return (i4_est_texture_bits_for_frm);
543*495ae853SAndroid Build Coastguard Worker }
544*495ae853SAndroid Build Coastguard Worker 
545*495ae853SAndroid Build Coastguard Worker /******************************************************************************
546*495ae853SAndroid Build Coastguard Worker  Function Name : irc_ba_get_cur_frm_est_header_bits
547*495ae853SAndroid Build Coastguard Worker  Description   : Based on remaining bits in period and rd_model
548*495ae853SAndroid Build Coastguard Worker                  the number of bits required for the current frame is estimated.
549*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_ba_get_cur_frm_est_header_bits(bit_allocation_t * ps_bit_allocation,picture_type_e e_pic_type)550*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_get_cur_frm_est_header_bits(bit_allocation_t *ps_bit_allocation,
551*495ae853SAndroid Build Coastguard Worker                                           picture_type_e e_pic_type)
552*495ae853SAndroid Build Coastguard Worker {
553*495ae853SAndroid Build Coastguard Worker     return (ps_bit_allocation->i4_prev_frm_header_bits[e_pic_type]);
554*495ae853SAndroid Build Coastguard Worker }
555*495ae853SAndroid Build Coastguard Worker 
irc_ba_get_rem_bits_in_period(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling)556*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_get_rem_bits_in_period(bit_allocation_t *ps_bit_allocation,
557*495ae853SAndroid Build Coastguard Worker                                      pic_handling_handle ps_pic_handling)
558*495ae853SAndroid Build Coastguard Worker {
559*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rem_bits_in_gop = 0;
560*495ae853SAndroid Build Coastguard Worker 
561*495ae853SAndroid Build Coastguard Worker     number_t vq_num_bits;
562*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_num_bits, 0, 0);
563*495ae853SAndroid Build Coastguard Worker 
564*495ae853SAndroid Build Coastguard Worker     irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits);
565*495ae853SAndroid Build Coastguard Worker     number_t_to_word32(ps_bit_allocation->s_rbip.vq_rem_bits_in_period,
566*495ae853SAndroid Build Coastguard Worker                        &i4_rem_bits_in_gop);
567*495ae853SAndroid Build Coastguard Worker     return (i4_rem_bits_in_gop);
568*495ae853SAndroid Build Coastguard Worker }
569*495ae853SAndroid Build Coastguard Worker 
570*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
571*495ae853SAndroid Build Coastguard Worker  Function Name : irc_ba_update_cur_frm_consumed_bits
572*495ae853SAndroid Build Coastguard Worker  Description   : Based on remaining bits in period and rd_model
573*495ae853SAndroid Build Coastguard Worker                  the number of bits required for the current frame is estimated.
574*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_ba_update_cur_frm_consumed_bits(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling,WORD32 i4_total_frame_bits,WORD32 i4_model_updation_hdr_bits,picture_type_e e_pic_type,UWORD8 u1_is_scd,WORD32 i4_last_frm_in_gop)575*495ae853SAndroid Build Coastguard Worker void irc_ba_update_cur_frm_consumed_bits(bit_allocation_t *ps_bit_allocation,
576*495ae853SAndroid Build Coastguard Worker                                          pic_handling_handle ps_pic_handling,
577*495ae853SAndroid Build Coastguard Worker                                          WORD32 i4_total_frame_bits,
578*495ae853SAndroid Build Coastguard Worker                                          WORD32 i4_model_updation_hdr_bits,
579*495ae853SAndroid Build Coastguard Worker                                          picture_type_e e_pic_type,
580*495ae853SAndroid Build Coastguard Worker                                          UWORD8 u1_is_scd,
581*495ae853SAndroid Build Coastguard Worker                                          WORD32 i4_last_frm_in_gop)
582*495ae853SAndroid Build Coastguard Worker {
583*495ae853SAndroid Build Coastguard Worker     WORD32 i4_error_bits = irc_get_error_bits(ps_bit_allocation->ps_error_bits);
584*495ae853SAndroid Build Coastguard Worker 
585*495ae853SAndroid Build Coastguard Worker     /* Update the remaining bits in period */
586*495ae853SAndroid Build Coastguard Worker     number_t vq_num_bits;
587*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_num_bits, (-i4_total_frame_bits + i4_error_bits), 0);
588*495ae853SAndroid Build Coastguard Worker 
589*495ae853SAndroid Build Coastguard Worker     irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits);
590*495ae853SAndroid Build Coastguard Worker 
591*495ae853SAndroid Build Coastguard Worker     /*
592*495ae853SAndroid Build Coastguard Worker      * Update the header bits so that it can be used as an estimate to the next
593*495ae853SAndroid Build Coastguard Worker      * frame
594*495ae853SAndroid Build Coastguard Worker      */
595*495ae853SAndroid Build Coastguard Worker     if(u1_is_scd)
596*495ae853SAndroid Build Coastguard Worker     {
597*495ae853SAndroid Build Coastguard Worker         /*
598*495ae853SAndroid Build Coastguard Worker          * In case of SCD, even though the frame type is P, it is equivalent to
599*495ae853SAndroid Build Coastguard Worker          * a I frame and so the corresponding header bits is updated
600*495ae853SAndroid Build Coastguard Worker          */
601*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->i4_prev_frm_header_bits[I_PIC] =
602*495ae853SAndroid Build Coastguard Worker                         i4_model_updation_hdr_bits;
603*495ae853SAndroid Build Coastguard Worker 
604*495ae853SAndroid Build Coastguard Worker #define MAX_NUM_GOPS_IN_PERIOD (3)
605*495ae853SAndroid Build Coastguard Worker         if(ps_bit_allocation->i4_num_gops_in_period < MAX_NUM_GOPS_IN_PERIOD)
606*495ae853SAndroid Build Coastguard Worker         {
607*495ae853SAndroid Build Coastguard Worker             /*
608*495ae853SAndroid Build Coastguard Worker              * Whenever there is a scene change increase the number of gops by
609*495ae853SAndroid Build Coastguard Worker              * 2 so that the number of bits allocated is not very constrained
610*495ae853SAndroid Build Coastguard Worker              */
611*495ae853SAndroid Build Coastguard Worker             ps_bit_allocation->i4_num_gops_in_period += 2;
612*495ae853SAndroid Build Coastguard Worker             /* Add the extra bits in GOP to remaining bits in period */
613*495ae853SAndroid Build Coastguard Worker             irc_ba_change_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling,
614*495ae853SAndroid Build Coastguard Worker                                ps_bit_allocation->i4_bits_per_frm,
615*495ae853SAndroid Build Coastguard Worker                                ps_bit_allocation->i4_num_gops_in_period);
616*495ae853SAndroid Build Coastguard Worker         }
617*495ae853SAndroid Build Coastguard Worker     }
618*495ae853SAndroid Build Coastguard Worker     else
619*495ae853SAndroid Build Coastguard Worker     {
620*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->i4_prev_frm_header_bits[e_pic_type] =
621*495ae853SAndroid Build Coastguard Worker                         i4_model_updation_hdr_bits;
622*495ae853SAndroid Build Coastguard Worker     }
623*495ae853SAndroid Build Coastguard Worker 
624*495ae853SAndroid Build Coastguard Worker     if(i4_last_frm_in_gop)
625*495ae853SAndroid Build Coastguard Worker     {
626*495ae853SAndroid Build Coastguard Worker         WORD32 i4_tot_frms_in_gop = get_number_of_frms_in_a_gop(
627*495ae853SAndroid Build Coastguard Worker                 ps_pic_handling);
628*495ae853SAndroid Build Coastguard Worker         number_t vq_total_frms_in_gop, vq_bits_per_frm, vq_num_bits_in_gop;
629*495ae853SAndroid Build Coastguard Worker 
630*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_total_frms_in_gop, i4_tot_frms_in_gop, 0);
631*495ae853SAndroid Build Coastguard Worker         SET_VAR_Q(vq_bits_per_frm, ps_bit_allocation->i4_bits_per_frm, 0);
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker         mult32_var_q(vq_bits_per_frm, vq_total_frms_in_gop,
634*495ae853SAndroid Build Coastguard Worker                      &vq_num_bits_in_gop);
635*495ae853SAndroid Build Coastguard Worker         /*
636*495ae853SAndroid Build Coastguard Worker          * If the number of gops in period has been increased due to scene
637*495ae853SAndroid Build Coastguard Worker          * change, slowly bring in down across the gops
638*495ae853SAndroid Build Coastguard Worker          */
639*495ae853SAndroid Build Coastguard Worker         if(ps_bit_allocation->i4_num_gops_in_period
640*495ae853SAndroid Build Coastguard Worker                         > ps_bit_allocation->i4_actual_num_gops_in_period)
641*495ae853SAndroid Build Coastguard Worker         {
642*495ae853SAndroid Build Coastguard Worker             ps_bit_allocation->i4_num_gops_in_period--;
643*495ae853SAndroid Build Coastguard Worker             irc_ba_change_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling,
644*495ae853SAndroid Build Coastguard Worker                                ps_bit_allocation->i4_bits_per_frm,
645*495ae853SAndroid Build Coastguard Worker                                ps_bit_allocation->i4_num_gops_in_period);
646*495ae853SAndroid Build Coastguard Worker         }
647*495ae853SAndroid Build Coastguard Worker         /*
648*495ae853SAndroid Build Coastguard Worker          * If rem_bits_in_period < 0 decrease the number of bits allocated for
649*495ae853SAndroid Build Coastguard Worker          * the next period else increase it
650*495ae853SAndroid Build Coastguard Worker          */
651*495ae853SAndroid Build Coastguard Worker         irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling,
652*495ae853SAndroid Build Coastguard Worker                            vq_num_bits_in_gop);
653*495ae853SAndroid Build Coastguard Worker     }
654*495ae853SAndroid Build Coastguard Worker     /* Update the lower modules */
655*495ae853SAndroid Build Coastguard Worker     irc_update_error_bits(ps_bit_allocation->ps_error_bits);
656*495ae853SAndroid Build Coastguard Worker }
657*495ae853SAndroid Build Coastguard Worker 
irc_ba_change_remaining_bits_in_period(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling,WORD32 i4_bit_rate,WORD32 i4_frame_rate,WORD32 * i4_peak_bit_rate)658*495ae853SAndroid Build Coastguard Worker void irc_ba_change_remaining_bits_in_period(bit_allocation_t *ps_bit_allocation,
659*495ae853SAndroid Build Coastguard Worker                                             pic_handling_handle ps_pic_handling,
660*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_bit_rate,
661*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_frame_rate,
662*495ae853SAndroid Build Coastguard Worker                                             WORD32 *i4_peak_bit_rate)
663*495ae853SAndroid Build Coastguard Worker {
664*495ae853SAndroid Build Coastguard Worker     WORD32 i4_new_avg_bits_per_frm;
665*495ae853SAndroid Build Coastguard Worker     WORD32 i4_new_peak_bits_per_frm[MAX_NUM_DRAIN_RATES];
666*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rem_frms_in_period[MAX_PIC_TYPE];
667*495ae853SAndroid Build Coastguard Worker     int i;
668*495ae853SAndroid Build Coastguard Worker 
669*495ae853SAndroid Build Coastguard Worker     /* Calculate the new per frame bits */
670*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(i4_bit_rate, 1000, i4_frame_rate, i4_new_avg_bits_per_frm);
671*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
672*495ae853SAndroid Build Coastguard Worker     {
673*495ae853SAndroid Build Coastguard Worker         X_PROD_Y_DIV_Z(i4_peak_bit_rate[i], 1000, i4_frame_rate,
674*495ae853SAndroid Build Coastguard Worker                        i4_new_peak_bits_per_frm[i]);
675*495ae853SAndroid Build Coastguard Worker     }
676*495ae853SAndroid Build Coastguard Worker 
677*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
678*495ae853SAndroid Build Coastguard Worker     {
679*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->i4_max_bits_per_frm[i] = i4_new_peak_bits_per_frm[i];
680*495ae853SAndroid Build Coastguard Worker     }
681*495ae853SAndroid Build Coastguard Worker 
682*495ae853SAndroid Build Coastguard Worker     /*
683*495ae853SAndroid Build Coastguard Worker      * Get the rem_frms_in_prd & the frms_in_prd from the pic_type state
684*495ae853SAndroid Build Coastguard Worker      * struct
685*495ae853SAndroid Build Coastguard Worker      */
686*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_rem_frms_in_gop(ps_pic_handling, i4_rem_frms_in_period);
687*495ae853SAndroid Build Coastguard Worker 
688*495ae853SAndroid Build Coastguard Worker     /*
689*495ae853SAndroid Build Coastguard Worker      * If the difference > 0(/ <0), the remaining bits in period needs to be
690*495ae853SAndroid Build Coastguard Worker      * increased(/decreased) based on the remaining number of frames
691*495ae853SAndroid Build Coastguard Worker      */
692*495ae853SAndroid Build Coastguard Worker     irc_ba_change_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling,
693*495ae853SAndroid Build Coastguard Worker                        i4_new_avg_bits_per_frm,
694*495ae853SAndroid Build Coastguard Worker                        ps_bit_allocation->i4_num_gops_in_period);
695*495ae853SAndroid Build Coastguard Worker 
696*495ae853SAndroid Build Coastguard Worker     /* Update the new average bits per frame */
697*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_bits_per_frm = i4_new_avg_bits_per_frm;
698*495ae853SAndroid Build Coastguard Worker     /* change the lower modules state */
699*495ae853SAndroid Build Coastguard Worker     irc_change_bitrate_in_error_bits(ps_bit_allocation->ps_error_bits,
700*495ae853SAndroid Build Coastguard Worker                                      i4_bit_rate);
701*495ae853SAndroid Build Coastguard Worker     irc_change_frm_rate_in_error_bits(ps_bit_allocation->ps_error_bits,
702*495ae853SAndroid Build Coastguard Worker                                       i4_frame_rate);
703*495ae853SAndroid Build Coastguard Worker 
704*495ae853SAndroid Build Coastguard Worker     /* Store the modified frame_rate */
705*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_frame_rate = i4_frame_rate;
706*495ae853SAndroid Build Coastguard Worker     ps_bit_allocation->i4_bit_rate = i4_bit_rate;
707*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
708*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->ai4_peak_bit_rate[i] = i4_peak_bit_rate[i];
709*495ae853SAndroid Build Coastguard Worker }
710*495ae853SAndroid Build Coastguard Worker 
irc_ba_change_ba_peak_bit_rate(bit_allocation_t * ps_bit_allocation,WORD32 * ai4_peak_bit_rate)711*495ae853SAndroid Build Coastguard Worker void irc_ba_change_ba_peak_bit_rate(bit_allocation_t *ps_bit_allocation,
712*495ae853SAndroid Build Coastguard Worker                                     WORD32 *ai4_peak_bit_rate)
713*495ae853SAndroid Build Coastguard Worker {
714*495ae853SAndroid Build Coastguard Worker     WORD32 i;
715*495ae853SAndroid Build Coastguard Worker 
716*495ae853SAndroid Build Coastguard Worker     /* Calculate the bits per frame */
717*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
718*495ae853SAndroid Build Coastguard Worker     {
719*495ae853SAndroid Build Coastguard Worker         X_PROD_Y_DIV_Z(ai4_peak_bit_rate[i], 1000,
720*495ae853SAndroid Build Coastguard Worker                        ps_bit_allocation->i4_frame_rate,
721*495ae853SAndroid Build Coastguard Worker                        ps_bit_allocation->i4_max_bits_per_frm[i]);
722*495ae853SAndroid Build Coastguard Worker         ps_bit_allocation->ai4_peak_bit_rate[i] = ai4_peak_bit_rate[i];
723*495ae853SAndroid Build Coastguard Worker     }
724*495ae853SAndroid Build Coastguard Worker }
725*495ae853SAndroid Build Coastguard Worker 
726*495ae853SAndroid Build Coastguard Worker /******************************************************************************
727*495ae853SAndroid Build Coastguard Worker  * @brief Modifies the remaining bit in period for the gop which has fif.
728*495ae853SAndroid Build Coastguard Worker  *      since fif would cause a new gop to be created, we need to add the number
729*495ae853SAndroid Build Coastguard Worker  *      of encoded frames in the fif GOP worth of bits to remaining bits in
730*495ae853SAndroid Build Coastguard Worker  *      period
731*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_ba_change_rem_bits_in_prd_at_force_I_frame(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling)732*495ae853SAndroid Build Coastguard Worker void irc_ba_change_rem_bits_in_prd_at_force_I_frame(bit_allocation_t *ps_bit_allocation,
733*495ae853SAndroid Build Coastguard Worker                                                     pic_handling_handle ps_pic_handling)
734*495ae853SAndroid Build Coastguard Worker {
735*495ae853SAndroid Build Coastguard Worker     WORD32 i4_frms_in_period;
736*495ae853SAndroid Build Coastguard Worker     number_t vq_frms_in_period, vq_bits_per_frm, vq_num_bits_in_period;
737*495ae853SAndroid Build Coastguard Worker 
738*495ae853SAndroid Build Coastguard Worker     i4_frms_in_period = irc_pic_type_get_frms_in_gop_force_I_frm(
739*495ae853SAndroid Build Coastguard Worker                     ps_pic_handling);
740*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_frms_in_period, i4_frms_in_period, 0);
741*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_bits_per_frm, ps_bit_allocation->i4_bits_per_frm, 0);
742*495ae853SAndroid Build Coastguard Worker 
743*495ae853SAndroid Build Coastguard Worker     mult32_var_q(vq_bits_per_frm, vq_frms_in_period, &vq_num_bits_in_period);
744*495ae853SAndroid Build Coastguard Worker 
745*495ae853SAndroid Build Coastguard Worker     irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits_in_period);
746*495ae853SAndroid Build Coastguard Worker }
747*495ae853SAndroid Build Coastguard Worker 
irc_ba_check_and_update_bit_allocation(bit_allocation_t * ps_bit_allocation,pic_handling_handle ps_pic_handling,WORD32 i4_cur_buf_size,WORD32 i4_max_buf_size,WORD32 i4_max_bits_inflow_per_frm,WORD32 i4_tot_frame_bits)748*495ae853SAndroid Build Coastguard Worker void irc_ba_check_and_update_bit_allocation(bit_allocation_t *ps_bit_allocation,
749*495ae853SAndroid Build Coastguard Worker                                             pic_handling_handle ps_pic_handling,
750*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_cur_buf_size,
751*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_max_buf_size,
752*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_max_bits_inflow_per_frm,
753*495ae853SAndroid Build Coastguard Worker                                             WORD32 i4_tot_frame_bits)
754*495ae853SAndroid Build Coastguard Worker {
755*495ae853SAndroid Build Coastguard Worker 
756*495ae853SAndroid Build Coastguard Worker     number_t vq_max_drain_bits, vq_extra_bits, vq_less_bits,
757*495ae853SAndroid Build Coastguard Worker                     vq_allocated_saved_bits, vq_min_bits_for_period;
758*495ae853SAndroid Build Coastguard Worker     WORD32 i4_num_frms_in_period = get_number_of_frms_in_a_gop(ps_pic_handling);
759*495ae853SAndroid Build Coastguard Worker     number_t vq_rem_bits_in_period, vq_num_frms_in_period, vq_zero;
760*495ae853SAndroid Build Coastguard Worker     WORD32 b_rem_bits_gt_max_drain, b_rem_bits_lt_min_bits,
761*495ae853SAndroid Build Coastguard Worker                     b_saved_bits_gt_zero;
762*495ae853SAndroid Build Coastguard Worker     rem_bit_in_prd_t *ps_rbip = &ps_bit_allocation->s_rbip;
763*495ae853SAndroid Build Coastguard Worker 
764*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_cur_buf_size);
765*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_max_buf_size);
766*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_tot_frame_bits);
767*495ae853SAndroid Build Coastguard Worker 
768*495ae853SAndroid Build Coastguard Worker     /*
769*495ae853SAndroid Build Coastguard Worker      * If the remaining bits is greater than what can be drained in that period
770*495ae853SAndroid Build Coastguard Worker      * Clip the remaining bits in period to the maximum it can drain in that
771*495ae853SAndroid Build Coastguard Worker      * period with the error of current buffer size.Accumulate the saved bits
772*495ae853SAndroid Build Coastguard Worker      * if any. else if the remaining bits is lesser than the minimum bit rate
773*495ae853SAndroid Build Coastguard Worker      * promised in that period Add the excess bits to remaining bits in period
774*495ae853SAndroid Build Coastguard Worker      * and reduce it from the saved bits Else Provide the extra bits from the
775*495ae853SAndroid Build Coastguard Worker      * "saved bits pool".
776*495ae853SAndroid Build Coastguard Worker      */
777*495ae853SAndroid Build Coastguard Worker     /*
778*495ae853SAndroid Build Coastguard Worker      * max_drain_bits = num_gops_in_period * num_frms_in_period *
779*495ae853SAndroid Build Coastguard Worker      * * max_bits_inflow_per_frm
780*495ae853SAndroid Build Coastguard Worker      */
781*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_num_frms_in_period,
782*495ae853SAndroid Build Coastguard Worker               (ps_bit_allocation->i4_num_gops_in_period * i4_num_frms_in_period),
783*495ae853SAndroid Build Coastguard Worker               0);
784*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_max_drain_bits, i4_max_bits_inflow_per_frm, 0);
785*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_zero, 0, 0);
786*495ae853SAndroid Build Coastguard Worker     mult32_var_q(vq_max_drain_bits, vq_num_frms_in_period, &vq_max_drain_bits);
787*495ae853SAndroid Build Coastguard Worker 
788*495ae853SAndroid Build Coastguard Worker     /*
789*495ae853SAndroid Build Coastguard Worker      * min_bits_for_period = num_gops_in_period * num_frms_in_period *
790*495ae853SAndroid Build Coastguard Worker      * min_bits_per_frm
791*495ae853SAndroid Build Coastguard Worker      */
792*495ae853SAndroid Build Coastguard Worker     SET_VAR_Q(vq_min_bits_for_period, ps_bit_allocation->i4_min_bits_per_frm,
793*495ae853SAndroid Build Coastguard Worker               0);
794*495ae853SAndroid Build Coastguard Worker     mult32_var_q(vq_min_bits_for_period, vq_num_frms_in_period,
795*495ae853SAndroid Build Coastguard Worker                  &vq_min_bits_for_period);
796*495ae853SAndroid Build Coastguard Worker 
797*495ae853SAndroid Build Coastguard Worker     vq_rem_bits_in_period = ps_rbip->vq_rem_bits_in_period;
798*495ae853SAndroid Build Coastguard Worker 
799*495ae853SAndroid Build Coastguard Worker     /* Evaluate rem_bits_in_period  > max_drain_bits      */
800*495ae853SAndroid Build Coastguard Worker     VQ_A_GT_VQ_B(ps_rbip->vq_rem_bits_in_period, vq_max_drain_bits,
801*495ae853SAndroid Build Coastguard Worker                  b_rem_bits_gt_max_drain);
802*495ae853SAndroid Build Coastguard Worker 
803*495ae853SAndroid Build Coastguard Worker     /* Evaluate rem_bits_in_period  < min_bits_for_period */
804*495ae853SAndroid Build Coastguard Worker     VQ_A_LT_VQ_B(ps_rbip->vq_rem_bits_in_period, vq_min_bits_for_period,
805*495ae853SAndroid Build Coastguard Worker                  b_rem_bits_lt_min_bits);
806*495ae853SAndroid Build Coastguard Worker 
807*495ae853SAndroid Build Coastguard Worker     /* Evaluate saved_bits  > 0 */
808*495ae853SAndroid Build Coastguard Worker     VQ_A_LT_VQ_B(ps_bit_allocation->vq_saved_bits, vq_zero,
809*495ae853SAndroid Build Coastguard Worker                  b_saved_bits_gt_zero);
810*495ae853SAndroid Build Coastguard Worker 
811*495ae853SAndroid Build Coastguard Worker     /* (i4_rem_bits_in_period > i4_max_drain_bits) */
812*495ae853SAndroid Build Coastguard Worker     if(b_rem_bits_gt_max_drain)
813*495ae853SAndroid Build Coastguard Worker     {
814*495ae853SAndroid Build Coastguard Worker         /* extra_bits = rem_bits_in_period - max_drain_bits */
815*495ae853SAndroid Build Coastguard Worker         sub32_var_q(ps_rbip->vq_rem_bits_in_period, vq_max_drain_bits,
816*495ae853SAndroid Build Coastguard Worker                     &vq_extra_bits);
817*495ae853SAndroid Build Coastguard Worker 
818*495ae853SAndroid Build Coastguard Worker         /* saved_bits += extra_bits */
819*495ae853SAndroid Build Coastguard Worker         add32_var_q(ps_bit_allocation->vq_saved_bits, vq_extra_bits,
820*495ae853SAndroid Build Coastguard Worker                     &ps_bit_allocation->vq_saved_bits);
821*495ae853SAndroid Build Coastguard Worker 
822*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period = vq_max_drain_bits */
823*495ae853SAndroid Build Coastguard Worker         ps_rbip->vq_rem_bits_in_period = vq_max_drain_bits;
824*495ae853SAndroid Build Coastguard Worker     }
825*495ae853SAndroid Build Coastguard Worker     else if(b_rem_bits_lt_min_bits)
826*495ae853SAndroid Build Coastguard Worker     {
827*495ae853SAndroid Build Coastguard Worker         /* extra_bits(-ve) =  rem_bits_in_period - i4_min_bits_for_period */
828*495ae853SAndroid Build Coastguard Worker         sub32_var_q(ps_rbip->vq_rem_bits_in_period, vq_min_bits_for_period,
829*495ae853SAndroid Build Coastguard Worker                     &vq_extra_bits);
830*495ae853SAndroid Build Coastguard Worker 
831*495ae853SAndroid Build Coastguard Worker         /* saved_bits += extra_bits(-ve) */
832*495ae853SAndroid Build Coastguard Worker         add32_var_q(ps_bit_allocation->vq_saved_bits, vq_extra_bits,
833*495ae853SAndroid Build Coastguard Worker                     &ps_bit_allocation->vq_saved_bits);
834*495ae853SAndroid Build Coastguard Worker 
835*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period = min_bits_for_period */
836*495ae853SAndroid Build Coastguard Worker         ps_rbip->vq_rem_bits_in_period = vq_min_bits_for_period;
837*495ae853SAndroid Build Coastguard Worker     }
838*495ae853SAndroid Build Coastguard Worker     else if(b_saved_bits_gt_zero)
839*495ae853SAndroid Build Coastguard Worker     {
840*495ae853SAndroid Build Coastguard Worker         /* less_bits = max_drain_bits - _rem_bits_in_period */
841*495ae853SAndroid Build Coastguard Worker         sub32_var_q(vq_max_drain_bits, vq_rem_bits_in_period, &vq_less_bits);
842*495ae853SAndroid Build Coastguard Worker 
843*495ae853SAndroid Build Coastguard Worker         /* allocated_saved_bits = MIN (less_bits, saved_bits) */
844*495ae853SAndroid Build Coastguard Worker         MIN_VARQ(ps_bit_allocation->vq_saved_bits, vq_less_bits,
845*495ae853SAndroid Build Coastguard Worker                  vq_allocated_saved_bits);
846*495ae853SAndroid Build Coastguard Worker 
847*495ae853SAndroid Build Coastguard Worker         /* rem_bits_in_period += allocted_save_bits */
848*495ae853SAndroid Build Coastguard Worker         add32_var_q(ps_rbip->vq_rem_bits_in_period, vq_allocated_saved_bits,
849*495ae853SAndroid Build Coastguard Worker                     &ps_rbip->vq_rem_bits_in_period);
850*495ae853SAndroid Build Coastguard Worker 
851*495ae853SAndroid Build Coastguard Worker         /* saved_bits -= allocted_save_bits */
852*495ae853SAndroid Build Coastguard Worker         sub32_var_q(ps_bit_allocation->vq_saved_bits, vq_allocated_saved_bits,
853*495ae853SAndroid Build Coastguard Worker                     &ps_bit_allocation->vq_saved_bits);
854*495ae853SAndroid Build Coastguard Worker     }
855*495ae853SAndroid Build Coastguard Worker     return;
856*495ae853SAndroid Build Coastguard Worker }
857*495ae853SAndroid Build Coastguard Worker 
irc_ba_get_frame_rate(bit_allocation_t * ps_bit_allocation)858*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_get_frame_rate(bit_allocation_t *ps_bit_allocation)
859*495ae853SAndroid Build Coastguard Worker {
860*495ae853SAndroid Build Coastguard Worker     return (ps_bit_allocation->i4_frame_rate);
861*495ae853SAndroid Build Coastguard Worker }
862*495ae853SAndroid Build Coastguard Worker 
irc_ba_get_bit_rate(bit_allocation_t * ps_bit_allocation)863*495ae853SAndroid Build Coastguard Worker WORD32 irc_ba_get_bit_rate(bit_allocation_t *ps_bit_allocation)
864*495ae853SAndroid Build Coastguard Worker {
865*495ae853SAndroid Build Coastguard Worker     return (ps_bit_allocation->i4_bit_rate);
866*495ae853SAndroid Build Coastguard Worker }
867*495ae853SAndroid Build Coastguard Worker 
irc_ba_get_peak_bit_rate(bit_allocation_t * ps_bit_allocation,WORD32 * pi4_peak_bit_rate)868*495ae853SAndroid Build Coastguard Worker void irc_ba_get_peak_bit_rate(bit_allocation_t *ps_bit_allocation,
869*495ae853SAndroid Build Coastguard Worker                               WORD32 *pi4_peak_bit_rate)
870*495ae853SAndroid Build Coastguard Worker {
871*495ae853SAndroid Build Coastguard Worker     WORD32 i;
872*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
873*495ae853SAndroid Build Coastguard Worker     {
874*495ae853SAndroid Build Coastguard Worker         pi4_peak_bit_rate[i] = ps_bit_allocation->ai4_peak_bit_rate[i];
875*495ae853SAndroid Build Coastguard Worker     }
876*495ae853SAndroid Build Coastguard Worker }
877