• 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 vbr_storage_vbv.c
23 *
24 * \brief
25 *    This file contain functions related to VBV buffer
26 *
27 * \date
28 *
29 * \author
30 *    ittiam
31 *
32 ******************************************************************************
33 */
34 /*****************************************************************************/
35 /* File Includes                                                             */
36 /*****************************************************************************/
37 /* System include files */
38 #include <stdio.h>
39 
40 /* User include files */
41 #include "ittiam_datatypes.h"
42 #include "mem_req_and_acq.h"
43 #include "rc_common.h"
44 #include "rc_cntrl_param.h"
45 #include "var_q_operator.h"
46 #include "fixed_point_error_bits.h"
47 #include "cbr_buffer_control.h"
48 #include "rc_rd_model.h"
49 #include "est_sad.h"
50 #include "cbr_buffer_control.h"
51 #include "picture_type.h"
52 #include "bit_allocation.h"
53 #include "vbr_storage_vbv.h"
54 #include "trace_support.h"
55 
56 #define MAX(x, y) ((x) > (y) ? (x) : (y))
57 
58 typedef struct vbr_storage_vbv_t
59 {
60     WORD32 i4_max_buf_size;
61     WORD32 i4_cur_buf_size;
62     WORD32 i4_max_bits_inflow_per_frm_period;
63     /* Storing input variables */
64     WORD32 i4_max_bit_rate;
65     WORD32 i4_max_frame_rate;
66     /* Error bits calculation module */
67     error_bits_handle ps_error_bits;
68 } vbr_storage_vbv_t;
69 
70 #if NON_STEADSTATE_CODE
71 
vbr_vbv_num_fill_use_free_memtab(vbr_storage_vbv_t ** pps_vbr_storage_vbv,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)72 WORD32 vbr_vbv_num_fill_use_free_memtab(
73     vbr_storage_vbv_t **pps_vbr_storage_vbv, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
74 {
75     WORD32 i4_mem_tab_idx = 0;
76     static vbr_storage_vbv_t s_vbr_storage_vbv_temp;
77 
78     /* Hack for al alloc, during which we dont have any state memory.
79       Dereferencing can cause issues */
80     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
81         (*pps_vbr_storage_vbv) = &s_vbr_storage_vbv_temp;
82 
83     /*for src rate control state structure*/
84     if(e_func_type != GET_NUM_MEMTAB)
85     {
86         fill_memtab(
87             &ps_memtab[i4_mem_tab_idx],
88             sizeof(vbr_storage_vbv_t),
89             MEM_TAB_ALIGNMENT,
90             PERSISTENT,
91             DDR);
92         use_or_fill_base(&ps_memtab[0], (void **)pps_vbr_storage_vbv, e_func_type);
93     }
94     i4_mem_tab_idx++;
95 
96     i4_mem_tab_idx += error_bits_num_fill_use_free_memtab(
97         &pps_vbr_storage_vbv[0]->ps_error_bits, &ps_memtab[i4_mem_tab_idx], e_func_type);
98     return (i4_mem_tab_idx);
99 }
100 /******************************************************************************
101   Function Name   : init_vbr_vbv
102   Description     :
103   Arguments       : ps_vbr_storage_vbv
104   Return Values   : void
105   Revision History:
106                     Creation
107 *****************************************************************************/
init_vbr_vbv(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_max_bit_rate,WORD32 i4_frm_rate,WORD32 i4_max_vbv_buff_size)108 void init_vbr_vbv(
109     vbr_storage_vbv_t *ps_vbr_storage_vbv,
110     WORD32 i4_max_bit_rate,
111     WORD32 i4_frm_rate,
112     WORD32 i4_max_vbv_buff_size)
113 {
114     ps_vbr_storage_vbv->i4_max_buf_size = i4_max_vbv_buff_size;
115     ps_vbr_storage_vbv->i4_cur_buf_size = i4_max_vbv_buff_size;
116 
117     /* Calculate the max number of bits that flow into the decoder
118     in the interval of two frames */
119     X_PROD_Y_DIV_Z(
120         i4_max_bit_rate, 1000, i4_frm_rate, ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
121 
122     /* init error bits */
123     init_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate, i4_max_bit_rate);
124 
125     /* Storing the input values */
126     ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate;
127     ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate;
128 }
129 #endif /* #if NON_STEADSTATE_CODE */
130 /******************************************************************************
131   Function Name   : update_vbr_vbv
132   Description     :
133   Arguments       : ps_vbr_storage_vbv
134   Return Values   : void
135   Revision History:
136                     Creation
137 *****************************************************************************/
update_vbr_vbv(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_total_bits_decoded)138 void update_vbr_vbv(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_total_bits_decoded)
139 {
140     WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
141     /* In the time interval between two decoded frames the buffer would have been
142        filled up by the max_bits_inflow_per_frm_period.*/
143     overflow_avoided_summation(
144         &ps_vbr_storage_vbv->i4_cur_buf_size,
145         (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
146 
147     if(ps_vbr_storage_vbv->i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
148     {
149         ps_vbr_storage_vbv->i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
150     }
151 
152     ps_vbr_storage_vbv->i4_cur_buf_size -= i4_total_bits_decoded;
153 
154     /* Update the error bits state */
155     update_error_bits(ps_vbr_storage_vbv->ps_error_bits);
156 
157 #define PRINT_UNDERFLOW 0
158 #if PRINT_UNDERFLOW
159     if(ps_vbr_storage_vbv->i4_cur_buf_size < 0)
160         printf("The buffer underflows \n");
161 #endif
162 }
163 /******************************************************************************
164   Function Name   : get_max_target_bits
165   Description     :
166   Arguments       : ps_vbr_storage_vbv
167   Return Values   : void
168   Revision History:
169                     Creation
170 *****************************************************************************/
get_max_target_bits(vbr_storage_vbv_t * ps_vbr_storage_vbv)171 WORD32 get_max_target_bits(vbr_storage_vbv_t *ps_vbr_storage_vbv)
172 {
173     WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size;
174     WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
175 
176     /* The buffer size when the next frame is decoded */
177     overflow_avoided_summation(
178         &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
179     if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
180     {
181         i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
182     }
183 
184     /* Thus for the next frame the maximum number of bits the decoder can consume
185     without underflow is i4_cur_buf_size */
186     return i4_cur_buf_size;
187 }
188 
189 /****************************************************************************
190 Function Name : get_buffer_status
191 Description   : Gets the state of VBV buffer
192 Inputs        : Rate control API , header and texture bits
193 Globals       :
194 Processing    :
195 Outputs       : 0 = normal, 1 = underflow, 2= overflow
196 Returns       : vbv_buf_status_e
197 Issues        :
198 Revision History:
199 DD MM YYYY   Author(s)       Changes (Describe the changes made)
200 *****************************************************************************/
get_vbv_buffer_status(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_total_frame_bits,WORD32 * pi4_num_bits_to_prevent_vbv_underflow)201 vbv_buf_status_e get_vbv_buffer_status(
202     vbr_storage_vbv_t *ps_vbr_storage_vbv,
203     WORD32 i4_total_frame_bits, /* Total frame bits consumed */
204     WORD32 *pi4_num_bits_to_prevent_vbv_underflow) /* The curent buffer status after updation */
205 {
206     vbv_buf_status_e e_buf_status;
207     WORD32 i4_cur_buf;
208     WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
209 
210     /* error bits due to fixed point computation of drain rate*/
211     i4_cur_buf = ps_vbr_storage_vbv->i4_cur_buf_size;
212     overflow_avoided_summation(
213         &i4_cur_buf, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
214 
215     if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size)
216     {
217         i4_cur_buf = ps_vbr_storage_vbv->i4_max_buf_size;
218     }
219 
220     pi4_num_bits_to_prevent_vbv_underflow[0] = i4_cur_buf;
221 
222     i4_cur_buf -= i4_total_frame_bits;
223     if(i4_cur_buf < 0)
224     {
225         e_buf_status = VBV_UNDERFLOW;
226     }
227     else if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size)
228     {
229         e_buf_status = VBV_OVERFLOW;
230     }
231     else if(i4_cur_buf < (ps_vbr_storage_vbv->i4_max_buf_size >> 2))
232     {
233         e_buf_status = VBR_CAUTION;
234     }
235     else
236     {
237         e_buf_status = VBV_NORMAL;
238     }
239 
240     return e_buf_status;
241 }
242 /******************************************************************************
243   Function Name   : get_max_vbv_buf_size
244   Description     :
245   Arguments       : ps_vbr_storage_vbv
246   Return Values   : void
247   Revision History:
248                     Creation
249 *****************************************************************************/
get_max_vbv_buf_size(vbr_storage_vbv_t * ps_vbr_storage_vbv)250 WORD32 get_max_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv)
251 {
252     return (ps_vbr_storage_vbv->i4_max_buf_size);
253 }
254 /******************************************************************************
255   Function Name   : get_cur_vbv_buf_size
256   Description     :
257   Arguments       : ps_vbr_storage_vbv
258   Return Values   : void
259   Revision History:
260                     Creation
261 *****************************************************************************/
get_cur_vbv_buf_size(vbr_storage_vbv_t * ps_vbr_storage_vbv)262 WORD32 get_cur_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv)
263 {
264     return (ps_vbr_storage_vbv->i4_cur_buf_size);
265 }
266 /******************************************************************************
267   Function Name   : get_max_bits_inflow_per_frm_periode
268   Description     :
269   Arguments       : ps_vbr_storage_vbv
270   Return Values   : void
271   Revision History:
272                     Creation
273 *****************************************************************************/
get_max_bits_inflow_per_frm_periode(vbr_storage_vbv_t * ps_vbr_storage_vbv)274 WORD32 get_max_bits_inflow_per_frm_periode(vbr_storage_vbv_t *ps_vbr_storage_vbv)
275 {
276     return (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
277 }
278 
279 /******************************************************************************
280   Function Name   : get_vbv_buf_fullness
281   Description     :
282   Arguments       : ps_vbr_storage_vbv
283   Return Values   : void
284   Revision History:
285                     Creation
286 *****************************************************************************/
get_vbv_buf_fullness(vbr_storage_vbv_t * ps_vbr_storage_vbv,UWORD32 u4_bits)287 WORD32 get_vbv_buf_fullness(vbr_storage_vbv_t *ps_vbr_storage_vbv, UWORD32 u4_bits)
288 {
289     WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
290     WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size;
291 
292     overflow_avoided_summation(
293         &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
294 
295     if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
296     {
297         i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
298     }
299 
300     i4_cur_buf_size -= u4_bits;
301 
302 #if PRINT_UNDERFLOW
303     if(i4_cur_buf_size < 0)
304         printf("The buffer underflows \n");
305 #endif
306     return (i4_cur_buf_size);
307 }
308 /******************************************************************************
309   Function Name   : get_max_tgt_bits_dvd_comp
310   Description     :
311   Arguments       : ps_vbr_storage_vbv
312   Return Values   : void
313   Revision History:
314                     Creation
315 *****************************************************************************/
get_max_tgt_bits_dvd_comp(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_rem_bits_in_gop,WORD32 i4_rem_frms_in_gop,picture_type_e e_pic_type)316 WORD32 get_max_tgt_bits_dvd_comp(
317     vbr_storage_vbv_t *ps_vbr_storage_vbv,
318     WORD32 i4_rem_bits_in_gop,
319     WORD32 i4_rem_frms_in_gop,
320     picture_type_e e_pic_type)
321 {
322     WORD32 i4_dbf_max, i4_dbf_min, i4_dbf_prev, i4_vbv_size, i4_dbf_desired;
323     WORD32 i4_max_tgt_bits;
324 
325     i4_vbv_size = ps_vbr_storage_vbv->i4_max_buf_size;
326     i4_dbf_max = 95 * i4_vbv_size / 100;
327     i4_dbf_min = 10 * i4_vbv_size / 100;
328     i4_dbf_prev = ps_vbr_storage_vbv->i4_cur_buf_size;
329 
330     if(i4_rem_bits_in_gop < 0)
331         i4_rem_bits_in_gop = 0;
332     if(i4_rem_frms_in_gop <= 0)
333         i4_rem_frms_in_gop = 1;
334 
335     if(e_pic_type == I_PIC)
336     {
337         i4_dbf_desired = i4_dbf_min;
338     }
339     else
340     {
341         i4_dbf_desired = (i4_dbf_max - i4_rem_bits_in_gop / i4_rem_frms_in_gop - i4_dbf_prev) /
342                          i4_rem_frms_in_gop;
343         i4_dbf_desired += i4_dbf_prev;
344     }
345 
346     i4_dbf_prev += ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period;
347     if(i4_dbf_prev > ps_vbr_storage_vbv->i4_max_buf_size)
348     {
349         i4_dbf_prev = ps_vbr_storage_vbv->i4_max_buf_size;
350     }
351 
352     i4_max_tgt_bits = MAX(0, (i4_dbf_prev - i4_dbf_desired));
353     return (i4_max_tgt_bits);
354 }
355 
356 #if NON_STEADSTATE_CODE
357 /******************************************************************************
358   Function Name   : change_vbr_vbv_frame_rate
359   Description     :
360   Arguments       : ps_vbr_storage_vbv
361   Return Values   : void
362   Revision History:
363                     Creation
364 *****************************************************************************/
change_vbr_vbv_frame_rate(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_frm_rate)365 void change_vbr_vbv_frame_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_frm_rate)
366 {
367     /* Calculate the max number of bits that flow into the decoder
368     in the interval of two frames */
369     X_PROD_Y_DIV_Z(
370         ps_vbr_storage_vbv->i4_max_bit_rate,
371         1000,
372         i4_frm_rate,
373         ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
374 
375     /* update the lower modules */
376     change_frm_rate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate);
377     /* Storing the input values */
378     ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate;
379 }
380 /******************************************************************************
381   Function Name   : change_vbr_vbv_bit_rate
382   Description     :
383   Arguments       : ps_vbr_storage_vbv
384   Return Values   : void
385   Revision History:
386                     Creation
387 *****************************************************************************/
change_vbr_vbv_bit_rate(vbr_storage_vbv_t * ps_vbr_storage_vbv,WORD32 i4_max_bit_rate)388 void change_vbr_vbv_bit_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_max_bit_rate)
389 {
390     /* Calculate the max number of bits that flow into the decoder
391     in the interval of two frames */
392     X_PROD_Y_DIV_Z(
393         i4_max_bit_rate,
394         1000,
395         ps_vbr_storage_vbv->i4_max_frame_rate,
396         ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
397 
398     /* update the lower modules */
399     change_bitrate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_max_bit_rate);
400 
401     /* Storing the input values */
402     ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate;
403 }
404 #endif /* #if NON_STEADSTATE_CODE */
405