/src/libavc/encoder/irc_cbr_buffer_control.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2015 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 Includes */ |
23 | | /*****************************************************************************/ |
24 | | |
25 | | /* System include files */ |
26 | | #include <stdio.h> |
27 | | |
28 | | /* User include files */ |
29 | | #include "irc_datatypes.h" |
30 | | #include "irc_cntrl_param.h" |
31 | | #include "irc_common.h" |
32 | | #include "irc_mem_req_and_acq.h" |
33 | | #include "irc_fixed_point_error_bits.h" |
34 | | #include "irc_cbr_buffer_control.h" |
35 | | #include "irc_trace_support.h" |
36 | | |
37 | | typedef struct cbr_buffer_t |
38 | | { |
39 | | /* Buffer size = Delay * Bitrate*/ |
40 | | WORD32 i4_buffer_size; |
41 | | |
42 | | /* Constant drain rate */ |
43 | | WORD32 i4_drain_bits_per_frame[MAX_NUM_DRAIN_RATES]; |
44 | | |
45 | | /* Encoder Buffer Fullness */ |
46 | | WORD32 i4_ebf; |
47 | | |
48 | | /* Upper threshold of the Buffer */ |
49 | | WORD32 i4_upr_thr[MAX_PIC_TYPE]; |
50 | | |
51 | | /* Lower threshold of the Buffer */ |
52 | | WORD32 i4_low_thr[MAX_PIC_TYPE]; |
53 | | |
54 | | /* Stuffing threshold equal to error bits per second in the drain bits |
55 | | * fixed point computation */ |
56 | | WORD32 i4_stuffing_threshold; |
57 | | |
58 | | /* For error due to bits per frame calculation */ |
59 | | error_bits_handle aps_bpf_error_bits[MAX_NUM_DRAIN_RATES]; |
60 | | |
61 | | /* Whether the buffer model is used for CBR or VBR streaming */ |
62 | | WORD32 i4_is_cbr_mode; |
63 | | |
64 | | /* Input parameters stored for initialization */ |
65 | | WORD32 ai4_bit_rate[MAX_NUM_DRAIN_RATES]; |
66 | | |
67 | | WORD32 i4_max_delay; |
68 | | |
69 | | WORD32 ai4_num_pics_in_delay_period[MAX_PIC_TYPE]; |
70 | | |
71 | | WORD32 i4_tgt_frm_rate; |
72 | | |
73 | | UWORD32 u4_max_vbv_buf_size; |
74 | | |
75 | | } cbr_buffer_t; |
76 | | |
77 | | WORD32 irc_cbr_buffer_num_fill_use_free_memtab(cbr_buffer_t **pps_cbr_buffer, |
78 | | itt_memtab_t *ps_memtab, |
79 | | ITT_FUNC_TYPE_E e_func_type) |
80 | 118k | { |
81 | 118k | WORD32 i4_mem_tab_idx = 0, i; |
82 | 118k | cbr_buffer_t s_cbr_buffer_temp; |
83 | | |
84 | | /* |
85 | | * Hack for all alloc, during which we don't have any state memory. |
86 | | * Dereferencing can cause issues |
87 | | */ |
88 | 118k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
89 | 99.0k | (*pps_cbr_buffer) = &s_cbr_buffer_temp; |
90 | | |
91 | 118k | if(e_func_type != GET_NUM_MEMTAB) |
92 | 59.4k | { |
93 | 59.4k | fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(cbr_buffer_t), |
94 | 59.4k | ALIGN_128_BYTE, PERSISTENT, DDR); |
95 | 59.4k | use_or_fill_base(&ps_memtab[0], (void**)pps_cbr_buffer, e_func_type); |
96 | 59.4k | } |
97 | 118k | i4_mem_tab_idx++; |
98 | | |
99 | 356k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
100 | 237k | { |
101 | 237k | i4_mem_tab_idx += irc_error_bits_num_fill_use_free_memtab( |
102 | 237k | &pps_cbr_buffer[0]->aps_bpf_error_bits[i], |
103 | 237k | &ps_memtab[i4_mem_tab_idx], e_func_type); |
104 | 237k | } |
105 | 118k | return (i4_mem_tab_idx); |
106 | 118k | } |
107 | | |
108 | | /****************************************************************************** |
109 | | * @brief Initialize the CBR VBV buffer state. |
110 | | * This could however be used for VBR streaming VBV also |
111 | | * |
112 | | ******************************************************************************/ |
113 | | void irc_init_cbr_buffer(cbr_buffer_t *ps_cbr_buffer, |
114 | | WORD32 i4_buffer_delay, |
115 | | WORD32 i4_tgt_frm_rate, |
116 | | WORD32 *i4_bit_rate, |
117 | | UWORD32 *u4_num_pics_in_delay_prd, |
118 | | UWORD32 u4_vbv_buf_size) |
119 | 25.7k | { |
120 | 25.7k | WORD32 i4_i, i4_bits_per_frm[MAX_NUM_DRAIN_RATES]; |
121 | 25.7k | int i; |
122 | | |
123 | 77.1k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
124 | 51.4k | { |
125 | 51.4k | X_PROD_Y_DIV_Z(i4_bit_rate[i], 1000, i4_tgt_frm_rate, |
126 | 51.4k | i4_bits_per_frm[i]); |
127 | | /* Drain rate = bitrate/(framerate/1000) */ |
128 | 51.4k | ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i]; |
129 | | /* Initialize the bits per frame error bits calculation */ |
130 | 51.4k | irc_init_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], |
131 | 51.4k | i4_tgt_frm_rate, i4_bit_rate[i]); |
132 | 51.4k | } |
133 | | |
134 | | /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/ |
135 | | /* This would mean CBR mode */ |
136 | 25.7k | if(i4_bit_rate[0] == i4_bit_rate[1]) |
137 | 25.7k | { |
138 | 25.7k | X_PROD_Y_DIV_Z(i4_bit_rate[0], i4_buffer_delay, 1000, |
139 | 25.7k | ps_cbr_buffer->i4_buffer_size); |
140 | 25.7k | ps_cbr_buffer->i4_is_cbr_mode = 1; |
141 | 25.7k | } |
142 | 0 | else |
143 | 0 | { |
144 | | /* VBR streaming case which has different drain rates for I and P */ |
145 | 0 | ps_cbr_buffer->i4_buffer_size = u4_num_pics_in_delay_prd[0] |
146 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[0] |
147 | 0 | + u4_num_pics_in_delay_prd[1] |
148 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
149 | |
|
150 | 0 | ps_cbr_buffer->i4_is_cbr_mode = 0; |
151 | 0 | } |
152 | | |
153 | 25.7k | if(ps_cbr_buffer->i4_buffer_size > (WORD32)u4_vbv_buf_size) |
154 | 2.88k | { |
155 | 2.88k | ps_cbr_buffer->i4_buffer_size = u4_vbv_buf_size; |
156 | 2.88k | } |
157 | | |
158 | | /* Initially Encoder buffer fullness is zero */ |
159 | 25.7k | ps_cbr_buffer->i4_ebf = 0; |
160 | | |
161 | | /* tgt_frame_rate is divided by 1000 because, an approximate value is fine |
162 | | * as this is just a threshold below which stuffing is done to avoid buffer |
163 | | * underflow due to fixed point error in drain rate |
164 | | */ |
165 | 25.7k | ps_cbr_buffer->i4_stuffing_threshold = (i4_bit_rate[0] |
166 | 25.7k | - (i4_bits_per_frm[0] * (i4_tgt_frm_rate / 1000))); |
167 | | |
168 | 102k | for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++) |
169 | 77.1k | { |
170 | | /* |
171 | | * Upper threshold for |
172 | | * I frame = 1 * bits per frame |
173 | | * P Frame = 4 * bits per frame. |
174 | | * The threshold for I frame is only 1 * bits per frame as the threshold |
175 | | * should only account for error in estimated bits. |
176 | | * In P frame it should account for difference bets bits consumed by |
177 | | * I(Scene change) and P frame I to P complexity is assumed to be 5. |
178 | | */ |
179 | 77.1k | WORD32 i4_index; |
180 | 77.1k | i4_index = i4_i > 0 ? 1 : 0; |
181 | 77.1k | ps_cbr_buffer->i4_upr_thr[i4_i] = ps_cbr_buffer->i4_buffer_size |
182 | 77.1k | - (ps_cbr_buffer->i4_buffer_size >> 3); |
183 | | |
184 | | /* |
185 | | * For both I and P frame Lower threshold is equal to drain rate.Even if |
186 | | * the encoder consumes zero bits it should have enough bits to drain |
187 | | */ |
188 | 77.1k | ps_cbr_buffer->i4_low_thr[i4_i] = i4_bits_per_frm[i4_index]; |
189 | 77.1k | } |
190 | | |
191 | | /* Storing the input parameters for using it for change functions */ |
192 | 77.1k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
193 | 51.4k | { |
194 | 51.4k | ps_cbr_buffer->ai4_bit_rate[i] = i4_bit_rate[i]; |
195 | 51.4k | } |
196 | | |
197 | 102k | for(i = 0; i < MAX_PIC_TYPE; i++) |
198 | 77.1k | { |
199 | 77.1k | ps_cbr_buffer->ai4_num_pics_in_delay_period[i] = |
200 | 77.1k | u4_num_pics_in_delay_prd[i]; |
201 | 77.1k | } |
202 | 25.7k | ps_cbr_buffer->i4_tgt_frm_rate = i4_tgt_frm_rate; |
203 | 25.7k | ps_cbr_buffer->i4_max_delay = i4_buffer_delay; |
204 | 25.7k | ps_cbr_buffer->u4_max_vbv_buf_size = u4_vbv_buf_size; |
205 | 25.7k | } |
206 | | |
207 | | /****************************************************************************** |
208 | | * @brief Condition check for constraining the number of bits allocated based on |
209 | | * bufer size |
210 | | ******************************************************************************/ |
211 | | WORD32 irc_cbr_buffer_constraint_check(cbr_buffer_t *ps_cbr_buffer, |
212 | | WORD32 i4_tgt_bits, |
213 | | picture_type_e e_pic_type) |
214 | 20.0k | { |
215 | 20.0k | WORD32 i4_max_tgt_bits, i4_min_tgt_bits; |
216 | 20.0k | WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC) ? |
217 | 6.58k | ps_cbr_buffer->i4_drain_bits_per_frame[0] : |
218 | 20.0k | ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
219 | | |
220 | | /* Max tgt bits = Upper threshold - current encoder buffer fullness */ |
221 | 20.0k | i4_max_tgt_bits = ps_cbr_buffer->i4_upr_thr[e_pic_type] |
222 | 20.0k | - ps_cbr_buffer->i4_ebf; |
223 | | /* Max tgt bits cannot be negative */ |
224 | 20.0k | if(i4_max_tgt_bits < 0) |
225 | 2.12k | i4_max_tgt_bits = 0; |
226 | | |
227 | | /* |
228 | | * Min tgt bits , least number of bits in the Encoder after |
229 | | * draining such that it is greater than lower threshold |
230 | | */ |
231 | 20.0k | i4_min_tgt_bits = ps_cbr_buffer->i4_low_thr[e_pic_type] |
232 | 20.0k | - (ps_cbr_buffer->i4_ebf - i4_drain_bits_per_frame); |
233 | | /* Min tgt bits cannot be negative */ |
234 | 20.0k | if(i4_min_tgt_bits < 0) |
235 | 6.49k | i4_min_tgt_bits = 0; |
236 | | |
237 | | /* Current tgt bits should be between max and min tgt bits */ |
238 | 20.0k | CLIP(i4_tgt_bits, i4_max_tgt_bits, i4_min_tgt_bits); |
239 | 20.0k | return i4_tgt_bits; |
240 | 20.0k | } |
241 | | |
242 | | /* ***************************************************************************** |
243 | | * @brief constaints the bit allocation based on buffer size |
244 | | * |
245 | | ******************************************************************************/ |
246 | | WORD32 irc_vbr_stream_buffer_constraint_check(cbr_buffer_t *ps_cbr_buffer, |
247 | | WORD32 i4_tgt_bits, |
248 | | picture_type_e e_pic_type) |
249 | 0 | { |
250 | 0 | WORD32 i4_max_tgt_bits; |
251 | | |
252 | | /* Max tgt bits = Upper threshold - current encoder buffer fullness */ |
253 | 0 | i4_max_tgt_bits = ps_cbr_buffer->i4_upr_thr[e_pic_type] |
254 | 0 | - ps_cbr_buffer->i4_ebf; |
255 | | |
256 | | /* Max tgt bits cannot be negative */ |
257 | 0 | if(i4_max_tgt_bits < 0) |
258 | 0 | i4_max_tgt_bits = 0; |
259 | |
|
260 | 0 | if(i4_tgt_bits > i4_max_tgt_bits) |
261 | 0 | i4_tgt_bits = i4_max_tgt_bits; |
262 | |
|
263 | 0 | return i4_tgt_bits; |
264 | 0 | } |
265 | | |
266 | | /* ***************************************************************************** |
267 | | * @brief Verifies the buffer state and returns whether it is overflowing, |
268 | | * underflowing or normal |
269 | | * |
270 | | ******************************************************************************/ |
271 | | vbv_buf_status_e irc_get_cbr_buffer_status(cbr_buffer_t *ps_cbr_buffer, |
272 | | WORD32 i4_tot_consumed_bits, |
273 | | WORD32 *pi4_num_bits_to_prevent_overflow, |
274 | | picture_type_e e_pic_type) |
275 | 4.29M | { |
276 | 4.29M | vbv_buf_status_e e_buf_status; |
277 | 4.29M | WORD32 i4_cur_enc_buf; |
278 | 4.29M | WORD32 i4_error_bits = (e_pic_type == I_PIC) ? |
279 | 4.02M | irc_get_error_bits(ps_cbr_buffer |
280 | 4.02M | ->aps_bpf_error_bits[0]) : |
281 | 4.29M | irc_get_error_bits(ps_cbr_buffer |
282 | 265k | ->aps_bpf_error_bits[1]); |
283 | | |
284 | 4.29M | WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC) ? |
285 | 4.02M | ps_cbr_buffer->i4_drain_bits_per_frame[0] : |
286 | 4.29M | ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
287 | | |
288 | | /* Add the tot consumed bits to the Encoder Buffer*/ |
289 | 4.29M | i4_cur_enc_buf = ps_cbr_buffer->i4_ebf + i4_tot_consumed_bits; |
290 | | |
291 | | /* If the Encoder exceeds the Buffer Size signal an Overflow*/ |
292 | 4.29M | if(i4_cur_enc_buf > ps_cbr_buffer->i4_buffer_size) |
293 | 863k | { |
294 | 863k | e_buf_status = VBV_OVERFLOW; |
295 | 863k | i4_cur_enc_buf = ps_cbr_buffer->i4_buffer_size; |
296 | 863k | } |
297 | 3.42M | else |
298 | 3.42M | { |
299 | | /* |
300 | | * Subtract the constant drain bits and error bits due to fixed point |
301 | | * implementation |
302 | | */ |
303 | 3.42M | i4_cur_enc_buf -= (i4_drain_bits_per_frame + i4_error_bits); |
304 | | |
305 | | /* |
306 | | * If the buffer is less than stuffing threshold an Underflow is |
307 | | * signaled else its NORMAL |
308 | | */ |
309 | 3.42M | if(i4_cur_enc_buf < ps_cbr_buffer->i4_stuffing_threshold) |
310 | 2.91M | { |
311 | 2.91M | e_buf_status = VBV_UNDERFLOW; |
312 | 2.91M | } |
313 | 507k | else |
314 | 507k | { |
315 | 507k | e_buf_status = VBV_NORMAL; |
316 | 507k | } |
317 | | |
318 | 3.42M | if(i4_cur_enc_buf < 0) |
319 | 2.91M | i4_cur_enc_buf = 0; |
320 | 3.42M | } |
321 | | |
322 | | /* |
323 | | * The RC lib models the encoder buffer, but the VBV buffer characterizes |
324 | | * the decoder buffer |
325 | | */ |
326 | 4.29M | if(e_buf_status == VBV_OVERFLOW) |
327 | 863k | { |
328 | 863k | e_buf_status = VBV_UNDERFLOW; |
329 | 863k | } |
330 | 3.42M | else if(e_buf_status == VBV_UNDERFLOW) |
331 | 2.92M | { |
332 | 2.92M | e_buf_status = VBV_OVERFLOW; |
333 | 2.92M | } |
334 | | |
335 | 4.29M | pi4_num_bits_to_prevent_overflow[0] = (ps_cbr_buffer->i4_buffer_size |
336 | 4.29M | - i4_cur_enc_buf); |
337 | | |
338 | 4.29M | return e_buf_status; |
339 | 4.29M | } |
340 | | |
341 | | /******************************************************************************* |
342 | | * @brief Based on the bits consumed the buffer model is updated |
343 | | ******************************************************************************/ |
344 | | void irc_update_cbr_buffer(cbr_buffer_t *ps_cbr_buffer, |
345 | | WORD32 i4_tot_consumed_bits, |
346 | | picture_type_e e_pic_type) |
347 | 41.9k | { |
348 | 41.9k | WORD32 i4_error_bits = (e_pic_type == I_PIC) ? |
349 | 12.2k | irc_get_error_bits(ps_cbr_buffer-> |
350 | 12.2k | aps_bpf_error_bits[0]) : |
351 | 41.9k | irc_get_error_bits( ps_cbr_buffer-> |
352 | 29.7k | aps_bpf_error_bits[1]); |
353 | | |
354 | 41.9k | WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC) ? |
355 | 12.2k | ps_cbr_buffer->i4_drain_bits_per_frame[0] : |
356 | 41.9k | ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
357 | | |
358 | | /* Update the Encoder buffer with the total consumed bits*/ |
359 | 41.9k | ps_cbr_buffer->i4_ebf += i4_tot_consumed_bits; |
360 | | |
361 | | /* |
362 | | * Subtract the drain bits and error bits due to fixed point |
363 | | * implementation |
364 | | */ |
365 | 41.9k | ps_cbr_buffer->i4_ebf -= (i4_drain_bits_per_frame + i4_error_bits); |
366 | | |
367 | 41.9k | if(ps_cbr_buffer->i4_ebf < 0) |
368 | 8.34k | ps_cbr_buffer->i4_ebf = 0; |
369 | | |
370 | | /*SS - Fix for lack of stuffing*/ |
371 | 41.9k | if(ps_cbr_buffer->i4_ebf > ps_cbr_buffer->i4_buffer_size) |
372 | 4.95k | { |
373 | 4.95k | TRACE_PRINTF((const WORD8*)"Error: Should not be coming here with stuffing\n"); |
374 | 4.95k | ps_cbr_buffer->i4_ebf = ps_cbr_buffer->i4_buffer_size; |
375 | 4.95k | } |
376 | 41.9k | } |
377 | | |
378 | | /******************************************************************************* |
379 | | * @brief If the buffer underflows then return the number of bits to prevent |
380 | | * underflow |
381 | | * |
382 | | ******************************************************************************/ |
383 | | WORD32 irc_get_cbr_bits_to_stuff(cbr_buffer_t *ps_cbr_buffer, |
384 | | WORD32 i4_tot_consumed_bits, |
385 | | picture_type_e e_pic_type) |
386 | 4.37k | { |
387 | 4.37k | WORD32 i4_bits_to_stuff; |
388 | 4.37k | WORD32 i4_error_bits = (e_pic_type == I_PIC) ? |
389 | 2.85k | irc_get_error_bits(ps_cbr_buffer |
390 | 2.85k | ->aps_bpf_error_bits[0]) : |
391 | 4.37k | irc_get_error_bits(ps_cbr_buffer |
392 | 1.52k | ->aps_bpf_error_bits[1]); |
393 | | |
394 | 4.37k | WORD32 i4_drain_bits_per_frame = (e_pic_type == I_PIC) ? |
395 | 2.85k | ps_cbr_buffer->i4_drain_bits_per_frame[0] : |
396 | 4.37k | ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
397 | | |
398 | | /* |
399 | | * Stuffing bits got from the following equation |
400 | | * Stuffing_threshold = ebf + tcb - drain bits - error bits + stuff_bits |
401 | | */ |
402 | 4.37k | i4_bits_to_stuff = i4_drain_bits_per_frame + i4_error_bits |
403 | 4.37k | + ps_cbr_buffer->i4_stuffing_threshold |
404 | 4.37k | - (ps_cbr_buffer->i4_ebf + i4_tot_consumed_bits); |
405 | | |
406 | 4.37k | return i4_bits_to_stuff; |
407 | 4.37k | } |
408 | | |
409 | | /******************************************************************************* |
410 | | * @brief Update the state for change in number of pics in the delay period |
411 | | * |
412 | | ******************************************************************************/ |
413 | | void irc_change_cbr_vbv_num_pics_in_delay_period(cbr_buffer_t *ps_cbr_buffer, |
414 | | UWORD32 *u4_num_pics_in_delay_prd) |
415 | 0 | { |
416 | 0 | WORD32 i; |
417 | |
|
418 | 0 | if(!ps_cbr_buffer->i4_is_cbr_mode) |
419 | 0 | { |
420 | 0 | ps_cbr_buffer->i4_buffer_size = |
421 | 0 | u4_num_pics_in_delay_prd[0] |
422 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[0] |
423 | 0 | + u4_num_pics_in_delay_prd[1] |
424 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
425 | |
|
426 | 0 | if(ps_cbr_buffer->i4_buffer_size |
427 | 0 | > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size) |
428 | 0 | { |
429 | 0 | ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size; |
430 | 0 | } |
431 | 0 | for(i = 0; i < MAX_PIC_TYPE; i++) |
432 | 0 | { |
433 | 0 | ps_cbr_buffer->i4_upr_thr[i] = ps_cbr_buffer->i4_buffer_size |
434 | 0 | - (ps_cbr_buffer->i4_buffer_size >> 3); |
435 | 0 | } |
436 | | |
437 | | /* Re-initialize the number of pics in delay period */ |
438 | 0 | for(i = 0; i < MAX_PIC_TYPE; i++) |
439 | 0 | { |
440 | 0 | ps_cbr_buffer->ai4_num_pics_in_delay_period[i] = |
441 | 0 | u4_num_pics_in_delay_prd[i]; |
442 | 0 | } |
443 | 0 | } |
444 | 0 | } |
445 | | |
446 | | /****************************************************************************** |
447 | | * @brief update the state for change in target frame rate |
448 | | * |
449 | | ******************************************************************************/ |
450 | | void irc_change_cbr_vbv_tgt_frame_rate(cbr_buffer_t *ps_cbr_buffer, |
451 | | WORD32 i4_tgt_frm_rate) |
452 | 11.8k | { |
453 | 11.8k | WORD32 i4_i, i4_bits_per_frm[MAX_NUM_DRAIN_RATES]; |
454 | 11.8k | int i; |
455 | | |
456 | 35.6k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
457 | 23.7k | { |
458 | 23.7k | X_PROD_Y_DIV_Z(ps_cbr_buffer->ai4_bit_rate[i], 1000, i4_tgt_frm_rate, |
459 | 23.7k | i4_bits_per_frm[i]); |
460 | | /* Drain rate = bitrate/(framerate/1000) */ |
461 | 23.7k | ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i]; |
462 | | /* Initialize the bits per frame error bits calculation */ |
463 | 23.7k | irc_change_frm_rate_in_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], |
464 | 23.7k | i4_tgt_frm_rate); |
465 | 23.7k | } |
466 | | |
467 | | /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/ |
468 | 11.8k | if(!ps_cbr_buffer->i4_is_cbr_mode) |
469 | 0 | { |
470 | | /* VBR streaming case which has different drain rates for I and P */ |
471 | 0 | ps_cbr_buffer->i4_buffer_size = |
472 | 0 | ps_cbr_buffer->ai4_num_pics_in_delay_period[0] |
473 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[0] |
474 | 0 | + ps_cbr_buffer->ai4_num_pics_in_delay_period[1] |
475 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
476 | 0 | } |
477 | | |
478 | 11.8k | if(ps_cbr_buffer->i4_buffer_size |
479 | 11.8k | > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size) |
480 | 0 | { |
481 | 0 | ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size; |
482 | 0 | } |
483 | | |
484 | | /* |
485 | | * Tgt_frame_rate is divided by 1000 because an approximate value is fine as |
486 | | * this is just a threshold below which stuffing is done to avoid buffer |
487 | | * underflow due to fixed point error in drain rate |
488 | | */ |
489 | 11.8k | ps_cbr_buffer->i4_stuffing_threshold = (ps_cbr_buffer->ai4_bit_rate[0] |
490 | 11.8k | - (i4_bits_per_frm[0] * (i4_tgt_frm_rate / 1000))); |
491 | | |
492 | 47.5k | for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++) |
493 | 35.6k | { |
494 | | /* |
495 | | * Upper threshold for |
496 | | * I frame = 1 * bits per frame |
497 | | * P Frame = 4 * bits per frame. |
498 | | * The threshold for I frame is only 1 * bits per frame as the threshold should |
499 | | * only account for error in estimated bits. |
500 | | * In P frame it should account for difference bets bits consumed by I(Scene change) |
501 | | * and P frame I to P complexity is assumed to be 5. |
502 | | */ |
503 | 35.6k | WORD32 i4_index; |
504 | 35.6k | i4_index = i4_i > 0 ? 1 : 0; |
505 | 35.6k | ps_cbr_buffer->i4_upr_thr[i4_i] = ps_cbr_buffer->i4_buffer_size |
506 | 35.6k | - (ps_cbr_buffer->i4_buffer_size >> 3); |
507 | | |
508 | | /* |
509 | | * For both I and P frame Lower threshold is equal to drain rate. |
510 | | * Even if the encoder consumes zero bits it should have enough bits to |
511 | | * drain |
512 | | */ |
513 | 35.6k | ps_cbr_buffer->i4_low_thr[i4_i] = i4_bits_per_frm[i4_index]; |
514 | 35.6k | } |
515 | | |
516 | | /* Storing the input parameters for using it for change functions */ |
517 | 11.8k | ps_cbr_buffer->i4_tgt_frm_rate = i4_tgt_frm_rate; |
518 | 11.8k | } |
519 | | |
520 | | /******************************************************************************* |
521 | | * @brief Change the state for change in bit rate |
522 | | * |
523 | | ******************************************************************************/ |
524 | | void irc_change_cbr_vbv_bit_rate(cbr_buffer_t *ps_cbr_buffer, |
525 | | WORD32 *i4_bit_rate) |
526 | 6.92k | { |
527 | 6.92k | WORD32 i4_i, i4_bits_per_frm[MAX_NUM_DRAIN_RATES]; |
528 | 6.92k | int i; |
529 | | |
530 | 20.7k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
531 | 13.8k | { |
532 | 13.8k | X_PROD_Y_DIV_Z(i4_bit_rate[i], 1000, ps_cbr_buffer->i4_tgt_frm_rate, |
533 | 13.8k | i4_bits_per_frm[i]); |
534 | | /* Drain rate = bitrate/(framerate/1000) */ |
535 | 13.8k | ps_cbr_buffer->i4_drain_bits_per_frame[i] = i4_bits_per_frm[i]; |
536 | | /* Initialize the bits per frame error bits calculation */ |
537 | 13.8k | irc_change_bitrate_in_error_bits(ps_cbr_buffer->aps_bpf_error_bits[i], |
538 | 13.8k | i4_bit_rate[i]); |
539 | 13.8k | } |
540 | | |
541 | | /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/ |
542 | 6.92k | if(i4_bit_rate[0] == i4_bit_rate[1]) /* This would mean CBR mode */ |
543 | 6.92k | { |
544 | 6.92k | X_PROD_Y_DIV_Z(i4_bit_rate[0], ps_cbr_buffer->i4_max_delay, 1000, |
545 | 6.92k | ps_cbr_buffer->i4_buffer_size); |
546 | 6.92k | ps_cbr_buffer->i4_is_cbr_mode = 1; |
547 | 6.92k | } |
548 | 0 | else |
549 | 0 | { |
550 | | /* VBR streaming case which has different drain rates for I and P */ |
551 | 0 | ps_cbr_buffer->i4_buffer_size = |
552 | 0 | ps_cbr_buffer->ai4_num_pics_in_delay_period[0] |
553 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[0] |
554 | 0 | + ps_cbr_buffer->ai4_num_pics_in_delay_period[1] |
555 | 0 | * ps_cbr_buffer->i4_drain_bits_per_frame[1]; |
556 | |
|
557 | 0 | ps_cbr_buffer->i4_is_cbr_mode = 0; |
558 | 0 | } |
559 | | |
560 | 6.92k | if(ps_cbr_buffer->i4_buffer_size |
561 | 6.92k | > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size) |
562 | 655 | { |
563 | 655 | ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size; |
564 | 655 | } |
565 | | |
566 | | /* |
567 | | * tgt_frame_rate is divided by 1000 because |
568 | | * an approximate value is fine as this is just a threshold below which |
569 | | * stuffing is done to avoid buffer underflow due to fixed point |
570 | | * error in drain rate |
571 | | */ |
572 | 6.92k | ps_cbr_buffer->i4_stuffing_threshold = (i4_bit_rate[0] |
573 | 6.92k | - (i4_bits_per_frm[0] |
574 | 6.92k | * (ps_cbr_buffer->i4_tgt_frm_rate / 1000))); |
575 | | |
576 | 27.6k | for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++) |
577 | 20.7k | { |
578 | | /* |
579 | | * Upper threshold for |
580 | | * I frame = 1 * bits per frame |
581 | | * P Frame = 4 * bits per frame. |
582 | | * The threshold for I frame is only 1 * bits per frame as the threshold |
583 | | * should only account for error in estimated bits. |
584 | | * In P frame it should account for difference bets bits consumed by |
585 | | * I(Scene change) and P frame I to P complexity is assumed to be 5. |
586 | | */ |
587 | | |
588 | 20.7k | WORD32 i4_index; |
589 | 20.7k | i4_index = i4_i > 0 ? 1 : 0; |
590 | 20.7k | ps_cbr_buffer->i4_upr_thr[i4_i] = ps_cbr_buffer->i4_buffer_size |
591 | 20.7k | - (ps_cbr_buffer->i4_buffer_size >> 3); |
592 | | |
593 | | /* For both I and P frame Lower threshold is equal to drain rate. |
594 | | * Even if the encoder consumes zero bits it should have enough bits to |
595 | | * drain |
596 | | */ |
597 | 20.7k | ps_cbr_buffer->i4_low_thr[i4_i] = i4_bits_per_frm[i4_index]; |
598 | 20.7k | } |
599 | | |
600 | | /* Storing the input parameters for using it for change functions */ |
601 | 20.7k | for(i = 0; i < MAX_NUM_DRAIN_RATES; i++) |
602 | 13.8k | { |
603 | 13.8k | ps_cbr_buffer->ai4_bit_rate[i] = i4_bit_rate[i]; |
604 | 13.8k | } |
605 | 6.92k | } |
606 | | |
607 | | void irc_change_cbr_buffer_delay(cbr_buffer_t *ps_cbr_buffer, |
608 | | WORD32 i4_buffer_delay) |
609 | 0 | { |
610 | 0 | WORD32 i4_i; |
611 | | |
612 | | /* Bitrate * delay = buffer size, divide by 1000 as delay is in ms*/ |
613 | 0 | if(ps_cbr_buffer->i4_is_cbr_mode) |
614 | 0 | { |
615 | 0 | X_PROD_Y_DIV_Z(ps_cbr_buffer->ai4_bit_rate[0], i4_buffer_delay, 1000, |
616 | 0 | ps_cbr_buffer->i4_buffer_size); |
617 | 0 | } |
618 | |
|
619 | 0 | if(ps_cbr_buffer->i4_buffer_size |
620 | 0 | > (WORD32)ps_cbr_buffer->u4_max_vbv_buf_size) |
621 | 0 | { |
622 | 0 | ps_cbr_buffer->i4_buffer_size = ps_cbr_buffer->u4_max_vbv_buf_size; |
623 | 0 | } |
624 | |
|
625 | 0 | for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++) |
626 | 0 | { |
627 | | /* |
628 | | * Upper threshold for |
629 | | * I frame = 1 * bits per frame |
630 | | * P Frame = 4 * bits per frame. |
631 | | * The threshold for I frame is only 1 * bits per frame as the threshold |
632 | | * should only account for error in estimated bits. |
633 | | * In P frame it should account for difference bets bits consumed by I |
634 | | * (Scene change) and P frame I to P complexity is assumed to be 5. |
635 | | */ |
636 | 0 | ps_cbr_buffer->i4_upr_thr[i4_i] = ps_cbr_buffer->i4_buffer_size |
637 | 0 | - (ps_cbr_buffer->i4_buffer_size >> 3); |
638 | 0 | } |
639 | | |
640 | | /* Storing the input parameters for using it for change functions */ |
641 | 0 | ps_cbr_buffer->i4_max_delay = i4_buffer_delay; |
642 | 0 | } |
643 | | |
644 | | WORD32 irc_get_cbr_buffer_delay(cbr_buffer_t *ps_cbr_buffer) |
645 | 18.6k | { |
646 | 18.6k | return (ps_cbr_buffer->i4_max_delay); |
647 | 18.6k | } |
648 | | |
649 | | WORD32 irc_get_cbr_buffer_size(cbr_buffer_t *ps_cbr_buffer) |
650 | 76.5k | { |
651 | 76.5k | return (ps_cbr_buffer->i4_buffer_size); |
652 | 76.5k | } |