xref: /aosp_15_r20/external/libavc/encoder/irc_rate_control_api.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 /*****************************************************************************/
22*495ae853SAndroid Build Coastguard Worker /* Includes */
23*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
24*495ae853SAndroid Build Coastguard Worker 
25*495ae853SAndroid Build Coastguard Worker /* System include files */
26*495ae853SAndroid Build Coastguard Worker #include "stdio.h"
27*495ae853SAndroid Build Coastguard Worker 
28*495ae853SAndroid Build Coastguard Worker /* User include files */
29*495ae853SAndroid Build Coastguard Worker #include "irc_datatypes.h"
30*495ae853SAndroid Build Coastguard Worker #include "irc_common.h"
31*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
32*495ae853SAndroid Build Coastguard Worker #include "irc_mem_req_and_acq.h"
33*495ae853SAndroid Build Coastguard Worker #include "irc_rd_model.h"
34*495ae853SAndroid Build Coastguard Worker #include "irc_est_sad.h"
35*495ae853SAndroid Build Coastguard Worker #include "irc_fixed_point_error_bits.h"
36*495ae853SAndroid Build Coastguard Worker #include "irc_vbr_storage_vbv.h"
37*495ae853SAndroid Build Coastguard Worker #include "irc_picture_type.h"
38*495ae853SAndroid Build Coastguard Worker #include "irc_bit_allocation.h"
39*495ae853SAndroid Build Coastguard Worker #include "irc_mb_model_based.h"
40*495ae853SAndroid Build Coastguard Worker #include "irc_cbr_buffer_control.h"
41*495ae853SAndroid Build Coastguard Worker #include "irc_vbr_str_prms.h"
42*495ae853SAndroid Build Coastguard Worker #include "irc_rate_control_api.h"
43*495ae853SAndroid Build Coastguard Worker #include "irc_rate_control_api_structs.h"
44*495ae853SAndroid Build Coastguard Worker #include "irc_trace_support.h"
45*495ae853SAndroid Build Coastguard Worker 
46*495ae853SAndroid Build Coastguard Worker 
47*495ae853SAndroid Build Coastguard Worker #define MIN(a,b)   (((a) < (b)) ? (a) : (b))
48*495ae853SAndroid Build Coastguard Worker #define MAX(a,b)   (((a) > (b)) ? (a) : (b))
49*495ae853SAndroid Build Coastguard Worker 
50*495ae853SAndroid Build Coastguard Worker #define DEV_Q   4       /*Q format(Shift) for Deviation range factor */
51*495ae853SAndroid Build Coastguard Worker #define HI_DEV_FCTR     22  /* 1.4*16 */
52*495ae853SAndroid Build Coastguard Worker #define LO_DEV_FCTR     12  /* 0.75*16 */
53*495ae853SAndroid Build Coastguard Worker #define GET_HI_DEV_QP(Qprev) (( ((WORD32) Qprev)*HI_DEV_FCTR + (1<<(DEV_Q-1)))>>DEV_Q)
54*495ae853SAndroid Build Coastguard Worker #define GET_LO_DEV_QP(Qprev) (( ((WORD32) Qprev)*LO_DEV_FCTR + (1<<(DEV_Q-1)))>>DEV_Q)
55*495ae853SAndroid Build Coastguard Worker #define CLIP_QP(Qc, hi_d, lo_d) (((Qc) < (lo_d))?((lo_d)):(((Qc) > (hi_d))?(hi_d):(Qc)))
56*495ae853SAndroid Build Coastguard Worker 
57*495ae853SAndroid Build Coastguard Worker /*****************************************************************************
58*495ae853SAndroid Build Coastguard Worker  Function Name : fill_memtab
59*495ae853SAndroid Build Coastguard Worker  Description   : fill memtab
60*495ae853SAndroid Build Coastguard Worker  Inputs        :
61*495ae853SAndroid Build Coastguard Worker  ps_mem_tab           -  Memtab pointer
62*495ae853SAndroid Build Coastguard Worker  u4_size              -  Size of the memtab
63*495ae853SAndroid Build Coastguard Worker  i4_alignment         -  alignment of the memtab
64*495ae853SAndroid Build Coastguard Worker  e_usage              -  usage
65*495ae853SAndroid Build Coastguard Worker  e_mem_region         -  region
66*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
fill_memtab(itt_memtab_t * ps_mem_tab,WORD32 u4_size,WORD32 i4_alignment,ITT_MEM_USAGE_TYPE_E e_usage,ITT_MEM_REGION_E e_mem_region)67*495ae853SAndroid Build Coastguard Worker void fill_memtab(itt_memtab_t *ps_mem_tab,
68*495ae853SAndroid Build Coastguard Worker                  WORD32 u4_size,
69*495ae853SAndroid Build Coastguard Worker                  WORD32 i4_alignment,
70*495ae853SAndroid Build Coastguard Worker                  ITT_MEM_USAGE_TYPE_E e_usage,
71*495ae853SAndroid Build Coastguard Worker                  ITT_MEM_REGION_E e_mem_region)
72*495ae853SAndroid Build Coastguard Worker {
73*495ae853SAndroid Build Coastguard Worker     /* Make the size next multiple of alignment */
74*495ae853SAndroid Build Coastguard Worker     WORD32 i4_aligned_size   = (((u4_size) + (i4_alignment-1)) & (~(i4_alignment-1)));
75*495ae853SAndroid Build Coastguard Worker 
76*495ae853SAndroid Build Coastguard Worker     /* Fill the memtab */
77*495ae853SAndroid Build Coastguard Worker     ps_mem_tab->u4_size      = i4_aligned_size;
78*495ae853SAndroid Build Coastguard Worker     ps_mem_tab->i4_alignment = i4_alignment;
79*495ae853SAndroid Build Coastguard Worker     ps_mem_tab->e_usage      = e_usage;
80*495ae853SAndroid Build Coastguard Worker     ps_mem_tab->e_mem_region = e_mem_region;
81*495ae853SAndroid Build Coastguard Worker }
82*495ae853SAndroid Build Coastguard Worker 
83*495ae853SAndroid Build Coastguard Worker /*****************************************************************************
84*495ae853SAndroid Build Coastguard Worker  Function Name : use_or_fill_base
85*495ae853SAndroid Build Coastguard Worker  Description   : Get or Set base pointer for the memtab
86*495ae853SAndroid Build Coastguard Worker  Inputs        :
87*495ae853SAndroid Build Coastguard Worker  ps_mem_tab           -  Memtab pointer
88*495ae853SAndroid Build Coastguard Worker  ptr_to_be_filled     -  Pointer to base pointer
89*495ae853SAndroid Build Coastguard Worker  e_func_type          -  Get/Set flag
90*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
use_or_fill_base(itt_memtab_t * ps_mem_tab,void ** ptr_to_be_filled,ITT_FUNC_TYPE_E e_func_type)91*495ae853SAndroid Build Coastguard Worker WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab,
92*495ae853SAndroid Build Coastguard Worker                         void **ptr_to_be_filled,
93*495ae853SAndroid Build Coastguard Worker                         ITT_FUNC_TYPE_E e_func_type)
94*495ae853SAndroid Build Coastguard Worker {
95*495ae853SAndroid Build Coastguard Worker     /* Fill base for freeing the allocated memory */
96*495ae853SAndroid Build Coastguard Worker     if (e_func_type == FILL_BASE)
97*495ae853SAndroid Build Coastguard Worker     {
98*495ae853SAndroid Build Coastguard Worker         if (ptr_to_be_filled[0] != 0)
99*495ae853SAndroid Build Coastguard Worker         {
100*495ae853SAndroid Build Coastguard Worker             ps_mem_tab->pv_base = ptr_to_be_filled[0];
101*495ae853SAndroid Build Coastguard Worker             return (0);
102*495ae853SAndroid Build Coastguard Worker         }
103*495ae853SAndroid Build Coastguard Worker         else
104*495ae853SAndroid Build Coastguard Worker         {
105*495ae853SAndroid Build Coastguard Worker             return (-1);
106*495ae853SAndroid Build Coastguard Worker         }
107*495ae853SAndroid Build Coastguard Worker     }
108*495ae853SAndroid Build Coastguard Worker     /* obtain the allocated memory from base pointer */
109*495ae853SAndroid Build Coastguard Worker     if (e_func_type == USE_BASE)
110*495ae853SAndroid Build Coastguard Worker     {
111*495ae853SAndroid Build Coastguard Worker         if (ps_mem_tab->pv_base != 0)
112*495ae853SAndroid Build Coastguard Worker         {
113*495ae853SAndroid Build Coastguard Worker             ptr_to_be_filled[0] = ps_mem_tab->pv_base;
114*495ae853SAndroid Build Coastguard Worker             return (0);
115*495ae853SAndroid Build Coastguard Worker         }
116*495ae853SAndroid Build Coastguard Worker         else
117*495ae853SAndroid Build Coastguard Worker         {
118*495ae853SAndroid Build Coastguard Worker             return (-1);
119*495ae853SAndroid Build Coastguard Worker         }
120*495ae853SAndroid Build Coastguard Worker     }
121*495ae853SAndroid Build Coastguard Worker     return (0);
122*495ae853SAndroid Build Coastguard Worker }
123*495ae853SAndroid Build Coastguard Worker 
124*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
125*495ae853SAndroid Build Coastguard Worker /* Restricts the quantization parameter variation within delta */
126*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
127*495ae853SAndroid Build Coastguard Worker /* static WORD32 restrict_swing(WORD32 cur_qp, WORD32 prev_qp, WORD32 delta_qp)
128*495ae853SAndroid Build Coastguard Worker  {
129*495ae853SAndroid Build Coastguard Worker  if((cur_qp) - (prev_qp) > (delta_qp)) (cur_qp) = (prev_qp) + (delta_qp) ;
130*495ae853SAndroid Build Coastguard Worker  if((prev_qp) - (cur_qp) > (delta_qp)) (cur_qp) = (prev_qp) - (delta_qp) ;
131*495ae853SAndroid Build Coastguard Worker  return cur_qp;
132*495ae853SAndroid Build Coastguard Worker  }*/
133*495ae853SAndroid Build Coastguard Worker 
134*495ae853SAndroid Build Coastguard Worker /*****************************************************************************
135*495ae853SAndroid Build Coastguard Worker  Function Name : rate_control_get_init_free_memtab
136*495ae853SAndroid Build Coastguard Worker  Description   : Takes or gives memtab
137*495ae853SAndroid Build Coastguard Worker  Inputs        : pps_rate_control_api -  pointer to RC api pointer
138*495ae853SAndroid Build Coastguard Worker  ps_memtab            -  Memtab pointer
139*495ae853SAndroid Build Coastguard Worker  i4_use_base          -  Set during init, else 0
140*495ae853SAndroid Build Coastguard Worker  i4_fill_base         -  Set during free, else 0
141*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_rate_control_num_fill_use_free_memtab(rate_control_handle * pps_rate_control_api,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)142*495ae853SAndroid Build Coastguard Worker WORD32 irc_rate_control_num_fill_use_free_memtab(rate_control_handle *pps_rate_control_api,
143*495ae853SAndroid Build Coastguard Worker                                                  itt_memtab_t *ps_memtab,
144*495ae853SAndroid Build Coastguard Worker                                                  ITT_FUNC_TYPE_E e_func_type)
145*495ae853SAndroid Build Coastguard Worker {
146*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mem_tab_idx = 0, i;
147*495ae853SAndroid Build Coastguard Worker     rate_control_api_t s_temp_rc_api;
148*495ae853SAndroid Build Coastguard Worker 
149*495ae853SAndroid Build Coastguard Worker     /*
150*495ae853SAndroid Build Coastguard Worker      * Hack for al alloc, during which we dont have any state memory.
151*495ae853SAndroid Build Coastguard Worker      * Dereferencing can cause issues
152*495ae853SAndroid Build Coastguard Worker      */
153*495ae853SAndroid Build Coastguard Worker     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
154*495ae853SAndroid Build Coastguard Worker         (*pps_rate_control_api) = &s_temp_rc_api;
155*495ae853SAndroid Build Coastguard Worker 
156*495ae853SAndroid Build Coastguard Worker     /*for src rate control state structure*/
157*495ae853SAndroid Build Coastguard Worker     if(e_func_type != GET_NUM_MEMTAB)
158*495ae853SAndroid Build Coastguard Worker     {
159*495ae853SAndroid Build Coastguard Worker         fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(rate_control_api_t),
160*495ae853SAndroid Build Coastguard Worker                     ALIGN_128_BYTE, PERSISTENT, DDR);
161*495ae853SAndroid Build Coastguard Worker         use_or_fill_base(&ps_memtab[0], (void**)pps_rate_control_api,
162*495ae853SAndroid Build Coastguard Worker                          e_func_type);
163*495ae853SAndroid Build Coastguard Worker     }
164*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx++;
165*495ae853SAndroid Build Coastguard Worker 
166*495ae853SAndroid Build Coastguard Worker     /* Get the memory requirement of lower modules */
167*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_ba_num_fill_use_free_memtab(
168*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_bit_allocation,
169*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
170*495ae853SAndroid Build Coastguard Worker 
171*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_cbr_buffer_num_fill_use_free_memtab(
172*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_cbr_buffer,
173*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
174*495ae853SAndroid Build Coastguard Worker 
175*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_est_sad_num_fill_use_free_memtab(
176*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_est_sad,
177*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
178*495ae853SAndroid Build Coastguard Worker 
179*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_mbrc_num_fill_use_free_memtab(
180*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_mb_rate_control,
181*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
182*495ae853SAndroid Build Coastguard Worker 
183*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_vbr_vbv_num_fill_use_free_memtab(
184*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_vbr_storage_vbv,
185*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
186*495ae853SAndroid Build Coastguard Worker 
187*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
188*495ae853SAndroid Build Coastguard Worker     {
189*495ae853SAndroid Build Coastguard Worker         i4_mem_tab_idx += irc_rd_model_num_fill_use_free_memtab(
190*495ae853SAndroid Build Coastguard Worker                         &pps_rate_control_api[0]->aps_rd_model[i],
191*495ae853SAndroid Build Coastguard Worker                         &ps_memtab[i4_mem_tab_idx], e_func_type);
192*495ae853SAndroid Build Coastguard Worker     }
193*495ae853SAndroid Build Coastguard Worker     i4_mem_tab_idx += irc_pic_handling_num_fill_use_free_memtab(
194*495ae853SAndroid Build Coastguard Worker                     &pps_rate_control_api[0]->ps_pic_handling,
195*495ae853SAndroid Build Coastguard Worker                     &ps_memtab[i4_mem_tab_idx], e_func_type);
196*495ae853SAndroid Build Coastguard Worker 
197*495ae853SAndroid Build Coastguard Worker     return (i4_mem_tab_idx);
198*495ae853SAndroid Build Coastguard Worker }
199*495ae853SAndroid Build Coastguard Worker 
200*495ae853SAndroid Build Coastguard Worker /*****************************************************************************
201*495ae853SAndroid Build Coastguard Worker  Function Name : irc_initialise_rate_control
202*495ae853SAndroid Build Coastguard Worker  Description   : Initialise the rate control structure
203*495ae853SAndroid Build Coastguard Worker  Inputs        : ps_rate_control_api   - api struct
204*495ae853SAndroid Build Coastguard Worker                  e_rate_control_type   - VBR, CBR (NLDRC/LDRC), VBR_STREAMING
205*495ae853SAndroid Build Coastguard Worker                  u1_is_mb_level_rc_on  - enabling mb level RC
206*495ae853SAndroid Build Coastguard Worker                  u4_avg_bit_rate       - bit rate to achieved across the entire
207*495ae853SAndroid Build Coastguard Worker                                          file size
208*495ae853SAndroid Build Coastguard Worker                  u4_peak_bit_rate      - max possible drain rate
209*495ae853SAndroid Build Coastguard Worker                  u4_frame_rate         - number of frames in 1000 seconds
210*495ae853SAndroid Build Coastguard Worker                  u4_intra_frame_interval - num frames between two I frames
211*495ae853SAndroid Build Coastguard Worker                  *au1_init_qp          - init_qp for I,P,B
212*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_initialise_rate_control(rate_control_api_t * ps_rate_control_api,rc_type_e e_rate_control_type,UWORD8 u1_is_mb_level_rc_on,UWORD32 u4_avg_bit_rate,UWORD32 * pu4_peak_bit_rate,UWORD32 u4_min_bit_rate,UWORD32 u4_frame_rate,UWORD32 u4_max_delay,UWORD32 u4_intra_frame_interval,WORD32 i4_inter_frm_int,UWORD8 * pu1_init_qp,UWORD32 u4_max_vbv_buff_size,WORD32 i4_max_inter_frm_int,WORD32 i4_is_gop_closed,UWORD8 * pu1_min_max_qp,WORD32 i4_use_est_intra_sad,UWORD32 u4_src_ticks,UWORD32 u4_tgt_ticks)213*495ae853SAndroid Build Coastguard Worker void irc_initialise_rate_control(rate_control_api_t *ps_rate_control_api,
214*495ae853SAndroid Build Coastguard Worker                                  rc_type_e e_rate_control_type,
215*495ae853SAndroid Build Coastguard Worker                                  UWORD8 u1_is_mb_level_rc_on,
216*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_avg_bit_rate,
217*495ae853SAndroid Build Coastguard Worker                                  UWORD32 *pu4_peak_bit_rate,
218*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_min_bit_rate,
219*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_frame_rate,
220*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_max_delay,
221*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_intra_frame_interval,
222*495ae853SAndroid Build Coastguard Worker                                  WORD32  i4_inter_frm_int,
223*495ae853SAndroid Build Coastguard Worker                                  UWORD8 *pu1_init_qp,
224*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_max_vbv_buff_size,
225*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_max_inter_frm_int,
226*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_is_gop_closed,
227*495ae853SAndroid Build Coastguard Worker                                  UWORD8 *pu1_min_max_qp,
228*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_use_est_intra_sad,
229*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_src_ticks,
230*495ae853SAndroid Build Coastguard Worker                                  UWORD32 u4_tgt_ticks)
231*495ae853SAndroid Build Coastguard Worker {
232*495ae853SAndroid Build Coastguard Worker     WORD32 i;
233*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_frms_in_delay_prd;
234*495ae853SAndroid Build Coastguard Worker 
235*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(u4_frame_rate, u4_max_delay, 1000000, u4_frms_in_delay_prd);
236*495ae853SAndroid Build Coastguard Worker     ps_rate_control_api->e_rc_type = e_rate_control_type;
237*495ae853SAndroid Build Coastguard Worker     ps_rate_control_api->u1_is_mb_level_rc_on = u1_is_mb_level_rc_on;
238*495ae853SAndroid Build Coastguard Worker 
239*495ae853SAndroid Build Coastguard Worker     TRACE_PRINTF((const WORD8*)"RC type = %d\n", e_rate_control_type);
240*495ae853SAndroid Build Coastguard Worker 
241*495ae853SAndroid Build Coastguard Worker     /* Set the avg_bitrate_changed flag for each pic_type to 0 */
242*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
243*495ae853SAndroid Build Coastguard Worker     {
244*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_avg_bitrate_changed[i] = 0;
245*495ae853SAndroid Build Coastguard Worker     }
246*495ae853SAndroid Build Coastguard Worker 
247*495ae853SAndroid Build Coastguard Worker     /* Initialize the pic_handling module */
248*495ae853SAndroid Build Coastguard Worker     irc_init_pic_handling(ps_rate_control_api->ps_pic_handling,
249*495ae853SAndroid Build Coastguard Worker                           (WORD32)u4_intra_frame_interval,
250*495ae853SAndroid Build Coastguard Worker                           i4_inter_frm_int, i4_max_inter_frm_int,
251*495ae853SAndroid Build Coastguard Worker                           i4_is_gop_closed);
252*495ae853SAndroid Build Coastguard Worker 
253*495ae853SAndroid Build Coastguard Worker     /*** Initialize the rate control modules  ***/
254*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
255*495ae853SAndroid Build Coastguard Worker     {
256*495ae853SAndroid Build Coastguard Worker         UWORD32 au4_num_pics_in_delay_prd[MAX_PIC_TYPE];
257*495ae853SAndroid Build Coastguard Worker 
258*495ae853SAndroid Build Coastguard Worker         /* Initialize the model parameter structures */
259*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < MAX_PIC_TYPE; i++)
260*495ae853SAndroid Build Coastguard Worker         {
261*495ae853SAndroid Build Coastguard Worker             irc_init_frm_rc_rd_model(ps_rate_control_api->aps_rd_model[i],
262*495ae853SAndroid Build Coastguard Worker                                      MAX_FRAMES_MODELLED);
263*495ae853SAndroid Build Coastguard Worker         }
264*495ae853SAndroid Build Coastguard Worker 
265*495ae853SAndroid Build Coastguard Worker         /* Initialize the buffer mechanism */
266*495ae853SAndroid Build Coastguard Worker         if((ps_rate_control_api->e_rc_type == VBR_STORAGE)
267*495ae853SAndroid Build Coastguard Worker                         || (ps_rate_control_api->e_rc_type
268*495ae853SAndroid Build Coastguard Worker                                         == VBR_STORAGE_DVD_COMP))
269*495ae853SAndroid Build Coastguard Worker         {
270*495ae853SAndroid Build Coastguard Worker             /* Assuming both the peak bit rates are same for a VBR_STORAGE and
271*495ae853SAndroid Build Coastguard Worker              VBR_STORAGE_DVD_COMP */
272*495ae853SAndroid Build Coastguard Worker             if(pu4_peak_bit_rate[0] != pu4_peak_bit_rate[1])
273*495ae853SAndroid Build Coastguard Worker             {
274*495ae853SAndroid Build Coastguard Worker                 TRACE_PRINTF((const WORD8*)"For VBR_STORAGE and VBR_STORAGE_DVD_COMP the peak bit rates should be same\n");
275*495ae853SAndroid Build Coastguard Worker             }
276*495ae853SAndroid Build Coastguard Worker             irc_init_vbr_vbv(ps_rate_control_api->ps_vbr_storage_vbv,
277*495ae853SAndroid Build Coastguard Worker                              (WORD32)pu4_peak_bit_rate[0],
278*495ae853SAndroid Build Coastguard Worker                              (WORD32)u4_frame_rate,
279*495ae853SAndroid Build Coastguard Worker                              (WORD32)u4_max_vbv_buff_size);
280*495ae853SAndroid Build Coastguard Worker         }
281*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
282*495ae853SAndroid Build Coastguard Worker         {
283*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_avg_bit_rate_copy[MAX_NUM_DRAIN_RATES];
284*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
285*495ae853SAndroid Build Coastguard Worker             {
286*495ae853SAndroid Build Coastguard Worker                 u4_avg_bit_rate_copy[i] = u4_avg_bit_rate;
287*495ae853SAndroid Build Coastguard Worker             }
288*495ae853SAndroid Build Coastguard Worker             /* In case of CBR the num pics in delay is ignored */
289*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_PIC_TYPE; i++)
290*495ae853SAndroid Build Coastguard Worker                 au4_num_pics_in_delay_prd[i] = 0;
291*495ae853SAndroid Build Coastguard Worker 
292*495ae853SAndroid Build Coastguard Worker             irc_init_cbr_buffer(ps_rate_control_api->ps_cbr_buffer,
293*495ae853SAndroid Build Coastguard Worker                                 u4_max_delay, u4_frame_rate,
294*495ae853SAndroid Build Coastguard Worker                                 (WORD32 *)u4_avg_bit_rate_copy,
295*495ae853SAndroid Build Coastguard Worker                                 au4_num_pics_in_delay_prd,
296*495ae853SAndroid Build Coastguard Worker                                 u4_max_vbv_buff_size);
297*495ae853SAndroid Build Coastguard Worker         }
298*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
299*495ae853SAndroid Build Coastguard Worker         {
300*495ae853SAndroid Build Coastguard Worker             irc_init_vbv_str_prms(&ps_rate_control_api->s_vbr_str_prms,
301*495ae853SAndroid Build Coastguard Worker                                   u4_intra_frame_interval, u4_src_ticks,
302*495ae853SAndroid Build Coastguard Worker                                   u4_tgt_ticks, u4_frms_in_delay_prd);
303*495ae853SAndroid Build Coastguard Worker 
304*495ae853SAndroid Build Coastguard Worker             /* Get the number of pics of each type in delay period */
305*495ae853SAndroid Build Coastguard Worker             irc_get_vsp_num_pics_in_dly_prd(
306*495ae853SAndroid Build Coastguard Worker                             &ps_rate_control_api->s_vbr_str_prms,
307*495ae853SAndroid Build Coastguard Worker                             au4_num_pics_in_delay_prd);
308*495ae853SAndroid Build Coastguard Worker 
309*495ae853SAndroid Build Coastguard Worker             irc_init_cbr_buffer(ps_rate_control_api->ps_cbr_buffer,
310*495ae853SAndroid Build Coastguard Worker                                 u4_max_delay, u4_frame_rate,
311*495ae853SAndroid Build Coastguard Worker                                 (WORD32 *)pu4_peak_bit_rate,
312*495ae853SAndroid Build Coastguard Worker                                 au4_num_pics_in_delay_prd,
313*495ae853SAndroid Build Coastguard Worker                                 u4_max_vbv_buff_size);
314*495ae853SAndroid Build Coastguard Worker         }
315*495ae853SAndroid Build Coastguard Worker 
316*495ae853SAndroid Build Coastguard Worker         /* Initialize the SAD estimation module */
317*495ae853SAndroid Build Coastguard Worker         irc_init_est_sad(ps_rate_control_api->ps_est_sad, i4_use_est_intra_sad);
318*495ae853SAndroid Build Coastguard Worker 
319*495ae853SAndroid Build Coastguard Worker         /* Initialize the bit allocation module according to VBR or CBR */
320*495ae853SAndroid Build Coastguard Worker         if((ps_rate_control_api->e_rc_type == VBR_STORAGE)
321*495ae853SAndroid Build Coastguard Worker                         || (ps_rate_control_api->e_rc_type == VBR_STREAMING)
322*495ae853SAndroid Build Coastguard Worker                         || (ps_rate_control_api->e_rc_type
323*495ae853SAndroid Build Coastguard Worker                                         == VBR_STORAGE_DVD_COMP))
324*495ae853SAndroid Build Coastguard Worker         {
325*495ae853SAndroid Build Coastguard Worker             irc_ba_init_bit_allocation(ps_rate_control_api->ps_bit_allocation,
326*495ae853SAndroid Build Coastguard Worker                                        ps_rate_control_api->ps_pic_handling,
327*495ae853SAndroid Build Coastguard Worker                                        VBR_BIT_ALLOC_PERIOD, u4_avg_bit_rate,
328*495ae853SAndroid Build Coastguard Worker                                        u4_frame_rate,
329*495ae853SAndroid Build Coastguard Worker                                        (WORD32 *)pu4_peak_bit_rate,
330*495ae853SAndroid Build Coastguard Worker                                        u4_min_bit_rate);
331*495ae853SAndroid Build Coastguard Worker         }
332*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
333*495ae853SAndroid Build Coastguard Worker         {
334*495ae853SAndroid Build Coastguard Worker             irc_ba_init_bit_allocation(ps_rate_control_api->ps_bit_allocation,
335*495ae853SAndroid Build Coastguard Worker                                        ps_rate_control_api->ps_pic_handling,
336*495ae853SAndroid Build Coastguard Worker                                        CBR_BIT_ALLOC_PERIOD, u4_avg_bit_rate,
337*495ae853SAndroid Build Coastguard Worker                                        u4_frame_rate,
338*495ae853SAndroid Build Coastguard Worker                                        (WORD32 *)pu4_peak_bit_rate,
339*495ae853SAndroid Build Coastguard Worker                                        u4_min_bit_rate);
340*495ae853SAndroid Build Coastguard Worker         }
341*495ae853SAndroid Build Coastguard Worker 
342*495ae853SAndroid Build Coastguard Worker         /*
343*495ae853SAndroid Build Coastguard Worker          * u1_scd_detected will be initialized to 1 when a Scene change is
344*495ae853SAndroid Build Coastguard Worker          * detected
345*495ae853SAndroid Build Coastguard Worker          */
346*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->u1_scd_detected = 0;
347*495ae853SAndroid Build Coastguard Worker     }
348*495ae853SAndroid Build Coastguard Worker 
349*495ae853SAndroid Build Coastguard Worker     /* Initialize the init_qp */
350*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
351*495ae853SAndroid Build Coastguard Worker     {
352*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_init_qp[i] = pu1_init_qp[i];
353*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_prev_frm_qp[i] = pu1_init_qp[i];
354*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_min_max_qp[(i << 1)] =
355*495ae853SAndroid Build Coastguard Worker                         pu1_min_max_qp[(i << 1)];
356*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_min_max_qp[(i << 1) + 1] = pu1_min_max_qp[(i
357*495ae853SAndroid Build Coastguard Worker                         << 1) + 1];
358*495ae853SAndroid Build Coastguard Worker     }
359*495ae853SAndroid Build Coastguard Worker 
360*495ae853SAndroid Build Coastguard Worker     /* Initialize the is_first_frm_encoded */
361*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
362*495ae853SAndroid Build Coastguard Worker     {
363*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_is_first_frm_coded[i] = 0;
364*495ae853SAndroid Build Coastguard Worker     }
365*495ae853SAndroid Build Coastguard Worker     ps_rate_control_api->u1_is_first_frm = 1;
366*495ae853SAndroid Build Coastguard Worker 
367*495ae853SAndroid Build Coastguard Worker     /*
368*495ae853SAndroid Build Coastguard Worker      * Control flag for delayed impact after a change in peak bitrate has been
369*495ae853SAndroid Build Coastguard Worker      * made
370*495ae853SAndroid Build Coastguard Worker      */
371*495ae853SAndroid Build Coastguard Worker     ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change = 0;
372*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
373*495ae853SAndroid Build Coastguard Worker     {
374*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au4_new_peak_bit_rate[i] = pu4_peak_bit_rate[i];
375*495ae853SAndroid Build Coastguard Worker     }
376*495ae853SAndroid Build Coastguard Worker 
377*495ae853SAndroid Build Coastguard Worker     /* Initialize the mb level rate control module */
378*495ae853SAndroid Build Coastguard Worker     irc_init_mb_level_rc(ps_rate_control_api->ps_mb_rate_control);
379*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(u4_avg_bit_rate, 1000, u4_frame_rate,
380*495ae853SAndroid Build Coastguard Worker                    ps_rate_control_api->i4_prev_frm_est_bits);
381*495ae853SAndroid Build Coastguard Worker 
382*495ae853SAndroid Build Coastguard Worker     ps_rate_control_api->prev_ref_pic_type = I_PIC;
383*495ae853SAndroid Build Coastguard Worker }
384*495ae853SAndroid Build Coastguard Worker 
385*495ae853SAndroid Build Coastguard Worker /******************************************************************************
386*495ae853SAndroid Build Coastguard Worker  *Description   : calls irc_add_pic_to_stack
387*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_add_picture_to_stack(rate_control_api_t * rate_control_api,WORD32 i4_enc_pic_id)388*495ae853SAndroid Build Coastguard Worker void irc_add_picture_to_stack(rate_control_api_t *rate_control_api,
389*495ae853SAndroid Build Coastguard Worker                               WORD32 i4_enc_pic_id)
390*495ae853SAndroid Build Coastguard Worker {
391*495ae853SAndroid Build Coastguard Worker     /* Call the routine to add the pic to stack in encode order */
392*495ae853SAndroid Build Coastguard Worker     irc_add_pic_to_stack(rate_control_api->ps_pic_handling, i4_enc_pic_id);
393*495ae853SAndroid Build Coastguard Worker }
394*495ae853SAndroid Build Coastguard Worker 
irc_add_picture_to_stack_re_enc(rate_control_api_t * rate_control_api,WORD32 i4_enc_pic_id,picture_type_e e_pic_type)395*495ae853SAndroid Build Coastguard Worker void irc_add_picture_to_stack_re_enc(rate_control_api_t *rate_control_api,
396*495ae853SAndroid Build Coastguard Worker                                      WORD32 i4_enc_pic_id,
397*495ae853SAndroid Build Coastguard Worker                                      picture_type_e e_pic_type)
398*495ae853SAndroid Build Coastguard Worker {
399*495ae853SAndroid Build Coastguard Worker     /*
400*495ae853SAndroid Build Coastguard Worker      * In case of a re-encoder, the pics will come in the encode order itself.
401*495ae853SAndroid Build Coastguard Worker      * So, there is no need to buffer the pics up
402*495ae853SAndroid Build Coastguard Worker      */
403*495ae853SAndroid Build Coastguard Worker     irc_add_pic_to_stack_re_enc(rate_control_api->ps_pic_handling,
404*495ae853SAndroid Build Coastguard Worker                                 i4_enc_pic_id, e_pic_type);
405*495ae853SAndroid Build Coastguard Worker }
406*495ae853SAndroid Build Coastguard Worker 
407*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
408*495ae853SAndroid Build Coastguard Worker  Description   : Decides the picture type based on the state
409*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_get_picture_details(rate_control_handle rate_control_api,WORD32 * pi4_pic_id,WORD32 * pi4_pic_disp_order_no,picture_type_e * pe_pic_type)410*495ae853SAndroid Build Coastguard Worker void irc_get_picture_details(rate_control_handle rate_control_api,
411*495ae853SAndroid Build Coastguard Worker                              WORD32 *pi4_pic_id,
412*495ae853SAndroid Build Coastguard Worker                              WORD32 *pi4_pic_disp_order_no,
413*495ae853SAndroid Build Coastguard Worker                              picture_type_e *pe_pic_type)
414*495ae853SAndroid Build Coastguard Worker {
415*495ae853SAndroid Build Coastguard Worker     /* Call to get the pic_details */
416*495ae853SAndroid Build Coastguard Worker     irc_get_pic_from_stack(rate_control_api->ps_pic_handling, pi4_pic_id,
417*495ae853SAndroid Build Coastguard Worker                            pi4_pic_disp_order_no, pe_pic_type);
418*495ae853SAndroid Build Coastguard Worker }
419*495ae853SAndroid Build Coastguard Worker 
420*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
421*495ae853SAndroid Build Coastguard Worker  *  Description   : Gets the frame level qp for the given picture type
422*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_get_frame_level_qp(rate_control_api_t * ps_rate_control_api,picture_type_e e_pic_type,WORD32 i4_ud_max_bits)423*495ae853SAndroid Build Coastguard Worker UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api,
424*495ae853SAndroid Build Coastguard Worker                               picture_type_e e_pic_type,
425*495ae853SAndroid Build Coastguard Worker                               WORD32 i4_ud_max_bits)
426*495ae853SAndroid Build Coastguard Worker {
427*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_frame_qp, i;
428*495ae853SAndroid Build Coastguard Worker 
429*495ae853SAndroid Build Coastguard Worker     if((ps_rate_control_api->e_rc_type != VBR_STORAGE)
430*495ae853SAndroid Build Coastguard Worker                     && (ps_rate_control_api->e_rc_type != VBR_STORAGE_DVD_COMP)
431*495ae853SAndroid Build Coastguard Worker                     && (ps_rate_control_api->e_rc_type != CBR_NLDRC)
432*495ae853SAndroid Build Coastguard Worker                     && (ps_rate_control_api->e_rc_type != CONST_QP)
433*495ae853SAndroid Build Coastguard Worker                     && (ps_rate_control_api->e_rc_type != VBR_STREAMING))
434*495ae853SAndroid Build Coastguard Worker     {
435*495ae853SAndroid Build Coastguard Worker         TRACE_PRINTF((const WORD8*)(const WORD8*)" Only VBR,NLDRC and CONST QP supported for now \n");
436*495ae853SAndroid Build Coastguard Worker         return (0);
437*495ae853SAndroid Build Coastguard Worker     }
438*495ae853SAndroid Build Coastguard Worker 
439*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
440*495ae853SAndroid Build Coastguard Worker     {
441*495ae853SAndroid Build Coastguard Worker         UWORD8 u1_is_first_frm_coded = 1;
442*495ae853SAndroid Build Coastguard Worker 
443*495ae853SAndroid Build Coastguard Worker         /* Check whether at least one frame of a each picture type gets encoded*/
444*495ae853SAndroid Build Coastguard Worker         /* Check whether it is an IPP or IPB kind of encoding */
445*495ae853SAndroid Build Coastguard Worker         if((ps_rate_control_api->au1_is_first_frm_coded[I_PIC]
446*495ae853SAndroid Build Coastguard Worker                         && ps_rate_control_api->au1_is_first_frm_coded[P_PIC])
447*495ae853SAndroid Build Coastguard Worker                         || ((irc_pic_type_get_intra_frame_interval(
448*495ae853SAndroid Build Coastguard Worker                                         ps_rate_control_api->ps_pic_handling)
449*495ae853SAndroid Build Coastguard Worker                                         == 1)
450*495ae853SAndroid Build Coastguard Worker                                         && (ps_rate_control_api->au1_is_first_frm_coded[I_PIC])))
451*495ae853SAndroid Build Coastguard Worker         {
452*495ae853SAndroid Build Coastguard Worker             if(e_pic_type != B_PIC)
453*495ae853SAndroid Build Coastguard Worker                 u1_is_first_frm_coded = 1;
454*495ae853SAndroid Build Coastguard Worker             else
455*495ae853SAndroid Build Coastguard Worker             {
456*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < MAX_PIC_TYPE; i++)
457*495ae853SAndroid Build Coastguard Worker                 {
458*495ae853SAndroid Build Coastguard Worker                     u1_is_first_frm_coded &=
459*495ae853SAndroid Build Coastguard Worker                                     ps_rate_control_api->au1_is_first_frm_coded[i];
460*495ae853SAndroid Build Coastguard Worker                 }
461*495ae853SAndroid Build Coastguard Worker             }
462*495ae853SAndroid Build Coastguard Worker         }
463*495ae853SAndroid Build Coastguard Worker         else
464*495ae853SAndroid Build Coastguard Worker         {
465*495ae853SAndroid Build Coastguard Worker             u1_is_first_frm_coded = 0;
466*495ae853SAndroid Build Coastguard Worker         }
467*495ae853SAndroid Build Coastguard Worker 
468*495ae853SAndroid Build Coastguard Worker         if(u1_is_first_frm_coded)
469*495ae853SAndroid Build Coastguard Worker         {
470*495ae853SAndroid Build Coastguard Worker             WORD32 i4_cur_est_texture_bits, i4_cur_est_header_bits;
471*495ae853SAndroid Build Coastguard Worker             WORD32 i4_cur_est_bits;
472*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_estimated_sad;
473*495ae853SAndroid Build Coastguard Worker 
474*495ae853SAndroid Build Coastguard Worker             /* Force I frame updation of rem_bits_in_frame*/
475*495ae853SAndroid Build Coastguard Worker             if(irc_get_forced_I_frame_cur_frm_flag(
476*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_pic_handling) == 1)
477*495ae853SAndroid Build Coastguard Worker             {
478*495ae853SAndroid Build Coastguard Worker                 irc_ba_change_rem_bits_in_prd_at_force_I_frame(
479*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_bit_allocation,
480*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_pic_handling);
481*495ae853SAndroid Build Coastguard Worker                 irc_reset_forced_I_frame_cur_frm_flag(
482*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_pic_handling);
483*495ae853SAndroid Build Coastguard Worker             }
484*495ae853SAndroid Build Coastguard Worker 
485*495ae853SAndroid Build Coastguard Worker             /* Get the estimated texture bits allocated for the current frame*/
486*495ae853SAndroid Build Coastguard Worker             i4_cur_est_texture_bits = irc_ba_get_cur_frm_est_texture_bits(
487*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_bit_allocation,
488*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->aps_rd_model,
489*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_est_sad,
490*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_pic_handling, e_pic_type);
491*495ae853SAndroid Build Coastguard Worker 
492*495ae853SAndroid Build Coastguard Worker             /* Get the estimated header bits*/
493*495ae853SAndroid Build Coastguard Worker             i4_cur_est_header_bits = irc_ba_get_cur_frm_est_header_bits(
494*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_bit_allocation, e_pic_type);
495*495ae853SAndroid Build Coastguard Worker 
496*495ae853SAndroid Build Coastguard Worker             /* Total estimated bits */
497*495ae853SAndroid Build Coastguard Worker             i4_cur_est_bits = i4_cur_est_header_bits + i4_cur_est_texture_bits;
498*495ae853SAndroid Build Coastguard Worker 
499*495ae853SAndroid Build Coastguard Worker             TRACE_PRINTF((const WORD8*)"ft %d, etb = %d, eb %d, ", e_pic_type,
500*495ae853SAndroid Build Coastguard Worker                          i4_cur_est_texture_bits, i4_cur_est_bits);
501*495ae853SAndroid Build Coastguard Worker 
502*495ae853SAndroid Build Coastguard Worker             /* Threshold the estimated bits based on the buffer fullness*/
503*495ae853SAndroid Build Coastguard Worker             if(ps_rate_control_api->e_rc_type == VBR_STORAGE)
504*495ae853SAndroid Build Coastguard Worker             {
505*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_cur_frm_max_bit_possible;
506*495ae853SAndroid Build Coastguard Worker                 i4_cur_frm_max_bit_possible = irc_get_max_target_bits(
507*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_vbr_storage_vbv);
508*495ae853SAndroid Build Coastguard Worker 
509*495ae853SAndroid Build Coastguard Worker                 if(i4_cur_est_bits > i4_cur_frm_max_bit_possible)
510*495ae853SAndroid Build Coastguard Worker                 {
511*495ae853SAndroid Build Coastguard Worker                     /* Assuming header would consume the same amount of bits */
512*495ae853SAndroid Build Coastguard Worker                     i4_cur_est_texture_bits = i4_cur_frm_max_bit_possible
513*495ae853SAndroid Build Coastguard Worker                                     - i4_cur_est_header_bits;
514*495ae853SAndroid Build Coastguard Worker                 }
515*495ae853SAndroid Build Coastguard Worker             }
516*495ae853SAndroid Build Coastguard Worker             else if(ps_rate_control_api->e_rc_type == VBR_STORAGE_DVD_COMP)
517*495ae853SAndroid Build Coastguard Worker             {
518*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_rem_bits_in_gop, i4_rem_frms_in_gop, i;
519*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_cur_frm_max_bit_possible,
520*495ae853SAndroid Build Coastguard Worker                                 ai4_rem_frms_in_gop[MAX_PIC_TYPE];
521*495ae853SAndroid Build Coastguard Worker                 irc_pic_type_get_rem_frms_in_gop(
522*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_pic_handling,
523*495ae853SAndroid Build Coastguard Worker                                 ai4_rem_frms_in_gop);
524*495ae853SAndroid Build Coastguard Worker                 i4_rem_bits_in_gop = irc_get_rem_bits_in_period(
525*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api);
526*495ae853SAndroid Build Coastguard Worker                 i4_rem_frms_in_gop = 0;
527*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < MAX_PIC_TYPE; i++)
528*495ae853SAndroid Build Coastguard Worker                     i4_rem_frms_in_gop += ai4_rem_frms_in_gop[i];
529*495ae853SAndroid Build Coastguard Worker 
530*495ae853SAndroid Build Coastguard Worker                 /* Threshold the bits based on estimated buffer fullness */
531*495ae853SAndroid Build Coastguard Worker                 i4_cur_frm_max_bit_possible = irc_get_max_tgt_bits_dvd_comp(
532*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_vbr_storage_vbv,
533*495ae853SAndroid Build Coastguard Worker                                 i4_rem_bits_in_gop, i4_rem_frms_in_gop,
534*495ae853SAndroid Build Coastguard Worker                                 e_pic_type);
535*495ae853SAndroid Build Coastguard Worker 
536*495ae853SAndroid Build Coastguard Worker                 if(i4_cur_est_bits > i4_cur_frm_max_bit_possible)
537*495ae853SAndroid Build Coastguard Worker                 {
538*495ae853SAndroid Build Coastguard Worker                     /* Assuming header would consume the same amount of bits */
539*495ae853SAndroid Build Coastguard Worker                     i4_cur_est_texture_bits = i4_cur_frm_max_bit_possible
540*495ae853SAndroid Build Coastguard Worker                                     - i4_cur_est_header_bits;
541*495ae853SAndroid Build Coastguard Worker 
542*495ae853SAndroid Build Coastguard Worker                 }
543*495ae853SAndroid Build Coastguard Worker             }
544*495ae853SAndroid Build Coastguard Worker             else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
545*495ae853SAndroid Build Coastguard Worker             {
546*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_cur_frm_bits_acc_buffer =
547*495ae853SAndroid Build Coastguard Worker                                 irc_cbr_buffer_constraint_check(
548*495ae853SAndroid Build Coastguard Worker                                                 ps_rate_control_api->ps_cbr_buffer,
549*495ae853SAndroid Build Coastguard Worker                                                 i4_cur_est_bits, e_pic_type);
550*495ae853SAndroid Build Coastguard Worker 
551*495ae853SAndroid Build Coastguard Worker                 /* Assuming the header would consume the same amount of bits */
552*495ae853SAndroid Build Coastguard Worker                 i4_cur_est_texture_bits = i4_cur_frm_bits_acc_buffer
553*495ae853SAndroid Build Coastguard Worker                                 - i4_cur_est_header_bits;
554*495ae853SAndroid Build Coastguard Worker 
555*495ae853SAndroid Build Coastguard Worker             }
556*495ae853SAndroid Build Coastguard Worker             else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
557*495ae853SAndroid Build Coastguard Worker             {
558*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_cur_frm_bits_acc_buffer =
559*495ae853SAndroid Build Coastguard Worker                                 irc_vbr_stream_buffer_constraint_check(
560*495ae853SAndroid Build Coastguard Worker                                                 ps_rate_control_api->ps_cbr_buffer,
561*495ae853SAndroid Build Coastguard Worker                                                 i4_cur_est_bits, e_pic_type);
562*495ae853SAndroid Build Coastguard Worker 
563*495ae853SAndroid Build Coastguard Worker                 /* Assuming the header would consume the same amount of bits */
564*495ae853SAndroid Build Coastguard Worker                 i4_cur_est_texture_bits = i4_cur_frm_bits_acc_buffer
565*495ae853SAndroid Build Coastguard Worker                                 - i4_cur_est_header_bits;
566*495ae853SAndroid Build Coastguard Worker             }
567*495ae853SAndroid Build Coastguard Worker 
568*495ae853SAndroid Build Coastguard Worker             TRACE_PRINTF((const WORD8*)"emtb = %d, ", i4_cur_est_texture_bits);
569*495ae853SAndroid Build Coastguard Worker 
570*495ae853SAndroid Build Coastguard Worker             /*
571*495ae853SAndroid Build Coastguard Worker              * If the estimated texture bits go to values less than zero
572*495ae853SAndroid Build Coastguard Worker              * due to buffer underflow, make the estimated target bits to go
573*495ae853SAndroid Build Coastguard Worker              * to zero
574*495ae853SAndroid Build Coastguard Worker              */
575*495ae853SAndroid Build Coastguard Worker             if(i4_cur_est_texture_bits < 0)
576*495ae853SAndroid Build Coastguard Worker                 i4_cur_est_texture_bits = 0;
577*495ae853SAndroid Build Coastguard Worker 
578*495ae853SAndroid Build Coastguard Worker             ps_rate_control_api->i4_prev_frm_est_bits = (i4_cur_est_texture_bits
579*495ae853SAndroid Build Coastguard Worker                             + i4_cur_est_header_bits);
580*495ae853SAndroid Build Coastguard Worker 
581*495ae853SAndroid Build Coastguard Worker             /* Clip est_texture_bits according to the user-defined max value */
582*495ae853SAndroid Build Coastguard Worker             if((i4_cur_est_texture_bits
583*495ae853SAndroid Build Coastguard Worker                             > (i4_ud_max_bits - i4_cur_est_header_bits))
584*495ae853SAndroid Build Coastguard Worker                             && (e_pic_type != I_PIC))
585*495ae853SAndroid Build Coastguard Worker             {
586*495ae853SAndroid Build Coastguard Worker                 i4_cur_est_texture_bits = (i4_ud_max_bits
587*495ae853SAndroid Build Coastguard Worker                                 - i4_cur_est_header_bits);
588*495ae853SAndroid Build Coastguard Worker                 TRACE_PRINTF((const WORD8*)"udcb = %d, ",
589*495ae853SAndroid Build Coastguard Worker                              i4_ud_max_bits - i4_cur_est_header_bits);
590*495ae853SAndroid Build Coastguard Worker             }
591*495ae853SAndroid Build Coastguard Worker 
592*495ae853SAndroid Build Coastguard Worker             /* Calculate the estimated SAD for corresponding frame*/
593*495ae853SAndroid Build Coastguard Worker             u4_estimated_sad = irc_get_est_sad(ps_rate_control_api->ps_est_sad,
594*495ae853SAndroid Build Coastguard Worker                                                e_pic_type);
595*495ae853SAndroid Build Coastguard Worker 
596*495ae853SAndroid Build Coastguard Worker             /* Query the model for the Qp for the corresponding frame*/
597*495ae853SAndroid Build Coastguard Worker 
598*495ae853SAndroid Build Coastguard Worker             /*
599*495ae853SAndroid Build Coastguard Worker              * The check is because the model gives a negative QP when the
600*495ae853SAndroid Build Coastguard Worker              * i4_cur_est_texture_bits is less than or equal to 0
601*495ae853SAndroid Build Coastguard Worker              * [This is a bug in the model]. As a temporary fix, the frame QP
602*495ae853SAndroid Build Coastguard Worker              * is being set to the max QP allowed
603*495ae853SAndroid Build Coastguard Worker              */
604*495ae853SAndroid Build Coastguard Worker             if(i4_cur_est_texture_bits > 0)
605*495ae853SAndroid Build Coastguard Worker             {
606*495ae853SAndroid Build Coastguard Worker                 u1_frame_qp = irc_find_qp_for_target_bits(
607*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->aps_rd_model[e_pic_type],
608*495ae853SAndroid Build Coastguard Worker                                 i4_cur_est_texture_bits,
609*495ae853SAndroid Build Coastguard Worker                                 u4_estimated_sad,
610*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->au1_min_max_qp[(e_pic_type
611*495ae853SAndroid Build Coastguard Worker                                                 << 1)],
612*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->au1_min_max_qp[(e_pic_type
613*495ae853SAndroid Build Coastguard Worker                                                 << 1) + 1]);
614*495ae853SAndroid Build Coastguard Worker             }
615*495ae853SAndroid Build Coastguard Worker             else
616*495ae853SAndroid Build Coastguard Worker             {
617*495ae853SAndroid Build Coastguard Worker                 u1_frame_qp = ps_rate_control_api->au1_min_max_qp[(e_pic_type
618*495ae853SAndroid Build Coastguard Worker                                 << 1) + 1];
619*495ae853SAndroid Build Coastguard Worker             }
620*495ae853SAndroid Build Coastguard Worker 
621*495ae853SAndroid Build Coastguard Worker             TRACE_PRINTF((const WORD8*)"ehb %d, etb %d, fqp %d, es %d, eb %d, ",
622*495ae853SAndroid Build Coastguard Worker                          i4_cur_est_header_bits, i4_cur_est_texture_bits,
623*495ae853SAndroid Build Coastguard Worker                          u1_frame_qp, u4_estimated_sad, i4_cur_est_bits);
624*495ae853SAndroid Build Coastguard Worker 
625*495ae853SAndroid Build Coastguard Worker             /* Restricting the QP swing if the average bit rate has changed */
626*495ae853SAndroid Build Coastguard Worker             if(ps_rate_control_api->au1_avg_bitrate_changed[e_pic_type] == 0)
627*495ae853SAndroid Build Coastguard Worker             {
628*495ae853SAndroid Build Coastguard Worker                 WORD32 prev_qp;
629*495ae853SAndroid Build Coastguard Worker                 WORD32 hi_dev_qp, lo_dev_qp;
630*495ae853SAndroid Build Coastguard Worker                 /* Restricting the qp swing */
631*495ae853SAndroid Build Coastguard Worker                 prev_qp = ps_rate_control_api->au1_prev_frm_qp[ps_rate_control_api->prev_ref_pic_type];
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker                 if(ps_rate_control_api->prev_ref_pic_type != e_pic_type)
634*495ae853SAndroid Build Coastguard Worker                 {
635*495ae853SAndroid Build Coastguard Worker                     if(e_pic_type == I_PIC)
636*495ae853SAndroid Build Coastguard Worker                     {
637*495ae853SAndroid Build Coastguard Worker                         /*
638*495ae853SAndroid Build Coastguard Worker                          * Constrain I-frame QP to be within specified limit of
639*495ae853SAndroid Build Coastguard Worker                          * prev_ref_qp/Kp
640*495ae853SAndroid Build Coastguard Worker                          */
641*495ae853SAndroid Build Coastguard Worker                         prev_qp = (P_TO_I_RATIO * prev_qp + (1 << (K_Q - 1)))
642*495ae853SAndroid Build Coastguard Worker                                         >> (K_Q);
643*495ae853SAndroid Build Coastguard Worker                     }
644*495ae853SAndroid Build Coastguard Worker                     else if(e_pic_type == P_PIC)
645*495ae853SAndroid Build Coastguard Worker                     {
646*495ae853SAndroid Build Coastguard Worker                         /*
647*495ae853SAndroid Build Coastguard Worker                          * Constrain P-frame QP to be within specified limit of
648*495ae853SAndroid Build Coastguard Worker                          * Kp*prev_ref_qp
649*495ae853SAndroid Build Coastguard Worker                          */
650*495ae853SAndroid Build Coastguard Worker                         prev_qp = (I_TO_P_RATIO * prev_qp + (1 << (K_Q - 1)))
651*495ae853SAndroid Build Coastguard Worker                                         >> (K_Q);
652*495ae853SAndroid Build Coastguard Worker                     }
653*495ae853SAndroid Build Coastguard Worker                     else if(ps_rate_control_api->prev_ref_pic_type == P_PIC)
654*495ae853SAndroid Build Coastguard Worker                     {
655*495ae853SAndroid Build Coastguard Worker                         /* current frame is B-pic */
656*495ae853SAndroid Build Coastguard Worker                         /* Constrain B-frame QP to be within specified limit of
657*495ae853SAndroid Build Coastguard Worker                          * prev_ref_qp/Kb
658*495ae853SAndroid Build Coastguard Worker                          */
659*495ae853SAndroid Build Coastguard Worker                         prev_qp = (P_TO_B_RATIO * prev_qp + (1 << (K_Q - 1)))
660*495ae853SAndroid Build Coastguard Worker                                         >> (K_Q);
661*495ae853SAndroid Build Coastguard Worker                     }
662*495ae853SAndroid Build Coastguard Worker                     else /* if(ps_rate_control_api->prev_ref_pic_type == I_PIC*/
663*495ae853SAndroid Build Coastguard Worker                     {
664*495ae853SAndroid Build Coastguard Worker                         /* current frame is B-pic */
665*495ae853SAndroid Build Coastguard Worker                         /*
666*495ae853SAndroid Build Coastguard Worker                          * Constrain B-frame QP to be within specified limit of
667*495ae853SAndroid Build Coastguard Worker                          * prev_ref_qp/Kb
668*495ae853SAndroid Build Coastguard Worker                          */
669*495ae853SAndroid Build Coastguard Worker                         prev_qp = (P_TO_B_RATIO * I_TO_P_RATIO * prev_qp
670*495ae853SAndroid Build Coastguard Worker                                         + (1 << (K_Q + K_Q - 1)))
671*495ae853SAndroid Build Coastguard Worker                                         >> (K_Q + K_Q);
672*495ae853SAndroid Build Coastguard Worker                     }
673*495ae853SAndroid Build Coastguard Worker                 }
674*495ae853SAndroid Build Coastguard Worker 
675*495ae853SAndroid Build Coastguard Worker                 /*
676*495ae853SAndroid Build Coastguard Worker                  * Due to the inexact nature of translation tables, QP may
677*495ae853SAndroid Build Coastguard Worker                  * get locked at some values. This is because of the inexactness of
678*495ae853SAndroid Build Coastguard Worker                  * the tables causing a change of +-1 in back and forth translations.
679*495ae853SAndroid Build Coastguard Worker                  * In that case, if we restrict the QP swing to +-1, we will get
680*495ae853SAndroid Build Coastguard Worker                  * the lock up condition. Hence we make it such that we will have
681*495ae853SAndroid Build Coastguard Worker                  * a swing of atleast +- 2 from prev_qp
682*495ae853SAndroid Build Coastguard Worker                  */
683*495ae853SAndroid Build Coastguard Worker 
684*495ae853SAndroid Build Coastguard Worker                 lo_dev_qp = GET_LO_DEV_QP(prev_qp);
685*495ae853SAndroid Build Coastguard Worker                 lo_dev_qp = MIN(lo_dev_qp, prev_qp - 2);
686*495ae853SAndroid Build Coastguard Worker                 lo_dev_qp = MAX(lo_dev_qp, ps_rate_control_api->au1_min_max_qp[(e_pic_type << 1)]);
687*495ae853SAndroid Build Coastguard Worker 
688*495ae853SAndroid Build Coastguard Worker                 hi_dev_qp = GET_HI_DEV_QP(prev_qp);
689*495ae853SAndroid Build Coastguard Worker                 hi_dev_qp = MAX(hi_dev_qp, prev_qp + 2);
690*495ae853SAndroid Build Coastguard Worker                 hi_dev_qp = MIN(hi_dev_qp, ps_rate_control_api->au1_min_max_qp[(e_pic_type << 1) + 1]);
691*495ae853SAndroid Build Coastguard Worker 
692*495ae853SAndroid Build Coastguard Worker                 u1_frame_qp = (UWORD8)CLIP_QP((WORD32)u1_frame_qp, hi_dev_qp , lo_dev_qp);
693*495ae853SAndroid Build Coastguard Worker 
694*495ae853SAndroid Build Coastguard Worker             }
695*495ae853SAndroid Build Coastguard Worker             else
696*495ae853SAndroid Build Coastguard Worker             {
697*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au1_avg_bitrate_changed[e_pic_type] = 0;
698*495ae853SAndroid Build Coastguard Worker             }
699*495ae853SAndroid Build Coastguard Worker         }
700*495ae853SAndroid Build Coastguard Worker         else
701*495ae853SAndroid Build Coastguard Worker         {
702*495ae853SAndroid Build Coastguard Worker             /*
703*495ae853SAndroid Build Coastguard Worker              * The u1_is_first_frm_coded gets reset
704*495ae853SAndroid Build Coastguard Worker              *  a) at start of sequence
705*495ae853SAndroid Build Coastguard Worker              *  b) whenever there is a scene change.
706*495ae853SAndroid Build Coastguard Worker              *     In both cases since we do not have any estimate about the
707*495ae853SAndroid Build Coastguard Worker              *     current frame, we just send in the previous frame qp value.IN
708*495ae853SAndroid Build Coastguard Worker              *     Scene change case the previous QP is incremented by 4 , This is
709*495ae853SAndroid Build Coastguard Worker              *     done because the Scene changed VOP will have over consumed and
710*495ae853SAndroid Build Coastguard Worker              *     chances of future frames skipping is very high. For the init
711*495ae853SAndroid Build Coastguard Worker              *     case, the previous frame QP is initialized with the init qp
712*495ae853SAndroid Build Coastguard Worker              */
713*495ae853SAndroid Build Coastguard Worker             if((ps_rate_control_api->u1_scd_detected)
714*495ae853SAndroid Build Coastguard Worker                             && (ps_rate_control_api->e_rc_type != CONST_QP))
715*495ae853SAndroid Build Coastguard Worker             {
716*495ae853SAndroid Build Coastguard Worker                 /*
717*495ae853SAndroid Build Coastguard Worker                  * If scene change is detected, I frame Qp would have been
718*495ae853SAndroid Build Coastguard Worker                  * updated
719*495ae853SAndroid Build Coastguard Worker                  */
720*495ae853SAndroid Build Coastguard Worker                  /* Use a QP calculated in the prev update fxn */
721*495ae853SAndroid Build Coastguard Worker                 u1_frame_qp = ps_rate_control_api->u1_frm_qp_after_scd;
722*495ae853SAndroid Build Coastguard Worker             }
723*495ae853SAndroid Build Coastguard Worker             else
724*495ae853SAndroid Build Coastguard Worker             {
725*495ae853SAndroid Build Coastguard Worker                 u1_frame_qp = ps_rate_control_api->au1_prev_frm_qp[e_pic_type];
726*495ae853SAndroid Build Coastguard Worker             }
727*495ae853SAndroid Build Coastguard Worker         }
728*495ae853SAndroid Build Coastguard Worker     }
729*495ae853SAndroid Build Coastguard Worker     else
730*495ae853SAndroid Build Coastguard Worker     {
731*495ae853SAndroid Build Coastguard Worker         u1_frame_qp = ps_rate_control_api->au1_init_qp[e_pic_type];
732*495ae853SAndroid Build Coastguard Worker     }
733*495ae853SAndroid Build Coastguard Worker 
734*495ae853SAndroid Build Coastguard Worker     TRACE_PRINTF((const WORD8*)"fqp %d\n", u1_frame_qp);
735*495ae853SAndroid Build Coastguard Worker 
736*495ae853SAndroid Build Coastguard Worker     return (u1_frame_qp);
737*495ae853SAndroid Build Coastguard Worker }
738*495ae853SAndroid Build Coastguard Worker 
739*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
740*495ae853SAndroid Build Coastguard Worker  *Function Name : irc_get_buffer_status
741*495ae853SAndroid Build Coastguard Worker  *Description   : Gets the state of VBV buffer
742*495ae853SAndroid Build Coastguard Worker  *Outputs       : 0 = normal, 1 = underflow, 2= overflow
743*495ae853SAndroid Build Coastguard Worker  *Returns       : vbv_buf_status_e
744*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_get_buffer_status(rate_control_api_t * ps_rate_control_api,WORD32 i4_total_frame_bits,picture_type_e e_pic_type,WORD32 * pi4_num_bits_to_prevent_vbv_underflow)745*495ae853SAndroid Build Coastguard Worker vbv_buf_status_e irc_get_buffer_status(rate_control_api_t *ps_rate_control_api,
746*495ae853SAndroid Build Coastguard Worker                                        WORD32 i4_total_frame_bits,
747*495ae853SAndroid Build Coastguard Worker                                        picture_type_e e_pic_type,
748*495ae853SAndroid Build Coastguard Worker                                        WORD32 *pi4_num_bits_to_prevent_vbv_underflow)
749*495ae853SAndroid Build Coastguard Worker {
750*495ae853SAndroid Build Coastguard Worker     vbv_buf_status_e e_buf_status = VBV_NORMAL;
751*495ae853SAndroid Build Coastguard Worker 
752*495ae853SAndroid Build Coastguard Worker     /* Get the buffer status for the current total consumed bits and error bits*/
753*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == VBR_STORAGE_DVD_COMP)
754*495ae853SAndroid Build Coastguard Worker     {
755*495ae853SAndroid Build Coastguard Worker         e_buf_status = irc_get_vbv_buffer_status(
756*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_vbr_storage_vbv,
757*495ae853SAndroid Build Coastguard Worker                         i4_total_frame_bits,
758*495ae853SAndroid Build Coastguard Worker                         pi4_num_bits_to_prevent_vbv_underflow);
759*495ae853SAndroid Build Coastguard Worker 
760*495ae853SAndroid Build Coastguard Worker         TRACE_PRINTF((const WORD8*)"e_buf_status = %d\n", e_buf_status);
761*495ae853SAndroid Build Coastguard Worker     }
762*495ae853SAndroid Build Coastguard Worker     else if(ps_rate_control_api->e_rc_type == VBR_STORAGE)
763*495ae853SAndroid Build Coastguard Worker     {
764*495ae853SAndroid Build Coastguard Worker         /* For VBR case since there is not underflow returning the max value */
765*495ae853SAndroid Build Coastguard Worker         pi4_num_bits_to_prevent_vbv_underflow[0] = irc_get_max_vbv_buf_size(
766*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_vbr_storage_vbv);
767*495ae853SAndroid Build Coastguard Worker         e_buf_status = VBV_NORMAL;
768*495ae853SAndroid Build Coastguard Worker     }
769*495ae853SAndroid Build Coastguard Worker     else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
770*495ae853SAndroid Build Coastguard Worker     {
771*495ae853SAndroid Build Coastguard Worker         e_buf_status = irc_get_cbr_buffer_status(
772*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_cbr_buffer, i4_total_frame_bits,
773*495ae853SAndroid Build Coastguard Worker                         pi4_num_bits_to_prevent_vbv_underflow, e_pic_type);
774*495ae853SAndroid Build Coastguard Worker 
775*495ae853SAndroid Build Coastguard Worker     }
776*495ae853SAndroid Build Coastguard Worker     else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
777*495ae853SAndroid Build Coastguard Worker     {
778*495ae853SAndroid Build Coastguard Worker         /* For VBR_streaming, error bits are computed according to peak bitrate*/
779*495ae853SAndroid Build Coastguard Worker         e_buf_status = irc_get_cbr_buffer_status(
780*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_cbr_buffer, i4_total_frame_bits,
781*495ae853SAndroid Build Coastguard Worker                         pi4_num_bits_to_prevent_vbv_underflow, e_pic_type);
782*495ae853SAndroid Build Coastguard Worker     }
783*495ae853SAndroid Build Coastguard Worker     return e_buf_status;
784*495ae853SAndroid Build Coastguard Worker }
785*495ae853SAndroid Build Coastguard Worker 
786*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
787*495ae853SAndroid Build Coastguard Worker  Function Name : irc_update_pic_handling_state
788*495ae853SAndroid Build Coastguard Worker  Description   : If the forward path and the backward path of rate control
789*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_update_pic_handling_state(rate_control_api_t * ps_rate_control_api,picture_type_e e_pic_type)790*495ae853SAndroid Build Coastguard Worker void irc_update_pic_handling_state(rate_control_api_t *ps_rate_control_api,
791*495ae853SAndroid Build Coastguard Worker                                    picture_type_e e_pic_type)
792*495ae853SAndroid Build Coastguard Worker {
793*495ae853SAndroid Build Coastguard Worker     irc_update_pic_handling(ps_rate_control_api->ps_pic_handling, e_pic_type);
794*495ae853SAndroid Build Coastguard Worker }
795*495ae853SAndroid Build Coastguard Worker 
796*495ae853SAndroid Build Coastguard Worker /******************************************************************************
797*495ae853SAndroid Build Coastguard Worker  Function Name : irc_update_frame_level_info
798*495ae853SAndroid Build Coastguard Worker  Description   : Updates the frame level information into the rate control
799*495ae853SAndroid Build Coastguard Worker                  structure
800*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_update_frame_level_info(rate_control_api_t * ps_rate_control_api,picture_type_e e_pic_type,WORD32 * pi4_mb_type_sad,WORD32 i4_total_frame_bits,WORD32 i4_model_updation_hdr_bits,WORD32 * pi4_mb_type_tex_bits,WORD32 * pi4_tot_mb_type_qp,WORD32 * pi4_tot_mb_in_type,WORD32 i4_avg_activity,UWORD8 u1_is_scd,WORD32 i4_is_it_a_skip,WORD32 i4_intra_frm_cost,WORD32 i4_is_pic_handling_done)801*495ae853SAndroid Build Coastguard Worker void irc_update_frame_level_info(rate_control_api_t *ps_rate_control_api,
802*495ae853SAndroid Build Coastguard Worker                                  picture_type_e e_pic_type,
803*495ae853SAndroid Build Coastguard Worker                                  WORD32 *pi4_mb_type_sad,
804*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_total_frame_bits,
805*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_model_updation_hdr_bits,
806*495ae853SAndroid Build Coastguard Worker                                  WORD32 *pi4_mb_type_tex_bits,
807*495ae853SAndroid Build Coastguard Worker                                  WORD32 *pi4_tot_mb_type_qp,
808*495ae853SAndroid Build Coastguard Worker                                  WORD32 *pi4_tot_mb_in_type,
809*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_avg_activity,
810*495ae853SAndroid Build Coastguard Worker                                  UWORD8 u1_is_scd,
811*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_is_it_a_skip,
812*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_intra_frm_cost,
813*495ae853SAndroid Build Coastguard Worker                                  WORD32 i4_is_pic_handling_done)
814*495ae853SAndroid Build Coastguard Worker {
815*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_num_skips = 0;
816*495ae853SAndroid Build Coastguard Worker     WORD32 i;
817*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_frame_sad = 0;
818*495ae853SAndroid Build Coastguard Worker     WORD32 i4_tot_texture_bits = 0;
819*495ae853SAndroid Build Coastguard Worker     WORD32 i4_tot_mbs = 0;
820*495ae853SAndroid Build Coastguard Worker     WORD32 i4_avg_qp = 0;
821*495ae853SAndroid Build Coastguard Worker 
822*495ae853SAndroid Build Coastguard Worker     /* SCD not supported in case of IPB encoder */
823*495ae853SAndroid Build Coastguard Worker     if(u1_is_scd && (irc_pic_type_get_inter_frame_interval(
824*495ae853SAndroid Build Coastguard Worker                                     ps_rate_control_api->ps_pic_handling) > 1))
825*495ae853SAndroid Build Coastguard Worker     {
826*495ae853SAndroid Build Coastguard Worker         u1_is_scd = 0;
827*495ae853SAndroid Build Coastguard Worker     }
828*495ae853SAndroid Build Coastguard Worker 
829*495ae853SAndroid Build Coastguard Worker     /* For frames that contain plane areas that differ from reference frames, encoder
830*495ae853SAndroid Build Coastguard Worker      * might generate more INTRA MBs because of lower SAD compared with INTER MBs.
831*495ae853SAndroid Build Coastguard Worker      * Such cases should not be treated as scene change.
832*495ae853SAndroid Build Coastguard Worker      * For such frames bits consumed will be lesser than the allocated bits.
833*495ae853SAndroid Build Coastguard Worker      */
834*495ae853SAndroid Build Coastguard Worker     if(i4_total_frame_bits < ps_rate_control_api->i4_prev_frm_est_bits)
835*495ae853SAndroid Build Coastguard Worker     {
836*495ae853SAndroid Build Coastguard Worker         u1_is_scd = 0;
837*495ae853SAndroid Build Coastguard Worker     }
838*495ae853SAndroid Build Coastguard Worker     TRACE_PRINTF((const WORD8*)"i4_total_frame_bits %d\n", i4_total_frame_bits);
839*495ae853SAndroid Build Coastguard Worker 
840*495ae853SAndroid Build Coastguard Worker     if(!i4_is_it_a_skip && !i4_is_pic_handling_done)
841*495ae853SAndroid Build Coastguard Worker     {
842*495ae853SAndroid Build Coastguard Worker         /* Update the pic_handling struct */
843*495ae853SAndroid Build Coastguard Worker         irc_update_pic_handling(ps_rate_control_api->ps_pic_handling,
844*495ae853SAndroid Build Coastguard Worker                                 e_pic_type);
845*495ae853SAndroid Build Coastguard Worker     }
846*495ae853SAndroid Build Coastguard Worker 
847*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
848*495ae853SAndroid Build Coastguard Worker     {
849*495ae853SAndroid Build Coastguard Worker         if(!i4_is_it_a_skip)
850*495ae853SAndroid Build Coastguard Worker         {
851*495ae853SAndroid Build Coastguard Worker             WORD32 i4_new_period_flag;
852*495ae853SAndroid Build Coastguard Worker             /******************************************************************
853*495ae853SAndroid Build Coastguard Worker              Calculate the total values from the individual values
854*495ae853SAndroid Build Coastguard Worker              ******************************************************************/
855*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_MB_TYPE; i++)
856*495ae853SAndroid Build Coastguard Worker                 u4_frame_sad += pi4_mb_type_sad[i];
857*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_MB_TYPE; i++)
858*495ae853SAndroid Build Coastguard Worker                 i4_tot_texture_bits += pi4_mb_type_tex_bits[i];
859*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_MB_TYPE; i++)
860*495ae853SAndroid Build Coastguard Worker                 i4_avg_qp += pi4_tot_mb_type_qp[i];
861*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_MB_TYPE; i++)
862*495ae853SAndroid Build Coastguard Worker                 i4_tot_mbs += pi4_tot_mb_in_type[i];
863*495ae853SAndroid Build Coastguard Worker             i4_avg_qp /= i4_tot_mbs; /* Calculate the average QP */
864*495ae853SAndroid Build Coastguard Worker 
865*495ae853SAndroid Build Coastguard Worker             if(ps_rate_control_api->u1_is_mb_level_rc_on)
866*495ae853SAndroid Build Coastguard Worker             {
867*495ae853SAndroid Build Coastguard Worker                 /*
868*495ae853SAndroid Build Coastguard Worker                  * The model needs to take into consideration the average
869*495ae853SAndroid Build Coastguard Worker                  * activity of the entire frame while estimating the QP. Thus
870*495ae853SAndroid Build Coastguard Worker                  * the frame sad values are scaled by the average activity
871*495ae853SAndroid Build Coastguard Worker                  * before updating it into the model.
872*495ae853SAndroid Build Coastguard Worker                  */
873*495ae853SAndroid Build Coastguard Worker                 if(!i4_avg_activity)
874*495ae853SAndroid Build Coastguard Worker                     i4_avg_activity = 1;
875*495ae853SAndroid Build Coastguard Worker                 i4_intra_frm_cost *= i4_avg_activity;
876*495ae853SAndroid Build Coastguard Worker                 u4_frame_sad *= i4_avg_activity;
877*495ae853SAndroid Build Coastguard Worker             }
878*495ae853SAndroid Build Coastguard Worker 
879*495ae853SAndroid Build Coastguard Worker             /******************************************************************
880*495ae853SAndroid Build Coastguard Worker              Update the bit allocation module
881*495ae853SAndroid Build Coastguard Worker              NOTE: For bit allocation module, the pic_type should not be
882*495ae853SAndroid Build Coastguard Worker              modified to that of 'I', in case of a SCD.
883*495ae853SAndroid Build Coastguard Worker              ******************************************************************/
884*495ae853SAndroid Build Coastguard Worker             i4_new_period_flag = irc_is_last_frame_in_gop(
885*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_pic_handling);
886*495ae853SAndroid Build Coastguard Worker             irc_ba_update_cur_frm_consumed_bits(
887*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_bit_allocation,
888*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_pic_handling,
889*495ae853SAndroid Build Coastguard Worker                             i4_total_frame_bits, i4_model_updation_hdr_bits,
890*495ae853SAndroid Build Coastguard Worker                             e_pic_type, u1_is_scd, i4_new_period_flag);
891*495ae853SAndroid Build Coastguard Worker 
892*495ae853SAndroid Build Coastguard Worker             if(1 == i4_new_period_flag
893*495ae853SAndroid Build Coastguard Worker                             && ((ps_rate_control_api->e_rc_type == VBR_STORAGE)
894*495ae853SAndroid Build Coastguard Worker                                             || (ps_rate_control_api->e_rc_type
895*495ae853SAndroid Build Coastguard Worker                                                             == VBR_STORAGE_DVD_COMP)))
896*495ae853SAndroid Build Coastguard Worker             {
897*495ae853SAndroid Build Coastguard Worker                 irc_ba_check_and_update_bit_allocation(
898*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_bit_allocation,
899*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_pic_handling,
900*495ae853SAndroid Build Coastguard Worker                                 irc_get_cur_vbv_buf_size(
901*495ae853SAndroid Build Coastguard Worker                                                 ps_rate_control_api->ps_vbr_storage_vbv),
902*495ae853SAndroid Build Coastguard Worker                                 irc_get_max_vbv_buf_size(
903*495ae853SAndroid Build Coastguard Worker                                                 ps_rate_control_api->ps_vbr_storage_vbv),
904*495ae853SAndroid Build Coastguard Worker                                 irc_get_max_bits_per_tgt_frm(
905*495ae853SAndroid Build Coastguard Worker                                                 ps_rate_control_api->ps_vbr_storage_vbv),
906*495ae853SAndroid Build Coastguard Worker                                 i4_total_frame_bits);
907*495ae853SAndroid Build Coastguard Worker             }
908*495ae853SAndroid Build Coastguard Worker         }
909*495ae853SAndroid Build Coastguard Worker 
910*495ae853SAndroid Build Coastguard Worker         /**********************************************************************
911*495ae853SAndroid Build Coastguard Worker          Update the buffer status
912*495ae853SAndroid Build Coastguard Worker          *********************************************************************/
913*495ae853SAndroid Build Coastguard Worker         /*
914*495ae853SAndroid Build Coastguard Worker          * This update is done after overflow and underflow handling to
915*495ae853SAndroid Build Coastguard Worker          *  account for the actual bits dumped
916*495ae853SAndroid Build Coastguard Worker          */
917*495ae853SAndroid Build Coastguard Worker         if((ps_rate_control_api->e_rc_type == VBR_STORAGE)
918*495ae853SAndroid Build Coastguard Worker                         || (ps_rate_control_api->e_rc_type
919*495ae853SAndroid Build Coastguard Worker                                         == VBR_STORAGE_DVD_COMP))
920*495ae853SAndroid Build Coastguard Worker         {
921*495ae853SAndroid Build Coastguard Worker             irc_update_vbr_vbv(ps_rate_control_api->ps_vbr_storage_vbv,
922*495ae853SAndroid Build Coastguard Worker                                i4_total_frame_bits);
923*495ae853SAndroid Build Coastguard Worker         }
924*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
925*495ae853SAndroid Build Coastguard Worker         {
926*495ae853SAndroid Build Coastguard Worker             irc_update_cbr_buffer(ps_rate_control_api->ps_cbr_buffer,
927*495ae853SAndroid Build Coastguard Worker                                   i4_total_frame_bits, e_pic_type);
928*495ae853SAndroid Build Coastguard Worker         }
929*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
930*495ae853SAndroid Build Coastguard Worker         {
931*495ae853SAndroid Build Coastguard Worker             UWORD32 au4_num_pics_in_delay_prd[MAX_PIC_TYPE];
932*495ae853SAndroid Build Coastguard Worker 
933*495ae853SAndroid Build Coastguard Worker             irc_get_vsp_num_pics_in_dly_prd(
934*495ae853SAndroid Build Coastguard Worker                             &ps_rate_control_api->s_vbr_str_prms,
935*495ae853SAndroid Build Coastguard Worker                             au4_num_pics_in_delay_prd);
936*495ae853SAndroid Build Coastguard Worker 
937*495ae853SAndroid Build Coastguard Worker             irc_update_cbr_buffer(ps_rate_control_api->ps_cbr_buffer,
938*495ae853SAndroid Build Coastguard Worker                                   i4_total_frame_bits, e_pic_type);
939*495ae853SAndroid Build Coastguard Worker 
940*495ae853SAndroid Build Coastguard Worker             irc_update_vbr_str_prms(&ps_rate_control_api->s_vbr_str_prms,
941*495ae853SAndroid Build Coastguard Worker                                     e_pic_type);
942*495ae853SAndroid Build Coastguard Worker 
943*495ae853SAndroid Build Coastguard Worker             irc_change_cbr_vbv_num_pics_in_delay_period(
944*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_cbr_buffer,
945*495ae853SAndroid Build Coastguard Worker                             au4_num_pics_in_delay_prd);
946*495ae853SAndroid Build Coastguard Worker 
947*495ae853SAndroid Build Coastguard Worker             /*
948*495ae853SAndroid Build Coastguard Worker              * If the change_in_peak_bitrate flag is set, after the delay period
949*495ae853SAndroid Build Coastguard Worker              * update the peak_bitrate and the buffer parameters
950*495ae853SAndroid Build Coastguard Worker              */
951*495ae853SAndroid Build Coastguard Worker             if(!ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change)
952*495ae853SAndroid Build Coastguard Worker             {
953*495ae853SAndroid Build Coastguard Worker                 irc_ba_change_ba_peak_bit_rate(
954*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_bit_allocation,
955*495ae853SAndroid Build Coastguard Worker                                 (WORD32 *)&ps_rate_control_api->au4_new_peak_bit_rate[0]);
956*495ae853SAndroid Build Coastguard Worker                 irc_change_cbr_vbv_bit_rate(
957*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_cbr_buffer,
958*495ae853SAndroid Build Coastguard Worker                                 (WORD32 *)&ps_rate_control_api->au4_new_peak_bit_rate[0]);
959*495ae853SAndroid Build Coastguard Worker             }
960*495ae853SAndroid Build Coastguard Worker             if(ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change)
961*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change--;
962*495ae853SAndroid Build Coastguard Worker         }
963*495ae853SAndroid Build Coastguard Worker 
964*495ae853SAndroid Build Coastguard Worker         if(!i4_is_it_a_skip)
965*495ae853SAndroid Build Coastguard Worker         {
966*495ae853SAndroid Build Coastguard Worker             /*******************************************************************
967*495ae853SAndroid Build Coastguard Worker              Handle the SCENE CHANGE DETECTED
968*495ae853SAndroid Build Coastguard Worker              1) Make the picture type as I, so that updation happens as if it is
969*495ae853SAndroid Build Coastguard Worker                 an I frame
970*495ae853SAndroid Build Coastguard Worker              2) Reset model, SAD and flag to restart the estimation process
971*495ae853SAndroid Build Coastguard Worker              ******************************************************************/
972*495ae853SAndroid Build Coastguard Worker             if(u1_is_scd)
973*495ae853SAndroid Build Coastguard Worker             {
974*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_frm_qp_after_scd;
975*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_prev_I_frm_sad;
976*495ae853SAndroid Build Coastguard Worker 
977*495ae853SAndroid Build Coastguard Worker                 e_pic_type = I_PIC;
978*495ae853SAndroid Build Coastguard Worker 
979*495ae853SAndroid Build Coastguard Worker                 /* Scale scd qp based on SCD Frm sad and previous I Frm sad */
980*495ae853SAndroid Build Coastguard Worker                 /* frm_qp_after_scd = (avg_qp * cur_frm_sad)/prev_I_frm_sad */
981*495ae853SAndroid Build Coastguard Worker 
982*495ae853SAndroid Build Coastguard Worker                 /*
983*495ae853SAndroid Build Coastguard Worker                  * QP for the next frame should take care of
984*495ae853SAndroid Build Coastguard Worker                  * 1) due to scene change, the current picture has consumed more
985*495ae853SAndroid Build Coastguard Worker                  *      bits
986*495ae853SAndroid Build Coastguard Worker                  * 2) relative complexity of the previous scene and the current
987*495ae853SAndroid Build Coastguard Worker                  *     scene
988*495ae853SAndroid Build Coastguard Worker                  */
989*495ae853SAndroid Build Coastguard Worker 
990*495ae853SAndroid Build Coastguard Worker                 /* Get the intra SAD for the previous scene */
991*495ae853SAndroid Build Coastguard Worker                 u4_prev_I_frm_sad = irc_get_est_sad(
992*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_est_sad, I_PIC);
993*495ae853SAndroid Build Coastguard Worker 
994*495ae853SAndroid Build Coastguard Worker                 /*
995*495ae853SAndroid Build Coastguard Worker                  * Scale the QP based on the SAD ratio of the current pic and
996*495ae853SAndroid Build Coastguard Worker                  * previous scene intra SAD
997*495ae853SAndroid Build Coastguard Worker                  */
998*495ae853SAndroid Build Coastguard Worker                 X_PROD_Y_DIV_Z(i4_avg_qp, u4_frame_sad, u4_prev_I_frm_sad,
999*495ae853SAndroid Build Coastguard Worker                                i4_frm_qp_after_scd);
1000*495ae853SAndroid Build Coastguard Worker 
1001*495ae853SAndroid Build Coastguard Worker                 /* Limit the next frame qp by 50% across both the sides */
1002*495ae853SAndroid Build Coastguard Worker                 if(i4_frm_qp_after_scd > ((i4_avg_qp * 3) >> 1))
1003*495ae853SAndroid Build Coastguard Worker                 {
1004*495ae853SAndroid Build Coastguard Worker                     i4_frm_qp_after_scd = (i4_avg_qp * 3) >> 1;
1005*495ae853SAndroid Build Coastguard Worker                 }
1006*495ae853SAndroid Build Coastguard Worker                 else if(i4_frm_qp_after_scd < (i4_avg_qp >> 1))
1007*495ae853SAndroid Build Coastguard Worker                 {
1008*495ae853SAndroid Build Coastguard Worker                     i4_frm_qp_after_scd = (i4_avg_qp >> 1);
1009*495ae853SAndroid Build Coastguard Worker                 }
1010*495ae853SAndroid Build Coastguard Worker 
1011*495ae853SAndroid Build Coastguard Worker                 /*
1012*495ae853SAndroid Build Coastguard Worker                  * Ensure that the next frame QP is within the min_max limit of
1013*495ae853SAndroid Build Coastguard Worker                  * QP allowed
1014*495ae853SAndroid Build Coastguard Worker                  */
1015*495ae853SAndroid Build Coastguard Worker                 if(i4_frm_qp_after_scd
1016*495ae853SAndroid Build Coastguard Worker                                 > ps_rate_control_api->au1_min_max_qp[(e_pic_type
1017*495ae853SAndroid Build Coastguard Worker                                                 << 1) + 1])
1018*495ae853SAndroid Build Coastguard Worker                 {
1019*495ae853SAndroid Build Coastguard Worker                     i4_frm_qp_after_scd =
1020*495ae853SAndroid Build Coastguard Worker                                     ps_rate_control_api->au1_min_max_qp[(e_pic_type
1021*495ae853SAndroid Build Coastguard Worker                                                     << 1) + 1];
1022*495ae853SAndroid Build Coastguard Worker                 }
1023*495ae853SAndroid Build Coastguard Worker                 else if(i4_frm_qp_after_scd
1024*495ae853SAndroid Build Coastguard Worker                                 < ps_rate_control_api->au1_min_max_qp[(e_pic_type
1025*495ae853SAndroid Build Coastguard Worker                                                 << 1)])
1026*495ae853SAndroid Build Coastguard Worker                 {
1027*495ae853SAndroid Build Coastguard Worker                     i4_frm_qp_after_scd =
1028*495ae853SAndroid Build Coastguard Worker                                     ps_rate_control_api->au1_min_max_qp[(e_pic_type
1029*495ae853SAndroid Build Coastguard Worker                                                     << 1)];
1030*495ae853SAndroid Build Coastguard Worker                 }
1031*495ae853SAndroid Build Coastguard Worker 
1032*495ae853SAndroid Build Coastguard Worker                 /* Update the state var */
1033*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->u1_frm_qp_after_scd =
1034*495ae853SAndroid Build Coastguard Worker                                 (UWORD8)i4_frm_qp_after_scd;
1035*495ae853SAndroid Build Coastguard Worker 
1036*495ae853SAndroid Build Coastguard Worker                 /* re-set model */
1037*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < MAX_PIC_TYPE; i++)
1038*495ae853SAndroid Build Coastguard Worker                 {
1039*495ae853SAndroid Build Coastguard Worker                     irc_reset_frm_rc_rd_model(
1040*495ae853SAndroid Build Coastguard Worker                                     ps_rate_control_api->aps_rd_model[i]);
1041*495ae853SAndroid Build Coastguard Worker                 }
1042*495ae853SAndroid Build Coastguard Worker 
1043*495ae853SAndroid Build Coastguard Worker                 /* Reset the SAD estimation module */
1044*495ae853SAndroid Build Coastguard Worker                 irc_reset_est_sad(ps_rate_control_api->ps_est_sad);
1045*495ae853SAndroid Build Coastguard Worker 
1046*495ae853SAndroid Build Coastguard Worker                 /* Reset flag */
1047*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < MAX_PIC_TYPE; i++)
1048*495ae853SAndroid Build Coastguard Worker                 {
1049*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->au1_is_first_frm_coded[i] = 0;
1050*495ae853SAndroid Build Coastguard Worker                 }
1051*495ae853SAndroid Build Coastguard Worker 
1052*495ae853SAndroid Build Coastguard Worker                 /* Reset the MB Rate control */
1053*495ae853SAndroid Build Coastguard Worker                 irc_init_mb_level_rc(ps_rate_control_api->ps_mb_rate_control);
1054*495ae853SAndroid Build Coastguard Worker 
1055*495ae853SAndroid Build Coastguard Worker                 /*Set u1_scd_detected flag*/
1056*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->u1_scd_detected = 1;
1057*495ae853SAndroid Build Coastguard Worker 
1058*495ae853SAndroid Build Coastguard Worker                 /*
1059*495ae853SAndroid Build Coastguard Worker                  * Adjust the average QP for the frame based on bits
1060*495ae853SAndroid Build Coastguard Worker                  * consumption
1061*495ae853SAndroid Build Coastguard Worker                  */
1062*495ae853SAndroid Build Coastguard Worker                 /*
1063*495ae853SAndroid Build Coastguard Worker                  *  Initialize the QP for each picture type according to the
1064*495ae853SAndroid Build Coastguard Worker                  * average QP of the SCD pic
1065*495ae853SAndroid Build Coastguard Worker                  */
1066*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au1_prev_frm_qp[I_PIC] = (UWORD8)i4_avg_qp;
1067*495ae853SAndroid Build Coastguard Worker 
1068*495ae853SAndroid Build Coastguard Worker                 TRACE_PRINTF((const WORD8*)"SCD DETECTED\n");
1069*495ae853SAndroid Build Coastguard Worker             }
1070*495ae853SAndroid Build Coastguard Worker             else
1071*495ae853SAndroid Build Coastguard Worker             {
1072*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->u1_scd_detected = 0;
1073*495ae853SAndroid Build Coastguard Worker                 /**************************************************************
1074*495ae853SAndroid Build Coastguard Worker                  Update the Qp used by the current frame
1075*495ae853SAndroid Build Coastguard Worker                  **************************************************************/
1076*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au1_prev_frm_qp[e_pic_type] =
1077*495ae853SAndroid Build Coastguard Worker                                 (UWORD8)i4_avg_qp;
1078*495ae853SAndroid Build Coastguard Worker             }
1079*495ae853SAndroid Build Coastguard Worker 
1080*495ae853SAndroid Build Coastguard Worker             /********************************************************************
1081*495ae853SAndroid Build Coastguard Worker              Update the model of the correponding picture type
1082*495ae853SAndroid Build Coastguard Worker              NOTE: For SCD, we force the frame type from 'P' to that of a 'I'
1083*495ae853SAndroid Build Coastguard Worker              ******************************************************************/
1084*495ae853SAndroid Build Coastguard Worker             /*
1085*495ae853SAndroid Build Coastguard Worker              * For very simple sequences no bits are consumed by texture. These
1086*495ae853SAndroid Build Coastguard Worker              * frames do not add any information to the model and so not added
1087*495ae853SAndroid Build Coastguard Worker              */
1088*495ae853SAndroid Build Coastguard Worker             if(i4_tot_texture_bits && u4_frame_sad)
1089*495ae853SAndroid Build Coastguard Worker             {
1090*495ae853SAndroid Build Coastguard Worker                 irc_add_frame_to_rd_model(
1091*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->aps_rd_model[e_pic_type],
1092*495ae853SAndroid Build Coastguard Worker                                 i4_tot_texture_bits, (UWORD8)i4_avg_qp,
1093*495ae853SAndroid Build Coastguard Worker                                 u4_frame_sad, u1_num_skips);
1094*495ae853SAndroid Build Coastguard Worker 
1095*495ae853SAndroid Build Coastguard Worker                 /*
1096*495ae853SAndroid Build Coastguard Worker                  * At least one proper frame in added into the model. Until that
1097*495ae853SAndroid Build Coastguard Worker                  * keep using the initial QP
1098*495ae853SAndroid Build Coastguard Worker                  */
1099*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au1_is_first_frm_coded[e_pic_type] = 1;
1100*495ae853SAndroid Build Coastguard Worker             }
1101*495ae853SAndroid Build Coastguard Worker 
1102*495ae853SAndroid Build Coastguard Worker             if(i4_avg_activity)
1103*495ae853SAndroid Build Coastguard Worker             {
1104*495ae853SAndroid Build Coastguard Worker                 /* Update the mb_level model */
1105*495ae853SAndroid Build Coastguard Worker                 irc_mb_update_frame_level(
1106*495ae853SAndroid Build Coastguard Worker                                 ps_rate_control_api->ps_mb_rate_control,
1107*495ae853SAndroid Build Coastguard Worker                                 i4_avg_activity);
1108*495ae853SAndroid Build Coastguard Worker             }
1109*495ae853SAndroid Build Coastguard Worker 
1110*495ae853SAndroid Build Coastguard Worker             /******************************************************************
1111*495ae853SAndroid Build Coastguard Worker              Update the sad estimation module
1112*495ae853SAndroid Build Coastguard Worker              NOTE: For SCD, we force the frame type from 'P' to that of a 'I'
1113*495ae853SAndroid Build Coastguard Worker              ******************************************************************/
1114*495ae853SAndroid Build Coastguard Worker             if(u4_frame_sad)
1115*495ae853SAndroid Build Coastguard Worker             {
1116*495ae853SAndroid Build Coastguard Worker                 irc_update_actual_sad(ps_rate_control_api->ps_est_sad,
1117*495ae853SAndroid Build Coastguard Worker                                       u4_frame_sad, e_pic_type);
1118*495ae853SAndroid Build Coastguard Worker 
1119*495ae853SAndroid Build Coastguard Worker                 irc_update_actual_sad_for_intra(ps_rate_control_api->ps_est_sad,
1120*495ae853SAndroid Build Coastguard Worker                                                 i4_intra_frm_cost);
1121*495ae853SAndroid Build Coastguard Worker             }
1122*495ae853SAndroid Build Coastguard Worker 
1123*495ae853SAndroid Build Coastguard Worker             /*
1124*495ae853SAndroid Build Coastguard Worker              * Update the variable which denotes that a frame has been
1125*495ae853SAndroid Build Coastguard Worker              * encountered
1126*495ae853SAndroid Build Coastguard Worker              */
1127*495ae853SAndroid Build Coastguard Worker             ps_rate_control_api->u1_is_first_frm = 0;
1128*495ae853SAndroid Build Coastguard Worker 
1129*495ae853SAndroid Build Coastguard Worker         }
1130*495ae853SAndroid Build Coastguard Worker     }
1131*495ae853SAndroid Build Coastguard Worker 
1132*495ae853SAndroid Build Coastguard Worker     /* Store the prev encoded picture type for restricting Qp swing */
1133*495ae853SAndroid Build Coastguard Worker     if((e_pic_type == I_PIC) || (e_pic_type == P_PIC))
1134*495ae853SAndroid Build Coastguard Worker     {
1135*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->prev_ref_pic_type = e_pic_type;
1136*495ae853SAndroid Build Coastguard Worker     }
1137*495ae853SAndroid Build Coastguard Worker 
1138*495ae853SAndroid Build Coastguard Worker     TRACE_PRINTF((const WORD8*)"ft %d,hb %d,tb %d,qp %d,fs %d\n", e_pic_type,
1139*495ae853SAndroid Build Coastguard Worker                  i4_model_updation_hdr_bits, i4_tot_texture_bits, i4_avg_qp,
1140*495ae853SAndroid Build Coastguard Worker                  u4_frame_sad);
1141*495ae853SAndroid Build Coastguard Worker 
1142*495ae853SAndroid Build Coastguard Worker     return;
1143*495ae853SAndroid Build Coastguard Worker }
1144*495ae853SAndroid Build Coastguard Worker 
1145*495ae853SAndroid Build Coastguard Worker /*******************************************************************************
1146*495ae853SAndroid Build Coastguard Worker  MB Level API functions
1147*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
1148*495ae853SAndroid Build Coastguard Worker 
1149*495ae853SAndroid Build Coastguard Worker /******************************************************************************
1150*495ae853SAndroid Build Coastguard Worker  Function Name : irc_init_mb_rc_frame_level
1151*495ae853SAndroid Build Coastguard Worker  Description   : Initialise the frame level details required for a mb level
1152*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
1153*495ae853SAndroid Build Coastguard Worker 
irc_init_mb_rc_frame_level(rate_control_api_t * ps_rate_control_api,UWORD8 u1_frame_qp)1154*495ae853SAndroid Build Coastguard Worker void irc_init_mb_rc_frame_level(rate_control_api_t *ps_rate_control_api,
1155*495ae853SAndroid Build Coastguard Worker                                 UWORD8 u1_frame_qp)
1156*495ae853SAndroid Build Coastguard Worker {
1157*495ae853SAndroid Build Coastguard Worker     irc_mb_init_frame_level(ps_rate_control_api->ps_mb_rate_control,
1158*495ae853SAndroid Build Coastguard Worker                             u1_frame_qp);
1159*495ae853SAndroid Build Coastguard Worker }
1160*495ae853SAndroid Build Coastguard Worker 
1161*495ae853SAndroid Build Coastguard Worker /******************************************************************************
1162*495ae853SAndroid Build Coastguard Worker  Function Name : irc_get_mb_level_qp
1163*495ae853SAndroid Build Coastguard Worker  Description   : Get the mb level qp
1164*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_get_mb_level_qp(rate_control_api_t * ps_rate_control_api,WORD32 i4_cur_mb_activity,WORD32 * pi4_mb_qp,picture_type_e e_pic_type)1165*495ae853SAndroid Build Coastguard Worker void irc_get_mb_level_qp(rate_control_api_t *ps_rate_control_api,
1166*495ae853SAndroid Build Coastguard Worker                          WORD32 i4_cur_mb_activity,
1167*495ae853SAndroid Build Coastguard Worker                          WORD32 *pi4_mb_qp,
1168*495ae853SAndroid Build Coastguard Worker                          picture_type_e e_pic_type)
1169*495ae853SAndroid Build Coastguard Worker {
1170*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->u1_is_mb_level_rc_on)
1171*495ae853SAndroid Build Coastguard Worker     {
1172*495ae853SAndroid Build Coastguard Worker         irc_get_mb_qp(ps_rate_control_api->ps_mb_rate_control,
1173*495ae853SAndroid Build Coastguard Worker                       i4_cur_mb_activity, pi4_mb_qp);
1174*495ae853SAndroid Build Coastguard Worker 
1175*495ae853SAndroid Build Coastguard Worker         /* Truncating the QP to the Max and Min Qp values possible */
1176*495ae853SAndroid Build Coastguard Worker         if(pi4_mb_qp[1] < ps_rate_control_api->au1_min_max_qp[e_pic_type << 1])
1177*495ae853SAndroid Build Coastguard Worker         {
1178*495ae853SAndroid Build Coastguard Worker             pi4_mb_qp[1] = ps_rate_control_api->au1_min_max_qp[e_pic_type << 1];
1179*495ae853SAndroid Build Coastguard Worker         }
1180*495ae853SAndroid Build Coastguard Worker         if(pi4_mb_qp[1]
1181*495ae853SAndroid Build Coastguard Worker                         > ps_rate_control_api->au1_min_max_qp[(e_pic_type << 1)
1182*495ae853SAndroid Build Coastguard Worker                                         + 1])
1183*495ae853SAndroid Build Coastguard Worker         {
1184*495ae853SAndroid Build Coastguard Worker             pi4_mb_qp[1] = ps_rate_control_api->au1_min_max_qp[(e_pic_type << 1)
1185*495ae853SAndroid Build Coastguard Worker                             + 1];
1186*495ae853SAndroid Build Coastguard Worker         }
1187*495ae853SAndroid Build Coastguard Worker     }
1188*495ae853SAndroid Build Coastguard Worker     else
1189*495ae853SAndroid Build Coastguard Worker     {
1190*495ae853SAndroid Build Coastguard Worker         WORD32 i4_qp;
1191*495ae853SAndroid Build Coastguard Worker         i4_qp = irc_get_frm_level_qp(ps_rate_control_api->ps_mb_rate_control);
1192*495ae853SAndroid Build Coastguard Worker         /* Both the qp are used for */
1193*495ae853SAndroid Build Coastguard Worker         pi4_mb_qp[0] = i4_qp; /* Used as feedback for the rate control */
1194*495ae853SAndroid Build Coastguard Worker         pi4_mb_qp[1] = i4_qp; /* Used for quantising the MB*/
1195*495ae853SAndroid Build Coastguard Worker     }
1196*495ae853SAndroid Build Coastguard Worker }
1197*495ae853SAndroid Build Coastguard Worker 
1198*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1199*495ae853SAndroid Build Coastguard Worker  Function Name : irc_get_bits_to_stuff
1200*495ae853SAndroid Build Coastguard Worker  Description   : Gets the bits to stuff to prevent Underflow of Encoder Buffer
1201*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_get_bits_to_stuff(rate_control_api_t * ps_rate_control_api,WORD32 i4_tot_consumed_bits,picture_type_e e_pic_type)1202*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_bits_to_stuff(rate_control_api_t *ps_rate_control_api,
1203*495ae853SAndroid Build Coastguard Worker                              WORD32 i4_tot_consumed_bits,
1204*495ae853SAndroid Build Coastguard Worker                              picture_type_e e_pic_type)
1205*495ae853SAndroid Build Coastguard Worker {
1206*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bits_to_stuff;
1207*495ae853SAndroid Build Coastguard Worker     /* Get the CBR bits to stuff*/
1208*495ae853SAndroid Build Coastguard Worker     i4_bits_to_stuff = irc_get_cbr_bits_to_stuff(
1209*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_cbr_buffer, i4_tot_consumed_bits,
1210*495ae853SAndroid Build Coastguard Worker                     e_pic_type);
1211*495ae853SAndroid Build Coastguard Worker     return i4_bits_to_stuff;
1212*495ae853SAndroid Build Coastguard Worker }
1213*495ae853SAndroid Build Coastguard Worker 
1214*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1215*495ae853SAndroid Build Coastguard Worker  Function Name : irc_get_prev_frm_est_bits
1216*495ae853SAndroid Build Coastguard Worker  Description   : Returns previous frame estimated bits
1217*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_get_prev_frm_est_bits(rate_control_api_t * ps_rate_control_api)1218*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_prev_frm_est_bits(rate_control_api_t *ps_rate_control_api)
1219*495ae853SAndroid Build Coastguard Worker {
1220*495ae853SAndroid Build Coastguard Worker     return (ps_rate_control_api->i4_prev_frm_est_bits);
1221*495ae853SAndroid Build Coastguard Worker }
1222*495ae853SAndroid Build Coastguard Worker 
1223*495ae853SAndroid Build Coastguard Worker /******************************************************************************
1224*495ae853SAndroid Build Coastguard Worker  Control Level API functions
1225*495ae853SAndroid Build Coastguard Worker  Logic: The control call sets the state structure of the rate control api
1226*495ae853SAndroid Build Coastguard Worker          accordingly such that the next process call would implement the same.
1227*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
1228*495ae853SAndroid Build Coastguard Worker 
irc_change_inter_frm_int_call(rate_control_api_t * ps_rate_control_api,WORD32 i4_inter_frm_int)1229*495ae853SAndroid Build Coastguard Worker void irc_change_inter_frm_int_call(rate_control_api_t *ps_rate_control_api,
1230*495ae853SAndroid Build Coastguard Worker                                    WORD32 i4_inter_frm_int)
1231*495ae853SAndroid Build Coastguard Worker {
1232*495ae853SAndroid Build Coastguard Worker     irc_pic_handling_register_new_inter_frm_interval(
1233*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_pic_handling, i4_inter_frm_int);
1234*495ae853SAndroid Build Coastguard Worker }
1235*495ae853SAndroid Build Coastguard Worker 
irc_change_intra_frm_int_call(rate_control_api_t * ps_rate_control_api,WORD32 i4_intra_frm_int)1236*495ae853SAndroid Build Coastguard Worker void irc_change_intra_frm_int_call(rate_control_api_t *ps_rate_control_api,
1237*495ae853SAndroid Build Coastguard Worker                                    WORD32 i4_intra_frm_int)
1238*495ae853SAndroid Build Coastguard Worker {
1239*495ae853SAndroid Build Coastguard Worker     irc_pic_handling_register_new_int_frm_interval(
1240*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_pic_handling, i4_intra_frm_int);
1241*495ae853SAndroid Build Coastguard Worker 
1242*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
1243*495ae853SAndroid Build Coastguard Worker     {
1244*495ae853SAndroid Build Coastguard Worker         irc_change_vsp_ifi(&ps_rate_control_api->s_vbr_str_prms,
1245*495ae853SAndroid Build Coastguard Worker                            i4_intra_frm_int);
1246*495ae853SAndroid Build Coastguard Worker     }
1247*495ae853SAndroid Build Coastguard Worker }
1248*495ae853SAndroid Build Coastguard Worker 
1249*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1250*495ae853SAndroid Build Coastguard Worker  Function Name : irc_change_avg_bit_rate
1251*495ae853SAndroid Build Coastguard Worker  Description   : Whenever the average bit rate changes, the excess bits is
1252*495ae853SAndroid Build Coastguard Worker                  between the changed bit rate and the old one is re-distributed
1253*495ae853SAndroid Build Coastguard Worker                  in the bit allocation module
1254*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_change_avg_bit_rate(rate_control_api_t * ps_rate_control_api,UWORD32 u4_average_bit_rate)1255*495ae853SAndroid Build Coastguard Worker void irc_change_avg_bit_rate(rate_control_api_t *ps_rate_control_api,
1256*495ae853SAndroid Build Coastguard Worker                              UWORD32 u4_average_bit_rate)
1257*495ae853SAndroid Build Coastguard Worker {
1258*495ae853SAndroid Build Coastguard Worker     int i;
1259*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
1260*495ae853SAndroid Build Coastguard Worker     {
1261*495ae853SAndroid Build Coastguard Worker         /*
1262*495ae853SAndroid Build Coastguard Worker          * Bit Allocation Module: distribute the excess/deficit bits between the
1263*495ae853SAndroid Build Coastguard Worker          * old and the new frame rate to all the remaining frames
1264*495ae853SAndroid Build Coastguard Worker          */
1265*495ae853SAndroid Build Coastguard Worker         irc_ba_change_remaining_bits_in_period(
1266*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_bit_allocation,
1267*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_pic_handling,
1268*495ae853SAndroid Build Coastguard Worker                         u4_average_bit_rate,
1269*495ae853SAndroid Build Coastguard Worker                         irc_ba_get_frame_rate(
1270*495ae853SAndroid Build Coastguard Worker                                         ps_rate_control_api->ps_bit_allocation),
1271*495ae853SAndroid Build Coastguard Worker                         (WORD32 *)(ps_rate_control_api->au4_new_peak_bit_rate));
1272*495ae853SAndroid Build Coastguard Worker     }
1273*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
1274*495ae853SAndroid Build Coastguard Worker     {
1275*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_average_bit_rate_copy[MAX_NUM_DRAIN_RATES];
1276*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
1277*495ae853SAndroid Build Coastguard Worker         {
1278*495ae853SAndroid Build Coastguard Worker             u4_average_bit_rate_copy[i] = u4_average_bit_rate;
1279*495ae853SAndroid Build Coastguard Worker         }
1280*495ae853SAndroid Build Coastguard Worker         irc_change_cbr_vbv_bit_rate(ps_rate_control_api->ps_cbr_buffer,
1281*495ae853SAndroid Build Coastguard Worker                                     (WORD32 *)(u4_average_bit_rate_copy));
1282*495ae853SAndroid Build Coastguard Worker     }
1283*495ae853SAndroid Build Coastguard Worker 
1284*495ae853SAndroid Build Coastguard Worker     /*
1285*495ae853SAndroid Build Coastguard Worker      * This is done only for average bitrate changing somewhere after the model
1286*495ae853SAndroid Build Coastguard Worker      * stabilizes.Here it is assumed that user will not do this call after
1287*495ae853SAndroid Build Coastguard Worker      * first few frames. If we dont have this check, what would happen is since
1288*495ae853SAndroid Build Coastguard Worker      * the model has not stabilized, also bitrate has changed before the first
1289*495ae853SAndroid Build Coastguard Worker      * frame, we dont restrict the qp. Qp can go to very bad values after init
1290*495ae853SAndroid Build Coastguard Worker      * qp since if swing is disabled.
1291*495ae853SAndroid Build Coastguard Worker      * This check will become buggy if change bitrate is called say somewhere
1292*495ae853SAndroid Build Coastguard Worker      * after first two frames.Bottom line - RC init is done during create and
1293*495ae853SAndroid Build Coastguard Worker      * this call is done just before first process.And we want to differentiate
1294*495ae853SAndroid Build Coastguard Worker      * between this call done before first process and the call which is done
1295*495ae853SAndroid Build Coastguard Worker      * during run time
1296*495ae853SAndroid Build Coastguard Worker      */
1297*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->u1_is_first_frm == 0)
1298*495ae853SAndroid Build Coastguard Worker     {
1299*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < MAX_PIC_TYPE; i++)
1300*495ae853SAndroid Build Coastguard Worker         {
1301*495ae853SAndroid Build Coastguard Worker             ps_rate_control_api->au1_avg_bitrate_changed[i] = 1;
1302*495ae853SAndroid Build Coastguard Worker         }
1303*495ae853SAndroid Build Coastguard Worker     }
1304*495ae853SAndroid Build Coastguard Worker }
1305*495ae853SAndroid Build Coastguard Worker 
1306*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1307*495ae853SAndroid Build Coastguard Worker  Function Name : irc_change_frame_rate
1308*495ae853SAndroid Build Coastguard Worker  Description   : Does the necessary changes whenever there is a change in
1309*495ae853SAndroid Build Coastguard Worker                  frame rate
1310*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_change_frame_rate(rate_control_api_t * ps_rate_control_api,UWORD32 u4_frame_rate,UWORD32 u4_src_ticks,UWORD32 u4_tgt_ticks)1311*495ae853SAndroid Build Coastguard Worker void irc_change_frame_rate(rate_control_api_t *ps_rate_control_api,
1312*495ae853SAndroid Build Coastguard Worker                            UWORD32 u4_frame_rate,
1313*495ae853SAndroid Build Coastguard Worker                            UWORD32 u4_src_ticks,
1314*495ae853SAndroid Build Coastguard Worker                            UWORD32 u4_tgt_ticks)
1315*495ae853SAndroid Build Coastguard Worker {
1316*495ae853SAndroid Build Coastguard Worker 
1317*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
1318*495ae853SAndroid Build Coastguard Worker     {
1319*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_frms_in_delay_prd = ((u4_frame_rate
1320*495ae853SAndroid Build Coastguard Worker                         * irc_get_cbr_buffer_delay(
1321*495ae853SAndroid Build Coastguard Worker                                         ps_rate_control_api->ps_cbr_buffer))
1322*495ae853SAndroid Build Coastguard Worker                         / 1000000);
1323*495ae853SAndroid Build Coastguard Worker         if((ps_rate_control_api->e_rc_type == VBR_STORAGE)
1324*495ae853SAndroid Build Coastguard Worker                         || (ps_rate_control_api->e_rc_type
1325*495ae853SAndroid Build Coastguard Worker                                         == VBR_STORAGE_DVD_COMP))
1326*495ae853SAndroid Build Coastguard Worker         {
1327*495ae853SAndroid Build Coastguard Worker             irc_change_vbr_vbv_frame_rate(
1328*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_vbr_storage_vbv,
1329*495ae853SAndroid Build Coastguard Worker                             u4_frame_rate);
1330*495ae853SAndroid Build Coastguard Worker         }
1331*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
1332*495ae853SAndroid Build Coastguard Worker         {
1333*495ae853SAndroid Build Coastguard Worker             irc_change_cbr_vbv_tgt_frame_rate(
1334*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_cbr_buffer, u4_frame_rate);
1335*495ae853SAndroid Build Coastguard Worker         }
1336*495ae853SAndroid Build Coastguard Worker         else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
1337*495ae853SAndroid Build Coastguard Worker         {
1338*495ae853SAndroid Build Coastguard Worker             UWORD32 au4_num_pics_in_delay_prd[MAX_PIC_TYPE];
1339*495ae853SAndroid Build Coastguard Worker             irc_change_vsp_tgt_ticks(&ps_rate_control_api->s_vbr_str_prms,
1340*495ae853SAndroid Build Coastguard Worker                                      u4_tgt_ticks);
1341*495ae853SAndroid Build Coastguard Worker             irc_change_vsp_src_ticks(&ps_rate_control_api->s_vbr_str_prms,
1342*495ae853SAndroid Build Coastguard Worker                                      u4_src_ticks);
1343*495ae853SAndroid Build Coastguard Worker             irc_change_vsp_fidp(&ps_rate_control_api->s_vbr_str_prms,
1344*495ae853SAndroid Build Coastguard Worker                                 u4_frms_in_delay_prd);
1345*495ae853SAndroid Build Coastguard Worker 
1346*495ae853SAndroid Build Coastguard Worker             irc_get_vsp_num_pics_in_dly_prd(
1347*495ae853SAndroid Build Coastguard Worker                             &ps_rate_control_api->s_vbr_str_prms,
1348*495ae853SAndroid Build Coastguard Worker                             au4_num_pics_in_delay_prd);
1349*495ae853SAndroid Build Coastguard Worker             irc_change_cbr_vbv_tgt_frame_rate(
1350*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_cbr_buffer, u4_frame_rate);
1351*495ae853SAndroid Build Coastguard Worker             irc_change_cbr_vbv_num_pics_in_delay_period(
1352*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_cbr_buffer,
1353*495ae853SAndroid Build Coastguard Worker                             au4_num_pics_in_delay_prd);
1354*495ae853SAndroid Build Coastguard Worker         }
1355*495ae853SAndroid Build Coastguard Worker 
1356*495ae853SAndroid Build Coastguard Worker         /*
1357*495ae853SAndroid Build Coastguard Worker          * Bit Allocation Module: distribute the excess/deficit bits between the
1358*495ae853SAndroid Build Coastguard Worker          * old and the new frame rate to all the remaining frames
1359*495ae853SAndroid Build Coastguard Worker          */
1360*495ae853SAndroid Build Coastguard Worker         irc_ba_change_remaining_bits_in_period(
1361*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_bit_allocation,
1362*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_pic_handling,
1363*495ae853SAndroid Build Coastguard Worker                         irc_ba_get_bit_rate(
1364*495ae853SAndroid Build Coastguard Worker                                         ps_rate_control_api->ps_bit_allocation),
1365*495ae853SAndroid Build Coastguard Worker                         u4_frame_rate,
1366*495ae853SAndroid Build Coastguard Worker                         (WORD32 *)(ps_rate_control_api->au4_new_peak_bit_rate));
1367*495ae853SAndroid Build Coastguard Worker     }
1368*495ae853SAndroid Build Coastguard Worker }
1369*495ae853SAndroid Build Coastguard Worker 
1370*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1371*495ae853SAndroid Build Coastguard Worker  Function Name : irc_change_frm_rate_for_bit_alloc
1372*495ae853SAndroid Build Coastguard Worker  Description   : Does the necessary changes only in the bit_allocation module
1373*495ae853SAndroid Build Coastguard Worker                  there is a change in frame rate
1374*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_change_frm_rate_for_bit_alloc(rate_control_api_t * ps_rate_control_api,UWORD32 u4_frame_rate)1375*495ae853SAndroid Build Coastguard Worker void irc_change_frm_rate_for_bit_alloc(rate_control_api_t *ps_rate_control_api,
1376*495ae853SAndroid Build Coastguard Worker                                        UWORD32 u4_frame_rate)
1377*495ae853SAndroid Build Coastguard Worker {
1378*495ae853SAndroid Build Coastguard Worker 
1379*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type != CONST_QP)
1380*495ae853SAndroid Build Coastguard Worker     {
1381*495ae853SAndroid Build Coastguard Worker         /*
1382*495ae853SAndroid Build Coastguard Worker          * Bit Allocation Module: distribute the excess/deficit bits between the
1383*495ae853SAndroid Build Coastguard Worker          * old and the new frame rate to all the remaining frames
1384*495ae853SAndroid Build Coastguard Worker          */
1385*495ae853SAndroid Build Coastguard Worker         irc_ba_change_remaining_bits_in_period(
1386*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_bit_allocation,
1387*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_pic_handling,
1388*495ae853SAndroid Build Coastguard Worker                         irc_ba_get_bit_rate(
1389*495ae853SAndroid Build Coastguard Worker                                         ps_rate_control_api->ps_bit_allocation),
1390*495ae853SAndroid Build Coastguard Worker                         u4_frame_rate,
1391*495ae853SAndroid Build Coastguard Worker                         (WORD32 *)(ps_rate_control_api->au4_new_peak_bit_rate));
1392*495ae853SAndroid Build Coastguard Worker 
1393*495ae853SAndroid Build Coastguard Worker         if(ps_rate_control_api->e_rc_type == VBR_STORAGE
1394*495ae853SAndroid Build Coastguard Worker                         || ps_rate_control_api->e_rc_type
1395*495ae853SAndroid Build Coastguard Worker                                         == VBR_STORAGE_DVD_COMP)
1396*495ae853SAndroid Build Coastguard Worker         {
1397*495ae853SAndroid Build Coastguard Worker             irc_change_vbr_max_bits_per_tgt_frm(
1398*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_vbr_storage_vbv,
1399*495ae853SAndroid Build Coastguard Worker                             u4_frame_rate);
1400*495ae853SAndroid Build Coastguard Worker         }
1401*495ae853SAndroid Build Coastguard Worker     }
1402*495ae853SAndroid Build Coastguard Worker }
1403*495ae853SAndroid Build Coastguard Worker 
irc_change_init_qp(rate_control_api_t * ps_rate_control_api,UWORD8 * pu1_init_qp)1404*495ae853SAndroid Build Coastguard Worker void irc_change_init_qp(rate_control_api_t *ps_rate_control_api,
1405*495ae853SAndroid Build Coastguard Worker                         UWORD8 *pu1_init_qp)
1406*495ae853SAndroid Build Coastguard Worker {
1407*495ae853SAndroid Build Coastguard Worker     WORD32 i;
1408*495ae853SAndroid Build Coastguard Worker     /* Initialize the init_qp */
1409*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
1410*495ae853SAndroid Build Coastguard Worker     {
1411*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_init_qp[i] = pu1_init_qp[i];
1412*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_prev_frm_qp[i] = pu1_init_qp[i];
1413*495ae853SAndroid Build Coastguard Worker     }
1414*495ae853SAndroid Build Coastguard Worker }
1415*495ae853SAndroid Build Coastguard Worker 
irc_change_min_max_qp(rate_control_api_t * ps_rate_control_api,UWORD8 * pu1_min_max_qp)1416*495ae853SAndroid Build Coastguard Worker void irc_change_min_max_qp(rate_control_api_t *ps_rate_control_api,
1417*495ae853SAndroid Build Coastguard Worker                            UWORD8 *pu1_min_max_qp)
1418*495ae853SAndroid Build Coastguard Worker {
1419*495ae853SAndroid Build Coastguard Worker     WORD32 i;
1420*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_PIC_TYPE; i++)
1421*495ae853SAndroid Build Coastguard Worker     {
1422*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_min_max_qp[(i << 1)] =
1423*495ae853SAndroid Build Coastguard Worker                         pu1_min_max_qp[(i << 1)];
1424*495ae853SAndroid Build Coastguard Worker         ps_rate_control_api->au1_min_max_qp[(i << 1) + 1] = pu1_min_max_qp[(i
1425*495ae853SAndroid Build Coastguard Worker                         << 1) + 1];
1426*495ae853SAndroid Build Coastguard Worker     }
1427*495ae853SAndroid Build Coastguard Worker }
1428*495ae853SAndroid Build Coastguard Worker 
1429*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1430*495ae853SAndroid Build Coastguard Worker  Function Name : irc_change_peak_bit_rate
1431*495ae853SAndroid Build Coastguard Worker  Description   : Does the necessary changes whenever there is a change in
1432*495ae853SAndroid Build Coastguard Worker                  peak bit rate
1433*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_change_peak_bit_rate(rate_control_api_t * ps_rate_control_api,UWORD32 * pu4_peak_bit_rate)1434*495ae853SAndroid Build Coastguard Worker WORD32 irc_change_peak_bit_rate(rate_control_api_t *ps_rate_control_api,
1435*495ae853SAndroid Build Coastguard Worker                                 UWORD32 *pu4_peak_bit_rate)
1436*495ae853SAndroid Build Coastguard Worker {
1437*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ret_val = RC_OK;
1438*495ae853SAndroid Build Coastguard Worker     int i;
1439*495ae853SAndroid Build Coastguard Worker 
1440*495ae853SAndroid Build Coastguard Worker     /*
1441*495ae853SAndroid Build Coastguard Worker      * Buffer Mechanism Module: Re-initialize the number of bits consumed per
1442*495ae853SAndroid Build Coastguard Worker      * frame
1443*495ae853SAndroid Build Coastguard Worker      */
1444*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == VBR_STORAGE
1445*495ae853SAndroid Build Coastguard Worker                     || ps_rate_control_api->e_rc_type == VBR_STORAGE_DVD_COMP)
1446*495ae853SAndroid Build Coastguard Worker     {
1447*495ae853SAndroid Build Coastguard Worker         /* Send the new peak bit rate and the old frame rate */
1448*495ae853SAndroid Build Coastguard Worker         irc_change_vbr_vbv_bit_rate(ps_rate_control_api->ps_vbr_storage_vbv,
1449*495ae853SAndroid Build Coastguard Worker                                     pu4_peak_bit_rate[0]);
1450*495ae853SAndroid Build Coastguard Worker         irc_ba_change_ba_peak_bit_rate(ps_rate_control_api->ps_bit_allocation,
1451*495ae853SAndroid Build Coastguard Worker                                        (WORD32 *)pu4_peak_bit_rate);
1452*495ae853SAndroid Build Coastguard Worker 
1453*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
1454*495ae853SAndroid Build Coastguard Worker         {
1455*495ae853SAndroid Build Coastguard Worker             ps_rate_control_api->au4_new_peak_bit_rate[i] =
1456*495ae853SAndroid Build Coastguard Worker                             pu4_peak_bit_rate[i];
1457*495ae853SAndroid Build Coastguard Worker         }
1458*495ae853SAndroid Build Coastguard Worker     }
1459*495ae853SAndroid Build Coastguard Worker     else if(ps_rate_control_api->e_rc_type == VBR_STREAMING)
1460*495ae853SAndroid Build Coastguard Worker     {
1461*495ae853SAndroid Build Coastguard Worker         if(ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change)
1462*495ae853SAndroid Build Coastguard Worker         {
1463*495ae853SAndroid Build Coastguard Worker             /*
1464*495ae853SAndroid Build Coastguard Worker              * Means that change in peak bit rate has been made twice before the
1465*495ae853SAndroid Build Coastguard Worker              * previous change could take effect
1466*495ae853SAndroid Build Coastguard Worker              */
1467*495ae853SAndroid Build Coastguard Worker             i4_ret_val = RC_BENIGN_ERR;
1468*495ae853SAndroid Build Coastguard Worker         }
1469*495ae853SAndroid Build Coastguard Worker         /*
1470*495ae853SAndroid Build Coastguard Worker          * If the change happens before encoding the first frame make the
1471*495ae853SAndroid Build Coastguard Worker          * effect immediately else delay the effect
1472*495ae853SAndroid Build Coastguard Worker          */
1473*495ae853SAndroid Build Coastguard Worker         if(ps_rate_control_api->u1_is_first_frm)
1474*495ae853SAndroid Build Coastguard Worker         {
1475*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
1476*495ae853SAndroid Build Coastguard Worker             {
1477*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au4_new_peak_bit_rate[i] =
1478*495ae853SAndroid Build Coastguard Worker                                 pu4_peak_bit_rate[i];
1479*495ae853SAndroid Build Coastguard Worker             }
1480*495ae853SAndroid Build Coastguard Worker             irc_ba_change_ba_peak_bit_rate(
1481*495ae853SAndroid Build Coastguard Worker                             ps_rate_control_api->ps_bit_allocation,
1482*495ae853SAndroid Build Coastguard Worker                             (WORD32 *)pu4_peak_bit_rate);
1483*495ae853SAndroid Build Coastguard Worker             irc_change_cbr_vbv_bit_rate(ps_rate_control_api->ps_cbr_buffer,
1484*495ae853SAndroid Build Coastguard Worker                                         (WORD32 *)pu4_peak_bit_rate);
1485*495ae853SAndroid Build Coastguard Worker         }
1486*495ae853SAndroid Build Coastguard Worker         else
1487*495ae853SAndroid Build Coastguard Worker         {
1488*495ae853SAndroid Build Coastguard Worker             UWORD32 au4_num_pics_in_delay_prd[MAX_NUM_DRAIN_RATES];
1489*495ae853SAndroid Build Coastguard Worker             /*
1490*495ae853SAndroid Build Coastguard Worker              * Else store the number of frames after which the effect should
1491*495ae853SAndroid Build Coastguard Worker              * happen and then update the peak bitrate
1492*495ae853SAndroid Build Coastguard Worker              */
1493*495ae853SAndroid Build Coastguard Worker             ps_rate_control_api->u4_frms_in_delay_prd_for_peak_bit_rate_change =
1494*495ae853SAndroid Build Coastguard Worker                             irc_get_vsp_num_pics_in_dly_prd(
1495*495ae853SAndroid Build Coastguard Worker                                             &ps_rate_control_api->s_vbr_str_prms,
1496*495ae853SAndroid Build Coastguard Worker                                             au4_num_pics_in_delay_prd);
1497*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
1498*495ae853SAndroid Build Coastguard Worker             {
1499*495ae853SAndroid Build Coastguard Worker                 ps_rate_control_api->au4_new_peak_bit_rate[i] =
1500*495ae853SAndroid Build Coastguard Worker                                 pu4_peak_bit_rate[i];
1501*495ae853SAndroid Build Coastguard Worker             }
1502*495ae853SAndroid Build Coastguard Worker         }
1503*495ae853SAndroid Build Coastguard Worker     }
1504*495ae853SAndroid Build Coastguard Worker 
1505*495ae853SAndroid Build Coastguard Worker     return (i4_ret_val);
1506*495ae853SAndroid Build Coastguard Worker }
1507*495ae853SAndroid Build Coastguard Worker 
irc_change_buffer_delay(rate_control_api_t * ps_rate_control_api,UWORD32 u4_buffer_delay)1508*495ae853SAndroid Build Coastguard Worker void irc_change_buffer_delay(rate_control_api_t *ps_rate_control_api,
1509*495ae853SAndroid Build Coastguard Worker                              UWORD32 u4_buffer_delay)
1510*495ae853SAndroid Build Coastguard Worker {
1511*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_frms_in_delay_prd = ((irc_ba_get_frame_rate(
1512*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_bit_allocation) * u4_buffer_delay)
1513*495ae853SAndroid Build Coastguard Worker                     / 1000000);
1514*495ae853SAndroid Build Coastguard Worker 
1515*495ae853SAndroid Build Coastguard Worker     /* Initialize the rate control modules */
1516*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == CBR_NLDRC)
1517*495ae853SAndroid Build Coastguard Worker     {
1518*495ae853SAndroid Build Coastguard Worker         irc_change_cbr_buffer_delay(ps_rate_control_api->ps_cbr_buffer,
1519*495ae853SAndroid Build Coastguard Worker                                     u4_buffer_delay);
1520*495ae853SAndroid Build Coastguard Worker     }
1521*495ae853SAndroid Build Coastguard Worker     else if(ps_rate_control_api->e_rc_type == VBR_STORAGE
1522*495ae853SAndroid Build Coastguard Worker                     || ps_rate_control_api->e_rc_type == VBR_STORAGE_DVD_COMP)
1523*495ae853SAndroid Build Coastguard Worker     {
1524*495ae853SAndroid Build Coastguard Worker         UWORD32 au4_num_pics_in_delay_prd[MAX_PIC_TYPE];
1525*495ae853SAndroid Build Coastguard Worker 
1526*495ae853SAndroid Build Coastguard Worker         irc_change_vsp_fidp(&ps_rate_control_api->s_vbr_str_prms,
1527*495ae853SAndroid Build Coastguard Worker                             u4_frms_in_delay_prd);
1528*495ae853SAndroid Build Coastguard Worker 
1529*495ae853SAndroid Build Coastguard Worker         /* Get the number of pics of each type in delay period */
1530*495ae853SAndroid Build Coastguard Worker         irc_get_vsp_num_pics_in_dly_prd(&ps_rate_control_api->s_vbr_str_prms,
1531*495ae853SAndroid Build Coastguard Worker                                         au4_num_pics_in_delay_prd);
1532*495ae853SAndroid Build Coastguard Worker 
1533*495ae853SAndroid Build Coastguard Worker         irc_change_cbr_vbv_num_pics_in_delay_period(
1534*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_cbr_buffer,
1535*495ae853SAndroid Build Coastguard Worker                         au4_num_pics_in_delay_prd);
1536*495ae853SAndroid Build Coastguard Worker     }
1537*495ae853SAndroid Build Coastguard Worker }
1538*495ae853SAndroid Build Coastguard Worker 
1539*495ae853SAndroid Build Coastguard Worker /* Getter functions to get the current rate control parameters */
irc_get_frame_rate(rate_control_api_t * ps_rate_control_api)1540*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_frame_rate(rate_control_api_t *ps_rate_control_api)
1541*495ae853SAndroid Build Coastguard Worker {
1542*495ae853SAndroid Build Coastguard Worker     return (irc_ba_get_frame_rate(ps_rate_control_api->ps_bit_allocation));
1543*495ae853SAndroid Build Coastguard Worker }
1544*495ae853SAndroid Build Coastguard Worker 
irc_get_bit_rate(rate_control_api_t * ps_rate_control_api)1545*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_bit_rate(rate_control_api_t *ps_rate_control_api)
1546*495ae853SAndroid Build Coastguard Worker {
1547*495ae853SAndroid Build Coastguard Worker     return (irc_ba_get_bit_rate(ps_rate_control_api->ps_bit_allocation));
1548*495ae853SAndroid Build Coastguard Worker }
1549*495ae853SAndroid Build Coastguard Worker 
irc_get_peak_bit_rate(rate_control_api_t * ps_rate_control_api,WORD32 i4_index)1550*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_peak_bit_rate(rate_control_api_t *ps_rate_control_api,
1551*495ae853SAndroid Build Coastguard Worker                               WORD32 i4_index)
1552*495ae853SAndroid Build Coastguard Worker {
1553*495ae853SAndroid Build Coastguard Worker     return (ps_rate_control_api->au4_new_peak_bit_rate[i4_index]);
1554*495ae853SAndroid Build Coastguard Worker }
1555*495ae853SAndroid Build Coastguard Worker 
irc_get_intra_frame_interval(rate_control_api_t * ps_rate_control_api)1556*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_intra_frame_interval(rate_control_api_t *ps_rate_control_api)
1557*495ae853SAndroid Build Coastguard Worker {
1558*495ae853SAndroid Build Coastguard Worker     return (irc_pic_type_get_intra_frame_interval(
1559*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_pic_handling));
1560*495ae853SAndroid Build Coastguard Worker }
1561*495ae853SAndroid Build Coastguard Worker 
irc_get_inter_frame_interval(rate_control_api_t * ps_rate_control_api)1562*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_inter_frame_interval(rate_control_api_t *ps_rate_control_api)
1563*495ae853SAndroid Build Coastguard Worker {
1564*495ae853SAndroid Build Coastguard Worker     return (irc_pic_type_get_inter_frame_interval(
1565*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_pic_handling));
1566*495ae853SAndroid Build Coastguard Worker }
1567*495ae853SAndroid Build Coastguard Worker 
irc_get_rc_type(rate_control_api_t * ps_rate_control_api)1568*495ae853SAndroid Build Coastguard Worker rc_type_e irc_get_rc_type(rate_control_api_t *ps_rate_control_api)
1569*495ae853SAndroid Build Coastguard Worker {
1570*495ae853SAndroid Build Coastguard Worker     return (ps_rate_control_api->e_rc_type);
1571*495ae853SAndroid Build Coastguard Worker }
1572*495ae853SAndroid Build Coastguard Worker 
irc_get_bits_per_frame(rate_control_api_t * ps_rate_control_api)1573*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_bits_per_frame(rate_control_api_t *ps_rate_control_api)
1574*495ae853SAndroid Build Coastguard Worker {
1575*495ae853SAndroid Build Coastguard Worker     WORD32 i4_bits_per_frm;
1576*495ae853SAndroid Build Coastguard Worker 
1577*495ae853SAndroid Build Coastguard Worker     X_PROD_Y_DIV_Z(irc_ba_get_bit_rate(ps_rate_control_api->ps_bit_allocation),
1578*495ae853SAndroid Build Coastguard Worker                    (UWORD32)1000,
1579*495ae853SAndroid Build Coastguard Worker                    irc_ba_get_frame_rate(ps_rate_control_api->ps_bit_allocation),
1580*495ae853SAndroid Build Coastguard Worker                    i4_bits_per_frm);
1581*495ae853SAndroid Build Coastguard Worker 
1582*495ae853SAndroid Build Coastguard Worker     return (i4_bits_per_frm);
1583*495ae853SAndroid Build Coastguard Worker }
1584*495ae853SAndroid Build Coastguard Worker 
irc_get_max_delay(rate_control_api_t * ps_rate_control_api)1585*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_max_delay(rate_control_api_t *ps_rate_control_api)
1586*495ae853SAndroid Build Coastguard Worker {
1587*495ae853SAndroid Build Coastguard Worker     return (irc_get_cbr_buffer_delay(ps_rate_control_api->ps_cbr_buffer));
1588*495ae853SAndroid Build Coastguard Worker }
1589*495ae853SAndroid Build Coastguard Worker 
irc_get_seq_no(rate_control_api_t * ps_rate_control_api)1590*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_seq_no(rate_control_api_t *ps_rate_control_api)
1591*495ae853SAndroid Build Coastguard Worker {
1592*495ae853SAndroid Build Coastguard Worker     return (irc_pic_type_get_disp_order_no(ps_rate_control_api->ps_pic_handling));
1593*495ae853SAndroid Build Coastguard Worker }
1594*495ae853SAndroid Build Coastguard Worker 
irc_get_rem_frames_in_gop(rate_control_api_t * ps_rate_control_api)1595*495ae853SAndroid Build Coastguard Worker UWORD32 irc_get_rem_frames_in_gop(rate_control_api_t *ps_rate_control_api)
1596*495ae853SAndroid Build Coastguard Worker {
1597*495ae853SAndroid Build Coastguard Worker     WORD32 ai4_rem_frms_in_period[MAX_PIC_TYPE];
1598*495ae853SAndroid Build Coastguard Worker     WORD32 j;
1599*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_rem_frms_in_period = 0;
1600*495ae853SAndroid Build Coastguard Worker 
1601*495ae853SAndroid Build Coastguard Worker     /* Get the rem_frms_in_gop & the frms_in_gop from the pic_type state struct */
1602*495ae853SAndroid Build Coastguard Worker     irc_pic_type_get_rem_frms_in_gop(ps_rate_control_api->ps_pic_handling,
1603*495ae853SAndroid Build Coastguard Worker                                      ai4_rem_frms_in_period);
1604*495ae853SAndroid Build Coastguard Worker 
1605*495ae853SAndroid Build Coastguard Worker     /* Depending on the number of gops in a period, find the num_frms_in_prd */
1606*495ae853SAndroid Build Coastguard Worker     for(j = 0; j < MAX_PIC_TYPE; j++)
1607*495ae853SAndroid Build Coastguard Worker     {
1608*495ae853SAndroid Build Coastguard Worker         u4_rem_frms_in_period += ai4_rem_frms_in_period[j];
1609*495ae853SAndroid Build Coastguard Worker     }
1610*495ae853SAndroid Build Coastguard Worker 
1611*495ae853SAndroid Build Coastguard Worker     return (u4_rem_frms_in_period);
1612*495ae853SAndroid Build Coastguard Worker }
1613*495ae853SAndroid Build Coastguard Worker 
1614*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1615*495ae853SAndroid Build Coastguard Worker  Function Name : irc_flush_buf_frames
1616*495ae853SAndroid Build Coastguard Worker  Description   : API call to flush the buffered up frames
1617*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_flush_buf_frames(rate_control_api_t * ps_rate_control_api)1618*495ae853SAndroid Build Coastguard Worker void irc_flush_buf_frames(rate_control_api_t *ps_rate_control_api)
1619*495ae853SAndroid Build Coastguard Worker {
1620*495ae853SAndroid Build Coastguard Worker     irc_flush_frame_from_pic_stack(ps_rate_control_api->ps_pic_handling);
1621*495ae853SAndroid Build Coastguard Worker }
1622*495ae853SAndroid Build Coastguard Worker 
1623*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1624*495ae853SAndroid Build Coastguard Worker  Function Name : irc_flush_buf_frames
1625*495ae853SAndroid Build Coastguard Worker  Description   : API call to flush the buffered up frames
1626*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
1627*495ae853SAndroid Build Coastguard Worker 
irc_post_encode_frame_skip(rate_control_api_t * ps_rate_control_api,picture_type_e e_pic_type)1628*495ae853SAndroid Build Coastguard Worker void irc_post_encode_frame_skip(rate_control_api_t *ps_rate_control_api,
1629*495ae853SAndroid Build Coastguard Worker                                 picture_type_e e_pic_type)
1630*495ae853SAndroid Build Coastguard Worker {
1631*495ae853SAndroid Build Coastguard Worker     irc_skip_encoded_frame(ps_rate_control_api->ps_pic_handling, e_pic_type);
1632*495ae853SAndroid Build Coastguard Worker }
1633*495ae853SAndroid Build Coastguard Worker 
1634*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1635*495ae853SAndroid Build Coastguard Worker  Function Name : irc_force_I_frame
1636*495ae853SAndroid Build Coastguard Worker  Description   : API call to force an I frame
1637*495ae853SAndroid Build Coastguard Worker  *****************************************************************************/
irc_force_I_frame(rate_control_api_t * ps_rate_control_api)1638*495ae853SAndroid Build Coastguard Worker void irc_force_I_frame(rate_control_api_t *ps_rate_control_api)
1639*495ae853SAndroid Build Coastguard Worker {
1640*495ae853SAndroid Build Coastguard Worker     irc_set_force_I_frame_flag(ps_rate_control_api->ps_pic_handling);
1641*495ae853SAndroid Build Coastguard Worker }
1642*495ae853SAndroid Build Coastguard Worker 
1643*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1644*495ae853SAndroid Build Coastguard Worker  * Function Name : rc_get_rem_bits_in_gop
1645*495ae853SAndroid Build Coastguard Worker  * Description   : API call to get remaining bits in GOP
1646*495ae853SAndroid Build Coastguard Worker  * *****************************************************************************/
irc_get_rem_bits_in_period(rate_control_api_t * ps_rate_control_api)1647*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_rem_bits_in_period(rate_control_api_t *ps_rate_control_api)
1648*495ae853SAndroid Build Coastguard Worker {
1649*495ae853SAndroid Build Coastguard Worker     return (irc_ba_get_rem_bits_in_period(
1650*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_bit_allocation,
1651*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_pic_handling));
1652*495ae853SAndroid Build Coastguard Worker }
1653*495ae853SAndroid Build Coastguard Worker 
1654*495ae853SAndroid Build Coastguard Worker /****************************************************************************
1655*495ae853SAndroid Build Coastguard Worker  * Function Name : irc_get_vbv_buf_fullness
1656*495ae853SAndroid Build Coastguard Worker  * Description   : API call to get VBV buffer fullness
1657*495ae853SAndroid Build Coastguard Worker  ******************************************************************************/
irc_get_vbv_buf_fullness(rate_control_api_t * ps_rate_control_api)1658*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_vbv_buf_fullness(rate_control_api_t *ps_rate_control_api)
1659*495ae853SAndroid Build Coastguard Worker {
1660*495ae853SAndroid Build Coastguard Worker     return (irc_get_cur_vbv_buf_size(ps_rate_control_api->ps_vbr_storage_vbv));
1661*495ae853SAndroid Build Coastguard Worker }
1662*495ae853SAndroid Build Coastguard Worker 
irc_get_vbv_buf_size(rate_control_api_t * ps_rate_control_api)1663*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_vbv_buf_size(rate_control_api_t *ps_rate_control_api)
1664*495ae853SAndroid Build Coastguard Worker {
1665*495ae853SAndroid Build Coastguard Worker     if(ps_rate_control_api->e_rc_type == CBR_NLDRC
1666*495ae853SAndroid Build Coastguard Worker                     || ps_rate_control_api->e_rc_type == VBR_STREAMING)
1667*495ae853SAndroid Build Coastguard Worker     {
1668*495ae853SAndroid Build Coastguard Worker         return (irc_get_cbr_buffer_size(ps_rate_control_api->ps_cbr_buffer));
1669*495ae853SAndroid Build Coastguard Worker     }
1670*495ae853SAndroid Build Coastguard Worker     else
1671*495ae853SAndroid Build Coastguard Worker     {
1672*495ae853SAndroid Build Coastguard Worker         return (irc_get_max_vbv_buf_size(
1673*495ae853SAndroid Build Coastguard Worker                         ps_rate_control_api->ps_vbr_storage_vbv));
1674*495ae853SAndroid Build Coastguard Worker     }
1675*495ae853SAndroid Build Coastguard Worker }
1676*495ae853SAndroid Build Coastguard Worker 
irc_get_vbv_fulness_with_cur_bits(rate_control_api_t * ps_rate_control_api,UWORD32 u4_bits)1677*495ae853SAndroid Build Coastguard Worker WORD32 irc_get_vbv_fulness_with_cur_bits(rate_control_api_t *ps_rate_control_api,
1678*495ae853SAndroid Build Coastguard Worker                                          UWORD32 u4_bits)
1679*495ae853SAndroid Build Coastguard Worker {
1680*495ae853SAndroid Build Coastguard Worker     return (irc_vbv_get_vbv_buf_fullness(
1681*495ae853SAndroid Build Coastguard Worker                     ps_rate_control_api->ps_vbr_storage_vbv, u4_bits));
1682*495ae853SAndroid Build Coastguard Worker }
1683*495ae853SAndroid Build Coastguard Worker 
irc_set_avg_mb_act(rate_control_api_t * ps_rate_control_api,WORD32 i4_avg_activity)1684*495ae853SAndroid Build Coastguard Worker void irc_set_avg_mb_act(rate_control_api_t *ps_rate_control_api,
1685*495ae853SAndroid Build Coastguard Worker                         WORD32 i4_avg_activity)
1686*495ae853SAndroid Build Coastguard Worker {
1687*495ae853SAndroid Build Coastguard Worker     irc_mb_update_frame_level(ps_rate_control_api->ps_mb_rate_control,
1688*495ae853SAndroid Build Coastguard Worker                               i4_avg_activity);
1689*495ae853SAndroid Build Coastguard Worker     return;
1690*495ae853SAndroid Build Coastguard Worker }
1691