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