• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*!
21 ******************************************************************************
22 * \file cbr_buffer_control.c
23 *
24 * \brief
25 *    This file contains all functions needed for cbr buffer control
26 * \date
27 * 06/05/2008
28 *
29 * \author
30 *    ittiam
31 *
32 *  \List of Functions
33 *                      init_cbr_buffer
34 *                      cbr_buffer_constraint_check
35 *                      get_cbr_buffer_status
36 *                      update_cbr_buffer
37 *
38 ******************************************************************************
39 */
40 /*****************************************************************************/
41 /* File Includes                                                             */
42 /*****************************************************************************/
43 
44 /* System include files */
45 #include <stdio.h>
46 
47 /* User include files */
48 #include "assert.h"
49 #include "ittiam_datatypes.h"
50 #include "rc_cntrl_param.h"
51 #include "rc_common.h"
52 #include "mem_req_and_acq.h"
53 #include "fixed_point_error_bits.h"
54 #include "cbr_buffer_control.h"
55 #include "trace_support.h"
56 #include "var_q_operator.h"
57 
58 #define MIN(x, y) ((x) < (y)) ? (x) : (y)
59 /*allow a maximum of 20 percent deviation when input is very large*/
60 #define VBR_MAX_BIT_DEV_SEC 50LL
61 
62 typedef struct cbr_buffer_t
63 {
64     WORD32 i4_buffer_size; /* Buffer size = Delay * Bitrate*/
65     WORD32
66     i4_drain_bits_per_frame[MAX_NUM_DRAIN_RATES]; /* Constant drain rate */
67     WORD32 i4_ebf; /* Encoder Buffer Fullness */
68     LWORD64
69     i8_ebf_bit_alloc; /* current encoder buffer fulness that accounts precise bit consumption (not truncated to max buffer size at skip)*/
70     LWORD64 i8_credit_level;
71     WORD32 i4_upr_thr[MAX_PIC_TYPE]; /* Upper threshold of the Buffer */
72     WORD32 i4_low_thr[MAX_PIC_TYPE]; /* Lower threshold of the Buffer */
73     error_bits_handle
74         aps_bpf_error_bits[MAX_NUM_DRAIN_RATES]; /* For error due to bits per frame calculation */
75     WORD32
76     i4_is_cbr_mode; /* Whether the buffer model is used for CBR or VBR streaming */
77     /* Input parameters stored for initialisation */
78     WORD32 ai4_bit_rate[MAX_NUM_DRAIN_RATES];
79     WORD32 i4_max_delay;
80     WORD32 ai4_num_pics_in_delay_period[MAX_PIC_TYPE];
81     WORD32 i4_tgt_frm_rate;
82     UWORD32 u4_max_vbv_buf_size;
83     WORD32 i4_peak_drain_rate_frame;
84     WORD32 u4_num_frms_in_delay;
85     UWORD32 u4_vbr_max_bit_deviation;
86     rc_type_e e_rc_type;
87     WORD32 i4_vbr_no_peak_rate_duration_limit;
88     LWORD64 i8_tot_frm_to_be_encoded;
89     LWORD64
90     i8_num_frames_encoded; /*need to track the number of frames encoded to calculate possible deviaiton allowed*/
91     WORD32 i4_cbr_rc_pass;
92     WORD32 i4_inter_frame_int;
93     WORD32 i4_intra_frame_int;
94     WORD32 i4_capped_vbr_on;
95     float f_max_dur_peak_rate;
96     LWORD64 i4_ebf_estimate;
97 } cbr_buffer_t;
98 
99 #if NON_STEADSTATE_CODE
cbr_buffer_num_fill_use_free_memtab(cbr_buffer_t ** pps_cbr_buffer,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)100 WORD32 cbr_buffer_num_fill_use_free_memtab(
101     cbr_buffer_t **pps_cbr_buffer, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
102 {
103     WORD32 i4_mem_tab_idx = 0, i;
104     static cbr_buffer_t s_cbr_buffer_temp;
105 
106     /* Hack for al alloc, during which we dont have any state memory.
107       Dereferencing can cause issues */
108     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
109         (*pps_cbr_buffer) = &s_cbr_buffer_temp;
110 
111     if(e_func_type != GET_NUM_MEMTAB)
112     {
113         fill_memtab(
114             &ps_memtab[i4_mem_tab_idx], sizeof(cbr_buffer_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
115         use_or_fill_base(&ps_memtab[0], (void **)pps_cbr_buffer, e_func_type);
116     }
117     i4_mem_tab_idx++;
118 
119     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
120     {
121         i4_mem_tab_idx += error_bits_num_fill_use_free_memtab(
122             &pps_cbr_buffer[0]->aps_bpf_error_bits[i], &ps_memtab[i4_mem_tab_idx], e_func_type);
123     }
124     return (i4_mem_tab_idx);
125 }
set_upper_lower_vbv_threshold(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_bits_per_frm)126 static void set_upper_lower_vbv_threshold(cbr_buffer_t *ps_cbr_buffer, WORD32 i4_bits_per_frm)
127 {
128     WORD32 i;
129     for(i = 0; i < MAX_PIC_TYPE; i++)
130     {
131         ps_cbr_buffer->i4_upr_thr[i] =
132             (WORD32)(((LWORD64)ps_cbr_buffer->i4_buffer_size >> 4) * UPPER_THRESHOLD_EBF_Q4);
133         if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
134         {
135             /*lower threshold can be zero as there is no problem of studffing in this mode (VBR STORAGE)*/
136             if(ps_cbr_buffer->i4_vbr_no_peak_rate_duration_limit)
137                 ps_cbr_buffer->i4_low_thr[i] = 0;
138             else
139                 ps_cbr_buffer->i4_low_thr[i] = ps_cbr_buffer->i4_inter_frame_int * i4_bits_per_frm;
140         }
141         else
142         {
143             if(ps_cbr_buffer->i4_inter_frame_int == 1)
144                 ps_cbr_buffer->i4_low_thr[i] = 0;
145             else
146             {
147                 ps_cbr_buffer->i4_low_thr[i] = ps_cbr_buffer->i4_inter_frame_int * i4_bits_per_frm;
148             }
149         }
150         /*For huge buffer low limit can be higher*/
151 
152         if(ps_cbr_buffer->i4_low_thr[i] < (ps_cbr_buffer->i4_buffer_size >> 6))
153             ps_cbr_buffer->i4_low_thr[i] = (ps_cbr_buffer->i4_buffer_size >> 6);
154 
155         if(ps_cbr_buffer->i4_low_thr[i] > (ps_cbr_buffer->i4_buffer_size >> 3))  //KISH_DEBUG
156             ps_cbr_buffer->i4_low_thr[i] = (ps_cbr_buffer->i4_buffer_size >> 3);
157         ASSERT(ps_cbr_buffer->i4_upr_thr[i] > ps_cbr_buffer->i4_low_thr[i]);
158     }
159 }
160 /* ******************************************************************************/
161 /**
162  * @brief Initialise the CBR VBV buffer state.
163  * This could however be used for VBR streaming VBV also
164  *
165  * @param ps_cbr_buffer
166  * @param i4_buffer_delay
167  * @param i4_tgt_frm_rate
168  * @param i4_bit_rate
169  * @param u4_num_pics_in_delay_prd
170  * @param u4_vbv_buf_size
171  */
172 /* ******************************************************************************/
init_cbr_buffer(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_buffer_delay,WORD32 i4_tgt_frm_rate,UWORD32 u4_bit_rate,UWORD32 * u4_num_pics_in_delay_prd,UWORD32 u4_vbv_buf_size,UWORD32 u4_intra_frm_int,rc_type_e e_rc_type,UWORD32 u4_peak_bit_rate,UWORD32 u4_num_frames_in_delay,float f_max_dur_peak_rate,LWORD64 i8_num_frames_to_encode,WORD32 i4_inter_frm_int,WORD32 i4_cbr_rc_pass,WORD32 i4_capped_vbr_flag)173 void init_cbr_buffer(
174     cbr_buffer_t *ps_cbr_buffer,
175     WORD32 i4_buffer_delay,
176     WORD32 i4_tgt_frm_rate,
177     UWORD32 u4_bit_rate,
178     UWORD32 *u4_num_pics_in_delay_prd,
179     UWORD32 u4_vbv_buf_size,
180     UWORD32 u4_intra_frm_int,
181     rc_type_e e_rc_type,
182     UWORD32 u4_peak_bit_rate,
183     UWORD32 u4_num_frames_in_delay,
184     float f_max_dur_peak_rate,
185     LWORD64 i8_num_frames_to_encode,
186     WORD32 i4_inter_frm_int,
187     WORD32 i4_cbr_rc_pass,
188     WORD32 i4_capped_vbr_flag)
189 
190 {
191     WORD32 i4_bits_per_frm[MAX_NUM_DRAIN_RATES];
192     int i;
193 
194     /* Initially Encoder buffer fullness is zero */
195     ps_cbr_buffer->i4_ebf = 0;
196     ps_cbr_buffer->i4_ebf_estimate = 0;
197     ps_cbr_buffer->i8_ebf_bit_alloc = 0;
198     ps_cbr_buffer->i8_credit_level = 0;
199     ps_cbr_buffer->e_rc_type = e_rc_type;
200     ps_cbr_buffer->i4_capped_vbr_on = i4_capped_vbr_flag;
201     /*If this is set to 1, it acts similar to storage VBR which allows peak rate to be sustained for infinite duration*/
202     ps_cbr_buffer->i4_vbr_no_peak_rate_duration_limit = 0;
203     ps_cbr_buffer->i8_num_frames_encoded = 0;
204     ps_cbr_buffer->i8_tot_frm_to_be_encoded = i8_num_frames_to_encode;
205     ps_cbr_buffer->i4_cbr_rc_pass = i4_cbr_rc_pass;
206     ps_cbr_buffer->i4_inter_frame_int = i4_inter_frm_int;
207     ps_cbr_buffer->i4_intra_frame_int = u4_intra_frm_int;
208     ps_cbr_buffer->f_max_dur_peak_rate = f_max_dur_peak_rate;
209 
210     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
211     {
212         X_PROD_Y_DIV_Z(u4_bit_rate, 1000, i4_tgt_frm_rate, i4_bits_per_frm[i]);
213         /* Drain rate = bitrate/(framerate/1000) */
214         ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i];
215         /* initialise the bits per frame error bits calculation */
216         init_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], i4_tgt_frm_rate, u4_bit_rate);
217     }
218 
219     /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/
220     if(e_rc_type == CBR_NLDRC) /* This would mean CBR mode */
221     {
222         //buffer size should be independent of initial delay
223         //X_PROD_Y_DIV_Z(u4_bit_rate,i4_buffer_delay,1000,ps_cbr_buffer->i4_buffer_size);
224         ps_cbr_buffer->i4_buffer_size = (WORD32)u4_vbv_buf_size;
225         ps_cbr_buffer->i4_is_cbr_mode = 1;
226         ps_cbr_buffer->i4_peak_drain_rate_frame = i4_bits_per_frm[0];
227         /*In CBR the max file size deviaiton allowed is specified by buffer size*/
228         ps_cbr_buffer->u4_vbr_max_bit_deviation = ps_cbr_buffer->i4_buffer_size;
229     }
230     else if(e_rc_type == VBR_STREAMING)
231     {
232         /*this is raw vbv buffer size, also initilize the buffer window to bit alloc (credit limit)*/
233         ps_cbr_buffer->i4_buffer_size = (WORD32)u4_vbv_buf_size;
234         /*if there is no limit on duration for which peak bitrate can be sustained, bits can be moved from any region to other region
235           giving better quality*/
236         if(f_max_dur_peak_rate < 0)
237             ps_cbr_buffer->i4_vbr_no_peak_rate_duration_limit = 1;
238         /*To avoid file size deviation in case of VBR mode of rate control, clip the max deviaiton allowed based on number of frames to enode*/
239         {
240             ULWORD64 u8_vbr_max_bit_deviation;
241             ULWORD64 file_size = (ULWORD64)(
242                 (((LWORD64)u4_bit_rate * 1000) / i4_tgt_frm_rate) * i8_num_frames_to_encode);
243 
244             /*When f_max_dur_peak_rate is -ve, it implies user is not worried about duration for which peak is sustained, hence go with max possible value*/
245             if(f_max_dur_peak_rate > 0)
246                 u8_vbr_max_bit_deviation = (ULWORD64)(f_max_dur_peak_rate * u4_bit_rate);
247             else
248                 u8_vbr_max_bit_deviation = (ULWORD64)(VBR_MAX_BIT_DEV_SEC * u4_bit_rate);
249 
250             /*when num frames to encode is negative is -ve it implies total frames data is not available (as in case of live encoding)*/
251             if(i8_num_frames_to_encode > 0)
252             {
253                 /*allow atleast one second deviation or 12% of total file size whichever is higher*/
254                 if(u8_vbr_max_bit_deviation > (file_size >> 3))
255                     u8_vbr_max_bit_deviation = (UWORD32)(file_size >> 3);
256 
257                 /*allow atleast one second for shorter sequence*/
258                 if(u8_vbr_max_bit_deviation < u4_bit_rate)
259                     u8_vbr_max_bit_deviation = u4_bit_rate;
260             }
261             else
262             {
263                 /*the data of number of frames to be encoded is not available*/
264                 /*start off with one second delay, this will be later adjusted once large number of frames are encoded*/
265                 u8_vbr_max_bit_deviation = u4_bit_rate;
266             }
267             ps_cbr_buffer->u4_vbr_max_bit_deviation = u8_vbr_max_bit_deviation;
268         }
269         ps_cbr_buffer->i4_is_cbr_mode = 0;
270         X_PROD_Y_DIV_Z(
271             u4_peak_bit_rate, 1000, i4_tgt_frm_rate, ps_cbr_buffer->i4_peak_drain_rate_frame);
272     }
273     else
274     {
275         /*currently only two modes are supported*/
276         ASSERT(e_rc_type == CONST_QP);
277     }
278 
279     if(ps_cbr_buffer->i4_buffer_size > (WORD32)u4_vbv_buf_size)
280     {
281         ps_cbr_buffer->i4_buffer_size = u4_vbv_buf_size;
282     }
283 
284     /* Uppr threshold for
285         I frame = 1 * bits per frame
286         P Frame = 4 * bits per frame.
287         The threshold for I frame is only 1 * bits per frame as the threshold should
288         only account for error in estimated bits.
289         In P frame it should account for difference bets bits consumed by I(Scene change)
290         and P frame I to P complexity is assumed to be 5. */
291     /*HEVC_hierarchy*/
292     if(e_rc_type != CONST_QP)
293         set_upper_lower_vbv_threshold(ps_cbr_buffer, i4_bits_per_frm[0]);
294     /* Storing the input parameters for using it for change functions */
295     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
296         ps_cbr_buffer->ai4_bit_rate[i] = u4_bit_rate;
297     for(i = 0; i < MAX_PIC_TYPE; i++)
298     {
299         ps_cbr_buffer->ai4_num_pics_in_delay_period[i] = u4_num_pics_in_delay_prd[i];
300     }
301     ps_cbr_buffer->i4_tgt_frm_rate = i4_tgt_frm_rate;
302     ps_cbr_buffer->i4_max_delay = i4_buffer_delay;
303     ps_cbr_buffer->u4_max_vbv_buf_size = u4_vbv_buf_size;
304     ps_cbr_buffer->u4_num_frms_in_delay = u4_num_frames_in_delay;
305 }
306 #endif /* #if NON_STEADSTATE_CODE */
307 
308 /* ******************************************************************************/
309 /**
310  * @brief Condition check for constrining the number of bits allocated based on bufer size
311  *
312  * @param ps_cbr_buffer
313  * @param i4_tgt_bits
314  * @param e_pic_type
315  *
316  * @return
317  */
318 /* ******************************************************************************/
cbr_buffer_constraint_check(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tgt_bits,picture_type_e e_pic_type,WORD32 * pi4_max_tgt_bits,WORD32 * pi4_min_tgt_bits)319 WORD32 cbr_buffer_constraint_check(
320     cbr_buffer_t *ps_cbr_buffer,
321     WORD32 i4_tgt_bits,
322     picture_type_e e_pic_type,
323     WORD32 *pi4_max_tgt_bits,
324     WORD32 *pi4_min_tgt_bits)
325 {
326     WORD32 i4_max_tgt_bits, i4_min_tgt_bits;
327     WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC)
328                                          ? ps_cbr_buffer->i4_drain_bits_per_frame[0]
329                                          : ps_cbr_buffer->i4_drain_bits_per_frame[1];
330     WORD32 i4_error_bits = (e_pic_type == I_PIC)
331                                ? get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[0])
332                                : get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[1]);
333 
334     /*trace_printf("  ebf = %d  bebf = %d ",ps_cbr_buffer->i4_ebf,ps_cbr_buffer->i8_ebf_bit_alloc);*/
335     /* Max tgt bits = Upper threshold - current encoder buffer fullness */
336     i4_max_tgt_bits =
337         (WORD32)(ps_cbr_buffer->i4_upr_thr[e_pic_type] - ps_cbr_buffer->i4_ebf_estimate);
338     /* Max tgt bits cannot be negative */
339     if(i4_max_tgt_bits < 0)
340         i4_max_tgt_bits = 0;
341 
342     /* Min tgt bits , least number of bits in the Encoder after
343     draining such that it is greater than lower threshold */
344     i4_min_tgt_bits = (WORD32)(
345         ps_cbr_buffer->i4_low_thr[e_pic_type] -
346         (ps_cbr_buffer->i4_ebf_estimate - i4_drain_bits_per_frame - i4_error_bits));
347     /*Min tgt bits cannot be negative*/
348     if(i4_min_tgt_bits < 0)
349         i4_min_tgt_bits = 0;
350 
351     /* current tgt bits should be between max and min tgt bits*/
352     CLIP(i4_tgt_bits, i4_max_tgt_bits, i4_min_tgt_bits);
353     pi4_min_tgt_bits[0] = i4_min_tgt_bits;
354     pi4_max_tgt_bits[0] = i4_max_tgt_bits;
355     return i4_tgt_bits;
356 }
357 
358 /* ******************************************************************************/
359 /**
360  * @brief constaints the bit allocation based on buffer size
361  *
362  * @param ps_cbr_buffer
363  * @param i4_tgt_bits
364  * @param e_pic_type
365  *
366  * @return
367  */
368 /* ******************************************************************************/
vbr_stream_buffer_constraint_check(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tgt_bits,picture_type_e e_pic_type,WORD32 * pi4_max_bits,WORD32 * pi4_min_bits)369 WORD32 vbr_stream_buffer_constraint_check(
370     cbr_buffer_t *ps_cbr_buffer,
371     WORD32 i4_tgt_bits,
372     picture_type_e e_pic_type,
373     WORD32 *pi4_max_bits,
374     WORD32 *pi4_min_bits)
375 {
376     WORD32 i4_max_tgt_bits, i4_min_tgt_bits = 0;
377 
378     /* Max tgt bits = Upper threshold - current encoder buffer fullness */
379     /*maximum target for a pic is amount of bits that can be transmitted to decoder buffer in delay assuming max drain rate
380       This above limit has to be constrained wrt a single frame being accomodated in the buffer*/
381     i4_max_tgt_bits = (WORD32)(
382         (ps_cbr_buffer->u4_num_frms_in_delay * ps_cbr_buffer->i4_peak_drain_rate_frame) -
383         ps_cbr_buffer->i4_ebf_estimate);
384     /*the below check is necessary to make sure that a single frame to be accomodated in encoder buffer*/
385     if(i4_max_tgt_bits > ps_cbr_buffer->i4_upr_thr[e_pic_type] - ps_cbr_buffer->i4_ebf_estimate)
386     {
387         i4_max_tgt_bits =
388             (WORD32)(ps_cbr_buffer->i4_upr_thr[e_pic_type] - ps_cbr_buffer->i4_ebf_estimate);
389     }
390 
391     /*In VBR streaming though encoder buffer underflow is not a problem, at any point of time the bitrate underconsumption
392       cannot go below specified limit. Hence it is limited based on possible bitrate deviation allowed*/
393     /*Enabling movement of stuffing bits always*/
394     if(ps_cbr_buffer->i4_vbr_no_peak_rate_duration_limit)
395     {
396         /*If the content has underconsumed force it to consume atleast per frame bits so that end of encoding there wont be too much undersonsumption*/
397         if(ps_cbr_buffer->i8_ebf_bit_alloc < 0 && ps_cbr_buffer->i4_cbr_rc_pass != 2)
398             i4_min_tgt_bits = (ps_cbr_buffer->i4_drain_bits_per_frame[0] >> 1);
399     }
400     else
401     {
402         /*In this case buffer is always guranteed to be positive, to avoid stuffing give decent amount of min bits*/
403         i4_min_tgt_bits = (WORD32)(ps_cbr_buffer->i4_low_thr[0] - ps_cbr_buffer->i8_ebf_bit_alloc);
404     }
405 
406     /*Clip min target bit*/
407     if(i4_min_tgt_bits < 0)
408         i4_min_tgt_bits = 0;
409     if(i4_tgt_bits < i4_min_tgt_bits)
410         i4_tgt_bits = i4_min_tgt_bits;
411     pi4_min_bits[0] = i4_min_tgt_bits;
412     /* Max tgt bits cannot be negative */
413     if(i4_max_tgt_bits < 0)
414         i4_max_tgt_bits = 0;
415     if(i4_tgt_bits > i4_max_tgt_bits)
416         i4_tgt_bits = i4_max_tgt_bits;
417     pi4_max_bits[0] = i4_max_tgt_bits;
418 
419     return i4_tgt_bits;
420 }
421 
422 /* ******************************************************************************/
423 /**
424  * @brief Verifies the buffer state and returns whether it is overflowing, underflowing or normal
425  *
426  * @param ps_cbr_buffer
427  * @param i4_tot_consumed_bits
428  * @param pi4_num_bits_to_prevent_overflow
429  * @param e_pic_type
430  *
431  * @return
432  */
433 /* ******************************************************************************/
get_cbr_buffer_status(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tot_consumed_bits,WORD32 * pi4_num_bits_to_prevent_overflow,picture_type_e e_pic_type,rc_type_e e_rc_type)434 vbv_buf_status_e get_cbr_buffer_status(
435     cbr_buffer_t *ps_cbr_buffer,
436     WORD32 i4_tot_consumed_bits,
437     WORD32 *pi4_num_bits_to_prevent_overflow,
438     picture_type_e e_pic_type,
439     rc_type_e e_rc_type)
440 {
441     vbv_buf_status_e e_buf_status;
442     WORD32 i4_cur_enc_buf;
443     WORD32 i4_error_bits = (e_pic_type == I_PIC)
444                                ? get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[0])
445                                : get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[1]);
446     WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC)
447                                          ? ps_cbr_buffer->i4_drain_bits_per_frame[0]
448                                          : ps_cbr_buffer->i4_drain_bits_per_frame[1];
449 
450     /* Add the tot consumed bits to the Encoder Buffer*/
451     i4_cur_enc_buf = ps_cbr_buffer->i4_ebf + i4_tot_consumed_bits;
452 
453     /* If the Encoder exceeds the Buffer Size signal an Overflow*/
454     if(i4_cur_enc_buf > ps_cbr_buffer->i4_buffer_size)
455     {
456         e_buf_status = VBV_OVERFLOW;
457         i4_cur_enc_buf = ps_cbr_buffer->i4_buffer_size;
458     }
459     else
460     {
461         /* Subtract the constant drain bits and error bits due to fixed point implementation*/
462         i4_cur_enc_buf -= (i4_drain_bits_per_frame + i4_error_bits);
463 
464         if(e_rc_type == VBR_STREAMING)
465         {
466             /*In VBR suffing scenerio will not occur*/
467             if(i4_cur_enc_buf < 0)
468                 i4_cur_enc_buf = 0;
469         }
470         /* If the buffer is less than stuffing threshold an Underflow is signaled else its NORMAL*/
471         if(i4_cur_enc_buf < 0)
472         {
473             e_buf_status = VBV_UNDERFLOW;
474         }
475         else
476         {
477             e_buf_status = VBV_NORMAL;
478         }
479 
480         if(i4_cur_enc_buf < 0)
481             i4_cur_enc_buf = 0;
482     }
483 
484     /* The RC lib models the encoder buffer, but the VBV buffer characterises the decoder buffer */
485     if(e_buf_status == VBV_OVERFLOW)
486     {
487         e_buf_status = VBV_UNDERFLOW;
488     }
489     else if(e_buf_status == VBV_UNDERFLOW)
490     {
491         e_buf_status = VBV_OVERFLOW;
492     }
493 
494     pi4_num_bits_to_prevent_overflow[0] = (ps_cbr_buffer->i4_buffer_size - i4_cur_enc_buf);
495 
496     return e_buf_status;
497 }
498 
499 /* ******************************************************************************/
500 /**
501  * @brief Based on the bits consumed the buffer model is updated
502  *
503  * @param ps_cbr_buffer
504  * @param i4_tot_consumed_bits
505  * @param e_pic_type
506  */
507 /* ******************************************************************************/
update_cbr_buffer(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tot_consumed_bits,picture_type_e e_pic_type)508 void update_cbr_buffer(
509     cbr_buffer_t *ps_cbr_buffer, WORD32 i4_tot_consumed_bits, picture_type_e e_pic_type)
510 {
511     WORD32 i;
512     WORD32 i4_error_bits = (e_pic_type == I_PIC)
513                                ? get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[0])
514                                : get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[1]);
515     WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC)
516                                          ? ps_cbr_buffer->i4_drain_bits_per_frame[0]
517                                          : ps_cbr_buffer->i4_drain_bits_per_frame[1];
518 
519     ps_cbr_buffer->i8_num_frames_encoded++;
520     if(ps_cbr_buffer->e_rc_type == VBR_STREAMING && ps_cbr_buffer->i8_tot_frm_to_be_encoded < 0)
521     {
522         LWORD64 i8_max_bit_dev_allowed = ps_cbr_buffer->ai4_bit_rate[0];
523         LWORD64 approx_file_size = ps_cbr_buffer->i8_num_frames_encoded *
524                                    ps_cbr_buffer->ai4_bit_rate[0] * 1000 /
525                                    ps_cbr_buffer->i4_tgt_frm_rate;
526         if(i8_max_bit_dev_allowed < (approx_file_size >> 4))
527             i8_max_bit_dev_allowed = (approx_file_size >> 4);
528 
529         /*have a max limit so that bit dev does not grow for very long sequence like 24 hours of encoding (max can be 20 second)*/
530         if(i8_max_bit_dev_allowed > (VBR_MAX_BIT_DEV_SEC * ps_cbr_buffer->ai4_bit_rate[0]))
531             i8_max_bit_dev_allowed = (VBR_MAX_BIT_DEV_SEC * ps_cbr_buffer->ai4_bit_rate[0]);
532 
533         ps_cbr_buffer->u4_max_vbv_buf_size = (UWORD32)i8_max_bit_dev_allowed;
534     }
535     /* Update the Encoder buffer with the total consumed bits*/
536     if(ps_cbr_buffer->i4_is_cbr_mode != 0)
537     {
538         ps_cbr_buffer->i4_ebf += i4_tot_consumed_bits;
539         ps_cbr_buffer->i8_ebf_bit_alloc += i4_tot_consumed_bits;
540 
541         /* Subtract the drain bits and error bits due to fixed point implementation*/
542         ps_cbr_buffer->i4_ebf -= (i4_drain_bits_per_frame + i4_error_bits);
543         ps_cbr_buffer->i8_ebf_bit_alloc -= (i4_drain_bits_per_frame + i4_error_bits);
544     }
545     else
546     {
547         ps_cbr_buffer->i4_ebf += i4_tot_consumed_bits;
548         ps_cbr_buffer->i4_ebf -=
549             ((MIN(ps_cbr_buffer->i4_peak_drain_rate_frame, ps_cbr_buffer->i4_ebf)) + i4_error_bits);
550 
551         ps_cbr_buffer->i8_ebf_bit_alloc += i4_tot_consumed_bits;
552         ps_cbr_buffer->i8_ebf_bit_alloc -=
553             (ps_cbr_buffer->i4_drain_bits_per_frame[0] + i4_error_bits);
554 
555         ps_cbr_buffer->i8_credit_level += i4_tot_consumed_bits;
556         ps_cbr_buffer->i8_credit_level -=
557             (ps_cbr_buffer->i4_drain_bits_per_frame[0] + i4_error_bits);
558         /*To keep limit on duration for which peak rate can be sustained limit the accumulation of bits from simpler regions*/
559         if(!ps_cbr_buffer->i4_vbr_no_peak_rate_duration_limit)
560         {
561             if(ps_cbr_buffer->i8_ebf_bit_alloc < 0)
562                 ps_cbr_buffer->i8_ebf_bit_alloc =
563                     0; /*This will make VBR buffer believe that the bits are lost*/
564         }
565     }
566 
567     /*SS - Fix for lack of stuffing*/
568     if(ps_cbr_buffer->i4_ebf < 0)
569     {
570         //trace_printf("Error: Should not be coming here with bit stuffing \n");
571         ps_cbr_buffer->i4_ebf = 0;
572     }
573 
574     if(ps_cbr_buffer->i4_ebf > ps_cbr_buffer->i4_buffer_size)
575     {
576         //trace_printf("Error: Frame should be skipped\n");
577         ps_cbr_buffer->i4_ebf = ps_cbr_buffer->i4_buffer_size;
578     }
579 
580     ps_cbr_buffer->i4_ebf_estimate = ps_cbr_buffer->i4_ebf;
581 
582     trace_printf(
583         "VBR ebf = %d  bebf = %d  ", ps_cbr_buffer->i4_ebf, ps_cbr_buffer->i8_ebf_bit_alloc);
584     /* Update the error bits */
585     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
586         update_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i]);
587 }
588 
589 /* ******************************************************************************/
590 /**
591  * @brief If the buffer underflows then return the number of bits to prevent underflow
592  *
593  * @param ps_cbr_buffer
594  * @param i4_tot_consumed_bits
595  * @param e_pic_type
596  *
597  * @return
598  */
599 /* ******************************************************************************/
get_cbr_bits_to_stuff(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tot_consumed_bits,picture_type_e e_pic_type)600 WORD32 get_cbr_bits_to_stuff(
601     cbr_buffer_t *ps_cbr_buffer, WORD32 i4_tot_consumed_bits, picture_type_e e_pic_type)
602 {
603     WORD32 i4_bits_to_stuff;
604     WORD32 i4_error_bits = (e_pic_type == I_PIC)
605                                ? get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[0])
606                                : get_error_bits(ps_cbr_buffer->aps_bpf_error_bits[1]);
607     WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC)
608                                          ? ps_cbr_buffer->i4_drain_bits_per_frame[0]
609                                          : ps_cbr_buffer->i4_drain_bits_per_frame[1];
610 
611     /* Stuffing bits got from the following equation
612        Stuffing_threshold = ebf + tcb - drain bits - error bits + stuff_bits*/
613     i4_bits_to_stuff =
614         i4_drain_bits_per_frame + i4_error_bits - (ps_cbr_buffer->i4_ebf + i4_tot_consumed_bits);
615 
616     return i4_bits_to_stuff;
617 }
618 
619 /* ******************************************************************************/
620 /**
621  * @brief Change the state for change in bit rate
622  *
623  * @param ps_cbr_buffer
624  * @param i4_bit_rate
625  */
626 /* ******************************************************************************/
change_cbr_vbv_bit_rate(cbr_buffer_t * ps_cbr_buffer,WORD32 * i4_bit_rate,WORD32 i4_peak_bitrate)627 void change_cbr_vbv_bit_rate(
628     cbr_buffer_t *ps_cbr_buffer, WORD32 *i4_bit_rate, WORD32 i4_peak_bitrate)
629 {
630     WORD32 i4_bits_per_frm[MAX_NUM_DRAIN_RATES];
631     int i;
632 
633     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
634     {
635         X_PROD_Y_DIV_Z(i4_bit_rate[i], 1000, ps_cbr_buffer->i4_tgt_frm_rate, i4_bits_per_frm[i]);
636         /* Drain rate = bitrate/(framerate/1000) */
637         ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i];
638 
639         /* initialise the bits per frame error bits calculation */
640         change_bitrate_in_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], i4_bit_rate[i]);
641     }
642     X_PROD_Y_DIV_Z(
643         i4_peak_bitrate,
644         1000,
645         ps_cbr_buffer->i4_tgt_frm_rate,
646         ps_cbr_buffer->i4_peak_drain_rate_frame);
647     /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/
648     //if(i4_bit_rate[0] == i4_bit_rate[1]) /* This would mean CBR mode */
649     {
650         X_PROD_Y_DIV_Z(
651             i4_bit_rate[0],
652             ps_cbr_buffer->i4_max_delay,
653             1000,
654             ps_cbr_buffer->i4_buffer_size);  //the delay term is supposed to remain constant
655         //ps_cbr_buffer->i4_is_cbr_mode = 1;
656         ps_cbr_buffer->u4_max_vbv_buf_size = ps_cbr_buffer->i4_buffer_size;
657     }
658     if(ps_cbr_buffer->i4_buffer_size > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size)
659     {
660         ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size;
661     }
662     set_upper_lower_vbv_threshold(ps_cbr_buffer, i4_bits_per_frm[0]);
663     if(ps_cbr_buffer->e_rc_type == CBR_NLDRC)
664     {
665         ps_cbr_buffer->u4_vbr_max_bit_deviation = ps_cbr_buffer->i4_buffer_size;
666     }
667     else
668     {
669         /*DCB: the deviaiton must be altered for VBR case, when bitrate is lowered quality might be bad because of this*/
670         {
671             ULWORD64 u8_vbr_max_bit_deviation =
672                 (ULWORD64)(ps_cbr_buffer->f_max_dur_peak_rate * i4_bit_rate[0]);
673             ULWORD64 file_size = (ULWORD64)(
674                 (((LWORD64)i4_bit_rate[0] * 1000) / ps_cbr_buffer->i4_tgt_frm_rate) *
675                 (ps_cbr_buffer->i8_tot_frm_to_be_encoded - ps_cbr_buffer->i8_num_frames_encoded));
676             /*When f_max_dur_peak_rate is -ve, it implies user is not worried about duration for which peak is sustained, hence go with max possible value*/
677             if(ps_cbr_buffer->f_max_dur_peak_rate > 0)
678                 u8_vbr_max_bit_deviation =
679                     (ULWORD64)(ps_cbr_buffer->f_max_dur_peak_rate * i4_bit_rate[0]);
680             else
681                 u8_vbr_max_bit_deviation = VBR_MAX_BIT_DEV_SEC * i4_bit_rate[0];
682 
683             /*when num frames to encode is negative is -ve it implies total frames data is not available (as in case of live encoding)*/
684             if(ps_cbr_buffer->i8_tot_frm_to_be_encoded > 0)
685             {
686                 /*allow atleast one second deviation or 12% of total file size whichever is higher*/
687                 if(u8_vbr_max_bit_deviation > (file_size >> 3))
688                     u8_vbr_max_bit_deviation = (UWORD32)(file_size >> 3);
689             }
690             else
691             {
692                 u8_vbr_max_bit_deviation = (UWORD32)(file_size >> 3);
693             }
694             /*allow atleast one second for shorter sequence*/
695             if(u8_vbr_max_bit_deviation < (ULWORD64)i4_bit_rate[0])
696                 u8_vbr_max_bit_deviation = (ULWORD64)i4_bit_rate[0];
697             ps_cbr_buffer->u4_vbr_max_bit_deviation = u8_vbr_max_bit_deviation;
698         }
699     }
700 
701     /* Storing the input parameters for using it for change functions */
702     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
703         ps_cbr_buffer->ai4_bit_rate[i] = i4_bit_rate[i];
704 }
705 /* ******************************************************************************/
706 /**
707  * @brief Update the state for change in number of pics in the delay period
708  *
709  * @param ps_cbr_buffer
710  * @param u4_num_pics_in_delay_prd
711  */
712 /* ******************************************************************************/
change_cbr_vbv_num_pics_in_delay_period(cbr_buffer_t * ps_cbr_buffer,UWORD32 * u4_num_pics_in_delay_prd)713 void change_cbr_vbv_num_pics_in_delay_period(
714     cbr_buffer_t *ps_cbr_buffer, UWORD32 *u4_num_pics_in_delay_prd)
715 {
716     WORD32 i;
717 
718     if(!ps_cbr_buffer->i4_is_cbr_mode)
719     {
720         ps_cbr_buffer->i4_buffer_size =
721             u4_num_pics_in_delay_prd[0] * ps_cbr_buffer->i4_drain_bits_per_frame[0] +
722             u4_num_pics_in_delay_prd[1] * ps_cbr_buffer->i4_drain_bits_per_frame[1];
723 
724         if(ps_cbr_buffer->i4_buffer_size > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size)
725         {
726             ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size;
727         }
728         for(i = 0; i < MAX_PIC_TYPE; i++)
729         {
730             ps_cbr_buffer->i4_upr_thr[i] =
731                 ps_cbr_buffer->i4_buffer_size - (ps_cbr_buffer->i4_buffer_size >> 3);
732         }
733 
734         /* Re-initilise the number of pics in delay period */
735         for(i = 0; i < MAX_PIC_TYPE; i++)
736         {
737             ps_cbr_buffer->ai4_num_pics_in_delay_period[i] = u4_num_pics_in_delay_prd[i];
738         }
739     }
740 }
741 /* ******************************************************************************/
742 /**
743  * @ modifies the ebf estimated parameter based on error
744  *
745  * @param ps_cbr_buffer
746  * @param i4_bit_error
747  */
748 /* ******************************************************************************/
cbr_modify_ebf_estimate(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_bit_error)749 void cbr_modify_ebf_estimate(cbr_buffer_t *ps_cbr_buffer, WORD32 i4_bit_error)
750 {
751     ps_cbr_buffer->i4_ebf_estimate = ps_cbr_buffer->i4_ebf + i4_bit_error;
752     if(ps_cbr_buffer->i4_ebf_estimate < 0)
753     {
754         ps_cbr_buffer->i4_ebf_estimate = 0;
755     }
756     else if(ps_cbr_buffer->i4_ebf_estimate > ps_cbr_buffer->i4_buffer_size)
757     {
758         ps_cbr_buffer->i4_ebf_estimate = ps_cbr_buffer->i4_buffer_size;
759     }
760 }
761 
762 /* ******************************************************************************/
763 /**
764  * @ get the buffer size
765  *
766  * @param ps_cbr_buffer
767  */
768 /* ******************************************************************************/
769 
get_cbr_buffer_size(cbr_buffer_t * ps_cbr_buffer)770 WORD32 get_cbr_buffer_size(cbr_buffer_t *ps_cbr_buffer)
771 {
772     return (ps_cbr_buffer->i4_buffer_size);
773 }
774 
775 #if NON_STEADSTATE_CODE
776 /* ******************************************************************************/
777 /**
778  * @brief update the state for change in target frame rate
779  *
780  * @param ps_cbr_buffer
781  * @param i4_tgt_frm_rate
782  */
783 /* ******************************************************************************/
change_cbr_vbv_tgt_frame_rate(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_tgt_frm_rate)784 void change_cbr_vbv_tgt_frame_rate(cbr_buffer_t *ps_cbr_buffer, WORD32 i4_tgt_frm_rate)
785 {
786     WORD32 i4_i, i4_bits_per_frm[MAX_NUM_DRAIN_RATES];
787     int i;
788 
789     for(i = 0; i < MAX_NUM_DRAIN_RATES; i++)
790     {
791         X_PROD_Y_DIV_Z(ps_cbr_buffer->ai4_bit_rate[i], 1000, i4_tgt_frm_rate, i4_bits_per_frm[i]);
792         /* Drain rate = bitrate/(framerate/1000) */
793         ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i];
794         /* initialise the bits per frame error bits calculation */
795         change_frm_rate_in_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], i4_tgt_frm_rate);
796     }
797 
798     /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/
799     if(!ps_cbr_buffer->i4_is_cbr_mode)
800     {
801         /* VBR streaming case which has different drain rates for I and P */
802         ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->ai4_num_pics_in_delay_period[0] *
803                                             ps_cbr_buffer->i4_drain_bits_per_frame[0] +
804                                         ps_cbr_buffer->ai4_num_pics_in_delay_period[1] *
805                                             ps_cbr_buffer->i4_drain_bits_per_frame[1];
806     }
807 
808     if(ps_cbr_buffer->i4_buffer_size > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size)
809     {
810         ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size;
811     }
812 
813     for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
814     {
815         /* Uppr threshold for
816            I frame = 1 * bits per frame
817            P Frame = 4 * bits per frame.
818            The threshold for I frame is only 1 * bits per frame as the threshold should
819            only account for error in estimated bits.
820            In P frame it should account for difference bets bits consumed by I(Scene change)
821            and P frame I to P complexity is assumed to be 5. */
822         WORD32 i4_index;
823         i4_index = i4_i > 0 ? 1 : 0;
824         ps_cbr_buffer->i4_upr_thr[i4_i] =
825             ps_cbr_buffer->i4_buffer_size - (ps_cbr_buffer->i4_buffer_size >> 3);
826 
827         /* For both I and P frame Lower threshold is equal to drain rate.
828         Even if the encoder consumes zero bits it should have enough bits to drain*/
829         ps_cbr_buffer->i4_low_thr[i4_i] = i4_bits_per_frm[i4_index];
830     }
831 
832     /* Storing the input parameters for using it for change functions */
833     ps_cbr_buffer->i4_tgt_frm_rate = i4_tgt_frm_rate;
834 }
835 /* ******************************************************************************/
836 /**
837  * @brief update the state for change in buffer delay
838  *
839  * @param ps_cbr_buffer
840  * @param i4_buffer_delay
841  */
842 /* ******************************************************************************/
change_cbr_buffer_delay(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_buffer_delay)843 void change_cbr_buffer_delay(cbr_buffer_t *ps_cbr_buffer, WORD32 i4_buffer_delay)
844 {
845     WORD32 i4_i;
846 
847     /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/
848     if(ps_cbr_buffer->i4_is_cbr_mode)
849     {
850         X_PROD_Y_DIV_Z(
851             ps_cbr_buffer->ai4_bit_rate[0], i4_buffer_delay, 1000, ps_cbr_buffer->i4_buffer_size);
852     }
853 
854     if(ps_cbr_buffer->i4_buffer_size > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size)
855     {
856         ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size;
857     }
858 
859     for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
860     {
861         /* Uppr threshold for
862            I frame = 1 * bits per frame
863            P Frame = 4 * bits per frame.
864            The threshold for I frame is only 1 * bits per frame as the threshold should
865            only account for error in estimated bits.
866            In P frame it should account for difference bets bits consumed by I(Scene change)
867            and P frame I to P complexity is assumed to be 5. */
868         ps_cbr_buffer->i4_upr_thr[i4_i] =
869             ps_cbr_buffer->i4_buffer_size - (ps_cbr_buffer->i4_buffer_size >> 3);
870     }
871 
872     /* Storing the input parameters for using it for change functions */
873     ps_cbr_buffer->i4_max_delay = i4_buffer_delay;
874 }
875 /* ******************************************************************************/
876 /**
877  * @brief update the state for change in buffer delay
878  *
879  * @param ps_cbr_buffer
880  * @param i4_buffer_delay
881  */
882 /* ******************************************************************************/
get_cbr_buffer_delay(cbr_buffer_t * ps_cbr_buffer)883 WORD32 get_cbr_buffer_delay(cbr_buffer_t *ps_cbr_buffer)
884 {
885     return (ps_cbr_buffer->i4_max_delay);
886 }
887 /* ******************************************************************************/
888 /**
889  * @brief get_cbr_ebf
890  *
891  * @param ps_cbr_buffer
892   */
893 /* ******************************************************************************/
get_cbr_ebf(cbr_buffer_t * ps_cbr_buffer)894 WORD32 get_cbr_ebf(cbr_buffer_t *ps_cbr_buffer)
895 {
896     return (ps_cbr_buffer->i4_ebf);
897 }
898 /* ******************************************************************************/
899 /**
900  * @brief get_cbr_max_ebf
901  *
902  * @param ps_cbr_buffer
903  */
904 /* ******************************************************************************/
get_cbr_max_ebf(cbr_buffer_t * ps_cbr_buffer)905 WORD32 get_cbr_max_ebf(cbr_buffer_t *ps_cbr_buffer)
906 {
907     return (ps_cbr_buffer->i4_upr_thr[0]);
908 }
909 /* ******************************************************************************/
910 /**
911  * @brief set_cbr_ebf
912  *
913  * @param ps_cbr_buffer
914  * @param i32_init_ebf
915  */
916 /* ******************************************************************************/
set_cbr_ebf(cbr_buffer_t * ps_cbr_buffer,WORD32 i32_init_ebf)917 void set_cbr_ebf(cbr_buffer_t *ps_cbr_buffer, WORD32 i32_init_ebf)
918 {
919     ps_cbr_buffer->i4_ebf = i32_init_ebf;
920 }
921 /* ******************************************************************************/
922 /**
923  * @brief update_cbr_buf_mismatch_bit
924  *
925  * @param ps_cbr_buffer
926  * @param i4_error_bits
927  */
928 /* ******************************************************************************/
update_cbr_buf_mismatch_bit(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_error_bits)929 void update_cbr_buf_mismatch_bit(cbr_buffer_t *ps_cbr_buffer, WORD32 i4_error_bits)
930 {
931     ps_cbr_buffer->i4_ebf -= i4_error_bits;
932     ps_cbr_buffer->i8_ebf_bit_alloc -= i4_error_bits;
933     ps_cbr_buffer->i8_credit_level -= i4_error_bits;
934 }
935 /* ******************************************************************************/
936 /**
937  * @brief get encoded number of frames
938  *
939  * @param ps_cbr_buffer
940   */
941 /* ******************************************************************************/
get_num_frms_encoded(cbr_buffer_t * ps_cbr_buffer)942 LWORD64 get_num_frms_encoded(cbr_buffer_t *ps_cbr_buffer)
943 {
944     return ps_cbr_buffer->i8_num_frames_encoded;
945 }
946 /* ******************************************************************************/
947 /**
948  * @brief get num frames to encode
949  *
950  * @param ps_cbr_buffer
951   */
952 /* ******************************************************************************/
get_num_frms_to_encode(cbr_buffer_t * ps_cbr_buffer)953 LWORD64 get_num_frms_to_encode(cbr_buffer_t *ps_cbr_buffer)
954 {
955     return ps_cbr_buffer->i8_tot_frm_to_be_encoded;
956 }
957 /* ******************************************************************************/
958 /**
959  * @brief get peak drain rate
960  *
961  * @param ps_cbr_buffer
962  */
963 /* ******************************************************************************/
964 /* The buffer limit in bit allocation should be according to peak bitrate */
get_buf_max_drain_rate(cbr_buffer_t * ps_cbr_buffer)965 WORD32 get_buf_max_drain_rate(cbr_buffer_t *ps_cbr_buffer)
966 {
967     if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
968         return ps_cbr_buffer->i4_peak_drain_rate_frame;
969     else if(ps_cbr_buffer->e_rc_type != CONST_QP)
970     {
971         ASSERT(
972             ps_cbr_buffer->i4_peak_drain_rate_frame == ps_cbr_buffer->i4_drain_bits_per_frame[0]);
973         return ps_cbr_buffer->i4_drain_bits_per_frame[0];
974     }
975     return ps_cbr_buffer->i4_drain_bits_per_frame[0];
976 }
977 /* ******************************************************************************/
978 /**
979  * @brief get excess bits by moving in VBV buffer to enable bitrate greater than peak rate for shorter duration in very
980  *  complex contents
981  *
982  * @param ps_cbr_buffer
983  * @param i4_tgt_frm_rate
984  */
985 /* ******************************************************************************/
get_vbv_buffer_based_excess(cbr_buffer_t * ps_cbr_buffer,float f_complexity_peak_rate,float f_cur_bits_complexity,WORD32 bit_alloc_period,WORD32 i4_num_gops_for_excess)986 WORD32 get_vbv_buffer_based_excess(
987     cbr_buffer_t *ps_cbr_buffer,
988     float f_complexity_peak_rate,
989     float f_cur_bits_complexity,
990     WORD32 bit_alloc_period,
991     WORD32 i4_num_gops_for_excess)
992 {
993     LWORD64 max_buffer_level = (LWORD64)((float)ps_cbr_buffer->i4_buffer_size * 0.8f);
994     LWORD64 i8_excess_bits;
995     /*LWORD64target_buf_level;*/
996     WORD32
997     num_frm_to_be_distributed;  //Number of frames for which excess bits should be distributed, using number of frames corresponding to buffer size for now
998 
999     if(ps_cbr_buffer->i4_upr_thr[0] <
1000        max_buffer_level) /*choose max allowed level to min(upper_threshold,80% of buffer*/
1001         max_buffer_level = ps_cbr_buffer->i4_upr_thr[0];
1002 
1003     if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
1004         max_buffer_level = (LWORD64)(
1005             ps_cbr_buffer->i4_peak_drain_rate_frame * ps_cbr_buffer->u4_num_frms_in_delay * 0.8f);
1006 
1007     if(f_cur_bits_complexity >
1008        0.9f) /*clip current to max of 80% of buffer size to avoid dangerous buffer level by end of GOP*/
1009         f_cur_bits_complexity = 0.9f;
1010 
1011     if(f_cur_bits_complexity < f_complexity_peak_rate || f_cur_bits_complexity < 0.1f ||
1012        ps_cbr_buffer->i4_buffer_size <
1013            ps_cbr_buffer->ai4_bit_rate
1014                [0])  //For buffer size less than 1 sec disable any contribution from buffer based for extra complex contents
1015     {
1016         /*For very low compleity content or Cavg do not allow buffer movement*/
1017         return 0;
1018     }
1019 
1020     i8_excess_bits = (LWORD64)(
1021         ((f_cur_bits_complexity - f_complexity_peak_rate) / (0.9f - f_complexity_peak_rate)) *
1022         (max_buffer_level - ps_cbr_buffer->i4_ebf));
1023 
1024     if(i8_excess_bits < 0)
1025         i8_excess_bits = 0;
1026 
1027     num_frm_to_be_distributed = (WORD32)(
1028         ((float)ps_cbr_buffer->i4_buffer_size / ps_cbr_buffer->ai4_bit_rate[0] *
1029          ps_cbr_buffer->i4_tgt_frm_rate / 1000) +
1030         0.5);
1031     /*Excess bits should be proportional to bit alloc period, shorter intra period should get in small incentives*/
1032     if(bit_alloc_period < num_frm_to_be_distributed)
1033         i8_excess_bits =
1034             (LWORD64)((float)i8_excess_bits * bit_alloc_period / num_frm_to_be_distributed);
1035 
1036     if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
1037     {
1038         if(i4_num_gops_for_excess > 1)
1039             i8_excess_bits = i8_excess_bits * i4_num_gops_for_excess;
1040 
1041         if(i8_excess_bits > (LWORD64)(
1042                                 (float)ps_cbr_buffer->i4_peak_drain_rate_frame *
1043                                 ps_cbr_buffer->u4_num_frms_in_delay * 0.8f))
1044             i8_excess_bits = (LWORD64)(
1045                 (float)ps_cbr_buffer->i4_peak_drain_rate_frame *
1046                 ps_cbr_buffer->u4_num_frms_in_delay * 0.8f);
1047     }
1048     trace_printf(
1049         "Excess bits %d %f %f num gops %d",
1050         i8_excess_bits,
1051         f_cur_bits_complexity,
1052         f_complexity_peak_rate,
1053         i4_num_gops_for_excess);
1054 
1055     return ((WORD32)i8_excess_bits);
1056 }
1057 /* ******************************************************************************/
1058 /**
1059  * @brief get gop correction error bits for  the current gop. This will be added to rbip.
1060   *
1061  * @param ps_cbr_buffer
1062  * @param i4_lap_complexity_q7
1063  * @param i4_bit_alloc_period
1064  */
1065 /* ******************************************************************************/
get_error_bits_for_desired_buf(cbr_buffer_t * ps_cbr_buffer,WORD32 i4_lap_complexity_q7,WORD32 i4_bit_alloc_period)1066 WORD32 get_error_bits_for_desired_buf(
1067     cbr_buffer_t *ps_cbr_buffer, WORD32 i4_lap_complexity_q7, WORD32 i4_bit_alloc_period)
1068 {
1069     if(ps_cbr_buffer->e_rc_type == CBR_NLDRC)
1070     {
1071         LWORD64 error_bits = 0, complexity_mov_buf_size = 0;
1072         LWORD64 i8_default_bits_in_period, i8_max_additional_bits_in_period;
1073         LWORD64 i8_buf_based_limit_red, i8_buf_based_limit_inc, i8_buf_diff_bits;
1074         float buf_diff, abs_lap_complexity;
1075 
1076         /*calculate default allocation*/
1077         i8_default_bits_in_period = (LWORD64)ps_cbr_buffer->ai4_bit_rate[0] * 1000 *
1078                                     i4_bit_alloc_period / ps_cbr_buffer->i4_tgt_frm_rate;
1079 
1080         /*In case of VBR give additional bits according to peak bitrate*/
1081         if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
1082         {
1083             i8_max_additional_bits_in_period =
1084                 ((LWORD64)ps_cbr_buffer->i4_peak_drain_rate_frame * i4_bit_alloc_period) -
1085                 i8_default_bits_in_period;
1086             ASSERT(i8_max_additional_bits_in_period >= 0);
1087             if(i8_max_additional_bits_in_period > (i8_default_bits_in_period))
1088             {
1089                 /*clip max bits that can be given to 2x bitrate since its too riskly to give more than that in single pass encoding
1090                   where long future is not known*/
1091                 i8_max_additional_bits_in_period = (i8_default_bits_in_period);
1092             }
1093         }
1094         else
1095         {
1096             i8_max_additional_bits_in_period = i8_default_bits_in_period;
1097         }
1098         {
1099             float X = ((float)i4_lap_complexity_q7 / 128);
1100             float desired_buf_level;
1101             /*For CBR VBV buffer size is "complexity_mov_buf_size" and In case of VBR it is determined by bit deviaiton*/
1102             if(ps_cbr_buffer->e_rc_type == CBR_NLDRC)
1103             {
1104                 complexity_mov_buf_size = (LWORD64)ps_cbr_buffer->i4_upr_thr[0];
1105             }
1106             else if(ps_cbr_buffer->e_rc_type == VBR_STREAMING)
1107             {
1108                 complexity_mov_buf_size = ps_cbr_buffer->u4_vbr_max_bit_deviation;
1109             }
1110             abs_lap_complexity = X;
1111 
1112             if(ps_cbr_buffer->i4_cbr_rc_pass == 2)
1113                 desired_buf_level = COMP_TO_BITS_MAP_2_PASS(X, complexity_mov_buf_size);
1114             else
1115                 desired_buf_level = COMP_TO_BITS_MAP(X, complexity_mov_buf_size);
1116 
1117             if(desired_buf_level < 0)
1118                 desired_buf_level = 0;
1119             /*map complexity to buffer level*/
1120 
1121             error_bits = (LWORD64)(desired_buf_level - ps_cbr_buffer->i8_ebf_bit_alloc);
1122             i8_buf_diff_bits = error_bits;
1123             /*For VBR its possible that i8_ebf_bit_alloc can go below 0, that the extent of giving should only be desired - cur( = 0 for cur < 0)*/
1124             buf_diff = (float)error_bits / complexity_mov_buf_size;
1125 
1126             /*clipping based on buffer size should depend on gop size. Assuming 7% of gop of gop = 32, calculate for other GOP intervals max 7% while giving from buffer and 10%
1127               while stealing from buffer(for GOP of 32)*/
1128             /*try to be conservative when giving extra bits to gop and limit while reducing bits to GOP needs to be higher inorder to be buffer compliant if necessary*/
1129             i8_buf_based_limit_red =
1130                 ((LWORD64)complexity_mov_buf_size * i4_bit_alloc_period * 12) >> 12;
1131             i8_buf_based_limit_inc = ((LWORD64)complexity_mov_buf_size * i4_bit_alloc_period * 8) >>
1132                                      12;
1133 
1134             /*(shd be 7 even if GOP size goes lesser)*/
1135             if(i8_buf_based_limit_red < (((LWORD64)complexity_mov_buf_size * 10) >> 7))
1136                 i8_buf_based_limit_red = (((LWORD64)complexity_mov_buf_size * 10) >> 7);
1137             if(i8_buf_based_limit_inc < (((LWORD64)complexity_mov_buf_size * 10) >> 7))
1138                 i8_buf_based_limit_inc = (((LWORD64)complexity_mov_buf_size * 10) >> 7);
1139 
1140             /*if error bits is too high it is given in stages so that buffer is utilized for entire complex content*/
1141             /*error bits should not exceed ten 7% of buffer*/
1142             /*error bits can be max equal to bitrate*/
1143             if(error_bits > 0)
1144             {
1145                 /*if lap compleixty is higher and buffer allows give the bits*/
1146                 error_bits = (WORD32)(abs_lap_complexity * i8_max_additional_bits_in_period);
1147                 /*if lap complexity is too simple do not give additional bits to make sure that simple scenes never get additional bits whatsoever*/
1148                 if(abs_lap_complexity < 0.2f && ps_cbr_buffer->i8_ebf_bit_alloc >= 0)
1149                 {
1150                     error_bits = 0;
1151                 }
1152                 if(error_bits > i8_buf_diff_bits)
1153                     error_bits = i8_buf_diff_bits;
1154 
1155                 if(error_bits > i8_buf_based_limit_inc)
1156                 {
1157                     error_bits = i8_buf_based_limit_inc;
1158                 }
1159                 /*If buffer is already half filled be conservative. Allocate 1.5 times bits
1160                  else allocate twice the bits*/
1161                 if(ps_cbr_buffer->i8_ebf_bit_alloc >
1162                    (LWORD64)(ps_cbr_buffer->i4_buffer_size * 0.75))
1163                 {
1164                     if(error_bits > (i8_max_additional_bits_in_period >> 1))
1165                     {
1166                         error_bits = (i8_max_additional_bits_in_period >> 1);
1167                     }
1168                 }
1169                 else
1170                 {
1171                     if(error_bits > i8_max_additional_bits_in_period)
1172                     {
1173                         error_bits = i8_max_additional_bits_in_period;
1174                     }
1175                 }
1176             }
1177             else
1178             {
1179                 error_bits = (WORD32)(buf_diff * (i8_default_bits_in_period >> 1));
1180                 if(error_bits < -i8_buf_based_limit_red)
1181                 {
1182                     error_bits = -i8_buf_based_limit_red;
1183                 }
1184                 /*when buffer level needs to reduce bits in period*/
1185                 /*If current level is less than half min bits in period = 70% of constant bit in period else 50%*/
1186                 if(ps_cbr_buffer->i8_ebf_bit_alloc > (ps_cbr_buffer->i4_buffer_size >> 1))
1187                 {
1188                     if(error_bits < -(i8_default_bits_in_period >> 1))
1189                     {
1190                         error_bits = -(i8_default_bits_in_period >> 1);
1191                     }
1192                 }
1193                 else
1194                 {
1195                     if(error_bits < -((i8_default_bits_in_period * 5) >> 4))
1196                     {
1197                         error_bits = -((i8_default_bits_in_period * 5) >> 4);
1198                     }
1199                 }
1200             }
1201         }
1202         return (WORD32)error_bits;
1203     }
1204     else
1205     {
1206         LWORD64 max_excess_bits, default_allocation_for_period, comp_based_excess = 0;
1207         LWORD64 i8_excess_bits = 0, bit_dev_so_far, credit_limit_level;
1208         LWORD64 Ravg_dur, num_intra_period_in_Ravg_dur,
1209             num_intra_in_clip;  //duration for which Ravg has to be met, for shorter slips this can be equal to clip duration
1210         LWORD64 i8_buf_based_limit_red, i8_buf_based_limit_inc;
1211         float comp_to_bit_mapped, X;
1212 
1213         /*default allocation for period in absence of complexity based bit allocation*/
1214         default_allocation_for_period =
1215             ps_cbr_buffer->i4_drain_bits_per_frame[0] * i4_bit_alloc_period;
1216 
1217         bit_dev_so_far = ps_cbr_buffer->i8_ebf_bit_alloc;
1218         credit_limit_level = ps_cbr_buffer->i8_credit_level;
1219         Ravg_dur =
1220             ps_cbr_buffer->u4_vbr_max_bit_deviation * 5 / ps_cbr_buffer->i4_drain_bits_per_frame[0];
1221         if(Ravg_dur > 20 * ps_cbr_buffer->i8_tot_frm_to_be_encoded / 100)
1222             Ravg_dur = 20 * ps_cbr_buffer->i8_tot_frm_to_be_encoded / 100;
1223         if(Ravg_dur <= 0)
1224             Ravg_dur = 1;
1225         /*map the complexity to bits ratio*/
1226         X = (float)i4_lap_complexity_q7 / 128;
1227         if(ps_cbr_buffer->i4_cbr_rc_pass == 2)
1228             comp_to_bit_mapped = COMP_TO_BITS_MAP_2_PASS(X, 1.0f);
1229         else
1230             comp_to_bit_mapped = COMP_TO_BITS_MAP(X, 1.0f);
1231 
1232         comp_to_bit_mapped *= 10;  //mapping it to absolute peak bitrate
1233 
1234         /*calculate the number of bit alloc periods over which the credit limit needs to build up*/
1235         num_intra_in_clip = ps_cbr_buffer->i8_tot_frm_to_be_encoded / i4_bit_alloc_period;
1236         num_intra_period_in_Ravg_dur = Ravg_dur / i4_bit_alloc_period;
1237         //ASSERT(ps_cbr_buffer->i8_tot_frm_to_be_encoded > i4_bit_alloc_period);
1238         if(ps_cbr_buffer->i8_tot_frm_to_be_encoded < i4_bit_alloc_period)
1239         {
1240             num_intra_period_in_Ravg_dur = 1;
1241             num_intra_in_clip = 1;
1242         }
1243         if(num_intra_period_in_Ravg_dur <= 0)
1244         {
1245             num_intra_period_in_Ravg_dur = 1;
1246         }
1247         /*max excess bits possible according to given peak bitrate*/
1248         {
1249             max_excess_bits = (ps_cbr_buffer->i4_peak_drain_rate_frame -
1250                                ps_cbr_buffer->i4_drain_bits_per_frame[0]) *
1251                               i4_bit_alloc_period;
1252             /*constrain max excess bits allocated to a region if buffer is already at critical level*/
1253             /*assume room for 20% over-consumption due to mismatch between allocation and consumption*/
1254             if(ps_cbr_buffer->i4_ebf >
1255                (ps_cbr_buffer->i4_upr_thr[0] - (WORD32)(max_excess_bits * 0.2)))
1256             {
1257                 max_excess_bits = (LWORD64)(max_excess_bits * 0.8);
1258             }
1259         }
1260         /*clipping based on buffer size should depend on gop size. Assuming 7% of gop of gop = 32, calculate for other GOP intervals max 7% while giving from buffer and 10%
1261             while stealing from buffer(for GOP of 32)*/
1262         /*try to be conservative when giving extra bits to gop and limit while reducing bits to GOP needs to be higher inorder to be buffer compliant if necessary*/
1263         i8_buf_based_limit_red =
1264             ((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * i4_bit_alloc_period * 12) >> 12;
1265         i8_buf_based_limit_inc =
1266             ((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * i4_bit_alloc_period * 8) >> 12;
1267 
1268         /*(shd be 7 even if GOP size goes lesser)*/
1269         if(i8_buf_based_limit_red < (((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * 10) >> 7))
1270             i8_buf_based_limit_red = (((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * 10) >> 7);
1271         if(i8_buf_based_limit_inc < (((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * 10) >> 7))
1272             i8_buf_based_limit_inc = (((LWORD64)ps_cbr_buffer->u4_vbr_max_bit_deviation * 10) >> 7);
1273 
1274         /*The credit limit is not completly built, hence the average  operating bitrate will be lesser than average*/
1275         //if(ps_cbr_buffer->i8_ebf_bit_alloc >= 0)
1276         //Disabling this to avoid under-consumption of bits since mostly contents will end with simpler sequence
1277         if(1 != ps_cbr_buffer->i4_capped_vbr_on)
1278         {
1279             /*adjust the excess bits to account for deviation in bitrate
1280             If bit deviation is positive then overconsumption, hence resuce the default bit allocation*/
1281 
1282             /* In capped vbr mode this is not calculated as there is no constraint to meet the configured bitrate */
1283             i8_excess_bits -= (bit_dev_so_far / num_intra_period_in_Ravg_dur);
1284         }
1285         /*allocate bits based on complexity*/
1286         /*comp_to_bit_mapped less than 1 implies a content that requires less than average bitrate,
1287           hence due to sign reversal we tend to steal bits*/
1288         comp_based_excess = (LWORD64)((comp_to_bit_mapped - 1) * default_allocation_for_period);
1289 
1290         if(1 != ps_cbr_buffer->i4_capped_vbr_on)
1291         {
1292             /*clip the complexity based on intra period and credit limit buffer size so that when credit limit is lower not everything is used for first GOP*/
1293             if(comp_based_excess > i8_buf_based_limit_inc)
1294             {
1295                 comp_based_excess = i8_buf_based_limit_inc;
1296             }
1297             else if(comp_based_excess < -i8_buf_based_limit_red)
1298             {
1299                 comp_based_excess = -i8_buf_based_limit_red;
1300             }
1301 
1302             /*when the credit limit is fully used, stop giving extra*/
1303             if(credit_limit_level > ps_cbr_buffer->u4_vbr_max_bit_deviation)
1304             {
1305                 if(comp_based_excess < 0)
1306                     i8_excess_bits += comp_based_excess;
1307             }
1308             /*when credit limit is almost full (80 percent full)*/
1309             else if(credit_limit_level > (LWORD64)(ps_cbr_buffer->u4_vbr_max_bit_deviation * 0.8f))
1310             {
1311                 /*follow smooth transition, at 80% utilized the excess should be 100 percent, it should move to zero percent as it approaches 100% utlization*/
1312                 if(comp_based_excess > 0)
1313                     i8_excess_bits += (LWORD64)(
1314                         ((ps_cbr_buffer->u4_vbr_max_bit_deviation - credit_limit_level) /
1315                          (0.2f * ps_cbr_buffer->u4_vbr_max_bit_deviation)) *
1316                         comp_based_excess);
1317                 else
1318                     i8_excess_bits += comp_based_excess;
1319             }
1320             else if(credit_limit_level > (LWORD64)(ps_cbr_buffer->u4_vbr_max_bit_deviation * 0.2f))
1321             {
1322                 i8_excess_bits += comp_based_excess;
1323             }
1324             /*When credit limit is almost unutilized*/
1325             else if(
1326                 credit_limit_level < (WORD32)(ps_cbr_buffer->u4_vbr_max_bit_deviation * 0.2f) &&
1327                 credit_limit_level > 0)
1328             {
1329                 if(comp_based_excess < 0)
1330                     i8_excess_bits += (LWORD64)(
1331                         (credit_limit_level / (0.2f * ps_cbr_buffer->u4_vbr_max_bit_deviation)) *
1332                         comp_based_excess);
1333                 else
1334                     i8_excess_bits += comp_based_excess;
1335             }
1336             /*If the credit limit still uutilized stop drawing bits from simpler content*/
1337             else if(credit_limit_level <= 0)
1338             {
1339                 if(comp_based_excess > 0)
1340                     i8_excess_bits += comp_based_excess;
1341             }
1342             else
1343                 ASSERT(0);
1344         }
1345         else
1346         {
1347             /* In capped vbr mode excess bits will be based on complexity of content alone*/
1348             i8_excess_bits = comp_based_excess;
1349         }
1350 
1351         /*Clip the excess bits such that it will never violate peak bitrate and also Rmin*/
1352         if(i8_excess_bits > max_excess_bits)
1353             i8_excess_bits = max_excess_bits;
1354         /*assuming atleast 0.4 times average bitrate even for the simplest content*/
1355         if(i8_excess_bits < -(default_allocation_for_period * 0.6f))
1356             i8_excess_bits = (LWORD64)(-(default_allocation_for_period * 0.6f));
1357 
1358         ASSERT(i8_excess_bits <= 0x7FFFFFFF);
1359         return (WORD32)i8_excess_bits;
1360     }
1361 }
1362 /* ******************************************************************************/
1363 /**
1364  * @brief get_rc_type.
1365   *
1366  * @param ps_cbr_buffer
1367  */
1368 /* ******************************************************************************/
get_rc_type(cbr_buffer_t * ps_cbr_buffer)1369 rc_type_e get_rc_type(cbr_buffer_t *ps_cbr_buffer)
1370 {
1371     return (ps_cbr_buffer->e_rc_type);
1372 }
1373 /* ******************************************************************************/
1374 /**
1375  * @brief cbr_get_delay_frames
1376   *
1377  * @param ps_cbr_buffer
1378  */
1379 /* ******************************************************************************/
cbr_get_delay_frames(cbr_buffer_t * ps_cbr_buffer)1380 UWORD32 cbr_get_delay_frames(cbr_buffer_t *ps_cbr_buffer)
1381 {
1382     return (ps_cbr_buffer->u4_num_frms_in_delay);
1383 }
1384 #endif /* #if NON_STEADSTATE_CODE */
1385