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