/src/libhevc/encoder/vbr_storage_vbv.c
Line | Count | Source |
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 | 0 | #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 | | |
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 | 49.4k | { |
75 | 49.4k | WORD32 i4_mem_tab_idx = 0; |
76 | 49.4k | 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 | 49.4k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
81 | 42.3k | (*pps_vbr_storage_vbv) = &s_vbr_storage_vbv_temp; |
82 | | |
83 | | /*for src rate control state structure*/ |
84 | 49.4k | if(e_func_type != GET_NUM_MEMTAB) |
85 | 21.1k | { |
86 | 21.1k | fill_memtab( |
87 | 21.1k | &ps_memtab[i4_mem_tab_idx], |
88 | 21.1k | sizeof(vbr_storage_vbv_t), |
89 | 21.1k | MEM_TAB_ALIGNMENT, |
90 | 21.1k | PERSISTENT, |
91 | 21.1k | DDR); |
92 | 21.1k | use_or_fill_base(&ps_memtab[0], (void **)pps_vbr_storage_vbv, e_func_type); |
93 | 21.1k | } |
94 | 49.4k | i4_mem_tab_idx++; |
95 | | |
96 | 49.4k | i4_mem_tab_idx += error_bits_num_fill_use_free_memtab( |
97 | 49.4k | &pps_vbr_storage_vbv[0]->ps_error_bits, &ps_memtab[i4_mem_tab_idx], e_func_type); |
98 | 49.4k | return (i4_mem_tab_idx); |
99 | 49.4k | } |
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 | | *****************************************************************************/ |
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 | 0 | { |
114 | 0 | ps_vbr_storage_vbv->i4_max_buf_size = i4_max_vbv_buff_size; |
115 | 0 | 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 | 0 | X_PROD_Y_DIV_Z( |
120 | 0 | 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 | 0 | init_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate, i4_max_bit_rate); |
124 | | |
125 | | /* Storing the input values */ |
126 | 0 | ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate; |
127 | 0 | ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate; |
128 | 0 | } |
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 | | *****************************************************************************/ |
138 | | void update_vbr_vbv(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_total_bits_decoded) |
139 | 0 | { |
140 | 0 | 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 | 0 | overflow_avoided_summation( |
144 | 0 | &ps_vbr_storage_vbv->i4_cur_buf_size, |
145 | 0 | (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits)); |
146 | |
|
147 | 0 | if(ps_vbr_storage_vbv->i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size) |
148 | 0 | { |
149 | 0 | ps_vbr_storage_vbv->i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size; |
150 | 0 | } |
151 | |
|
152 | 0 | ps_vbr_storage_vbv->i4_cur_buf_size -= i4_total_bits_decoded; |
153 | | |
154 | | /* Update the error bits state */ |
155 | 0 | update_error_bits(ps_vbr_storage_vbv->ps_error_bits); |
156 | |
|
157 | 0 | #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 | 0 | } |
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 | | *****************************************************************************/ |
171 | | WORD32 get_max_target_bits(vbr_storage_vbv_t *ps_vbr_storage_vbv) |
172 | 0 | { |
173 | 0 | WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size; |
174 | 0 | 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 | 0 | overflow_avoided_summation( |
178 | 0 | &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits)); |
179 | 0 | if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size) |
180 | 0 | { |
181 | 0 | i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size; |
182 | 0 | } |
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 | 0 | return i4_cur_buf_size; |
187 | 0 | } |
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 | | *****************************************************************************/ |
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 | 0 | { |
206 | 0 | vbv_buf_status_e e_buf_status; |
207 | 0 | WORD32 i4_cur_buf; |
208 | 0 | 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 | 0 | i4_cur_buf = ps_vbr_storage_vbv->i4_cur_buf_size; |
212 | 0 | overflow_avoided_summation( |
213 | 0 | &i4_cur_buf, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits)); |
214 | |
|
215 | 0 | if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size) |
216 | 0 | { |
217 | 0 | i4_cur_buf = ps_vbr_storage_vbv->i4_max_buf_size; |
218 | 0 | } |
219 | |
|
220 | 0 | pi4_num_bits_to_prevent_vbv_underflow[0] = i4_cur_buf; |
221 | |
|
222 | 0 | i4_cur_buf -= i4_total_frame_bits; |
223 | 0 | if(i4_cur_buf < 0) |
224 | 0 | { |
225 | 0 | e_buf_status = VBV_UNDERFLOW; |
226 | 0 | } |
227 | 0 | else if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size) |
228 | 0 | { |
229 | 0 | e_buf_status = VBV_OVERFLOW; |
230 | 0 | } |
231 | 0 | else if(i4_cur_buf < (ps_vbr_storage_vbv->i4_max_buf_size >> 2)) |
232 | 0 | { |
233 | 0 | e_buf_status = VBR_CAUTION; |
234 | 0 | } |
235 | 0 | else |
236 | 0 | { |
237 | 0 | e_buf_status = VBV_NORMAL; |
238 | 0 | } |
239 | |
|
240 | 0 | return e_buf_status; |
241 | 0 | } |
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 | | *****************************************************************************/ |
250 | | WORD32 get_max_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv) |
251 | 0 | { |
252 | 0 | return (ps_vbr_storage_vbv->i4_max_buf_size); |
253 | 0 | } |
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 | | *****************************************************************************/ |
262 | | WORD32 get_cur_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv) |
263 | 0 | { |
264 | 0 | return (ps_vbr_storage_vbv->i4_cur_buf_size); |
265 | 0 | } |
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 | | *****************************************************************************/ |
274 | | WORD32 get_max_bits_inflow_per_frm_periode(vbr_storage_vbv_t *ps_vbr_storage_vbv) |
275 | 0 | { |
276 | 0 | return (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period); |
277 | 0 | } |
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 | | *****************************************************************************/ |
287 | | WORD32 get_vbv_buf_fullness(vbr_storage_vbv_t *ps_vbr_storage_vbv, UWORD32 u4_bits) |
288 | 0 | { |
289 | 0 | WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits); |
290 | 0 | WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size; |
291 | |
|
292 | 0 | overflow_avoided_summation( |
293 | 0 | &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits)); |
294 | |
|
295 | 0 | if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size) |
296 | 0 | { |
297 | 0 | i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size; |
298 | 0 | } |
299 | |
|
300 | 0 | 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 | 0 | return (i4_cur_buf_size); |
307 | 0 | } |
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 | | *****************************************************************************/ |
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 | 0 | { |
322 | 0 | WORD32 i4_dbf_max, i4_dbf_min, i4_dbf_prev, i4_vbv_size, i4_dbf_desired; |
323 | 0 | WORD32 i4_max_tgt_bits; |
324 | |
|
325 | 0 | i4_vbv_size = ps_vbr_storage_vbv->i4_max_buf_size; |
326 | 0 | i4_dbf_max = 95 * i4_vbv_size / 100; |
327 | 0 | i4_dbf_min = 10 * i4_vbv_size / 100; |
328 | 0 | i4_dbf_prev = ps_vbr_storage_vbv->i4_cur_buf_size; |
329 | |
|
330 | 0 | if(i4_rem_bits_in_gop < 0) |
331 | 0 | i4_rem_bits_in_gop = 0; |
332 | 0 | if(i4_rem_frms_in_gop <= 0) |
333 | 0 | i4_rem_frms_in_gop = 1; |
334 | |
|
335 | 0 | if(e_pic_type == I_PIC) |
336 | 0 | { |
337 | 0 | i4_dbf_desired = i4_dbf_min; |
338 | 0 | } |
339 | 0 | else |
340 | 0 | { |
341 | 0 | i4_dbf_desired = (i4_dbf_max - i4_rem_bits_in_gop / i4_rem_frms_in_gop - i4_dbf_prev) / |
342 | 0 | i4_rem_frms_in_gop; |
343 | 0 | i4_dbf_desired += i4_dbf_prev; |
344 | 0 | } |
345 | |
|
346 | 0 | i4_dbf_prev += ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period; |
347 | 0 | if(i4_dbf_prev > ps_vbr_storage_vbv->i4_max_buf_size) |
348 | 0 | { |
349 | 0 | i4_dbf_prev = ps_vbr_storage_vbv->i4_max_buf_size; |
350 | 0 | } |
351 | |
|
352 | 0 | i4_max_tgt_bits = MAX(0, (i4_dbf_prev - i4_dbf_desired)); |
353 | 0 | return (i4_max_tgt_bits); |
354 | 0 | } |
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 | | *****************************************************************************/ |
365 | | void change_vbr_vbv_frame_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_frm_rate) |
366 | 0 | { |
367 | | /* Calculate the max number of bits that flow into the decoder |
368 | | in the interval of two frames */ |
369 | 0 | X_PROD_Y_DIV_Z( |
370 | 0 | ps_vbr_storage_vbv->i4_max_bit_rate, |
371 | 0 | 1000, |
372 | 0 | i4_frm_rate, |
373 | 0 | ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period); |
374 | | |
375 | | /* update the lower modules */ |
376 | 0 | change_frm_rate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate); |
377 | | /* Storing the input values */ |
378 | 0 | ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate; |
379 | 0 | } |
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 | | *****************************************************************************/ |
388 | | void change_vbr_vbv_bit_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_max_bit_rate) |
389 | 0 | { |
390 | | /* Calculate the max number of bits that flow into the decoder |
391 | | in the interval of two frames */ |
392 | 0 | X_PROD_Y_DIV_Z( |
393 | 0 | i4_max_bit_rate, |
394 | 0 | 1000, |
395 | 0 | ps_vbr_storage_vbv->i4_max_frame_rate, |
396 | 0 | ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period); |
397 | | |
398 | | /* update the lower modules */ |
399 | 0 | change_bitrate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_max_bit_rate); |
400 | | |
401 | | /* Storing the input values */ |
402 | 0 | ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate; |
403 | 0 | } |
404 | | #endif /* #if NON_STEADSTATE_CODE */ |