/src/libavc/encoder/ih264e_rate_control.c
Line | Count | Source (jump to first uncovered line) |
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 | | ******************************************************************************* |
23 | | * @file |
24 | | * ih264e_rate_control.c |
25 | | * |
26 | | * @brief |
27 | | * Contains api function definitions for h264 rate control |
28 | | * |
29 | | * @author |
30 | | * ittiam |
31 | | * |
32 | | * @par List of Functions: |
33 | | * - ih264e_rc_init |
34 | | * - ih264e_rc_get_picture_details |
35 | | * - ih264e_update_rc_framerates |
36 | | * - ih264e_update_rc_mb_info |
37 | | * - ih264e_rc_get_buffer_status |
38 | | * - ih264e_rc_post_enc |
39 | | * - ih264e_update_rc_bits_info |
40 | | * |
41 | | * @remarks |
42 | | * none |
43 | | * |
44 | | ******************************************************************************* |
45 | | */ |
46 | | |
47 | | /*****************************************************************************/ |
48 | | /* File Includes */ |
49 | | /*****************************************************************************/ |
50 | | |
51 | | /* System Include Files */ |
52 | | #include <stdio.h> |
53 | | #include <stddef.h> |
54 | | #include <stdlib.h> |
55 | | #include <string.h> |
56 | | #include <limits.h> |
57 | | #include <assert.h> |
58 | | |
59 | | /* User Include Files */ |
60 | | #include "ih264_typedefs.h" |
61 | | #include "iv2.h" |
62 | | #include "ive2.h" |
63 | | |
64 | | #include "ih264_macros.h" |
65 | | #include "ih264_defs.h" |
66 | | #include "ih264_mem_fns.h" |
67 | | #include "ih264_padding.h" |
68 | | #include "ih264_structs.h" |
69 | | #include "ih264_trans_quant_itrans_iquant.h" |
70 | | #include "ih264_inter_pred_filters.h" |
71 | | #include "ih264_intra_pred_filters.h" |
72 | | #include "ih264_deblk_edge_filters.h" |
73 | | #include "ih264_common_tables.h" |
74 | | #include "ih264_cabac_tables.h" |
75 | | |
76 | | #include "ime_defs.h" |
77 | | #include "ime_distortion_metrics.h" |
78 | | #include "ime_structs.h" |
79 | | |
80 | | #include "irc_mem_req_and_acq.h" |
81 | | #include "irc_cntrl_param.h" |
82 | | #include "irc_frame_info_collector.h" |
83 | | #include "irc_rate_control_api.h" |
84 | | |
85 | | #include "ih264e.h" |
86 | | #include "ih264e_error.h" |
87 | | #include "ih264e_defs.h" |
88 | | #include "ih264e_globals.h" |
89 | | #include "ih264e_rate_control.h" |
90 | | #include "ih264e_bitstream.h" |
91 | | #include "ih264e_cabac_structs.h" |
92 | | #include "ih264e_structs.h" |
93 | | #include "ih264e_utils.h" |
94 | | #include "ih264e_time_stamp.h" |
95 | | #include "ih264e_modify_frm_rate.h" |
96 | | |
97 | | |
98 | | /*****************************************************************************/ |
99 | | /* Function Definitions */ |
100 | | /*****************************************************************************/ |
101 | | |
102 | | /** |
103 | | ******************************************************************************* |
104 | | * |
105 | | * @brief |
106 | | * This function initializes rate control context and variables |
107 | | * |
108 | | * @par Description |
109 | | * This function initializes rate control type, source and target frame rate, |
110 | | * average and peak bitrate, intra-inter frame interval and initial |
111 | | * quantization parameter |
112 | | * |
113 | | * @param[in] pv_rc_api |
114 | | * Handle to rate control api |
115 | | * |
116 | | * @param[in] pv_frame_time |
117 | | * Handle to frame time context |
118 | | * |
119 | | * @param[in] pv_time_stamp |
120 | | * Handle to time stamp context |
121 | | * |
122 | | * @param[in] pv_pd_frm_rate |
123 | | * Handle to pull down frame time context |
124 | | * |
125 | | * @param[in] u4_max_frm_rate |
126 | | * Maximum frame rate |
127 | | * |
128 | | * @param[in] u4_src_frm_rate |
129 | | * Source frame rate |
130 | | * |
131 | | * @param[in] u4_tgt_frm_rate |
132 | | * Target frame rate |
133 | | * |
134 | | * @param[in] e_rate_control_type |
135 | | * Rate control type |
136 | | * |
137 | | * @param[in] u4_avg_bit_rate |
138 | | * Average bit rate |
139 | | * |
140 | | * @param[in] u4_peak_bit_rate |
141 | | * Peak bit rate |
142 | | * |
143 | | * @param[in] u4_max_delay |
144 | | * Maximum delay between frames |
145 | | * |
146 | | * @param[in] u4_intra_frame_interval |
147 | | * Intra frame interval |
148 | | * |
149 | | * @param[in] pu1_init_qp |
150 | | * Initial qp |
151 | | * |
152 | | * @param[in] i4_max_inter_frm_int |
153 | | * Maximum inter frame interval |
154 | | * |
155 | | * @param[in] pu1_min_max_qp |
156 | | * Array of min/max qp |
157 | | * |
158 | | * @param[in] u1_profile_level |
159 | | * Encoder profile level |
160 | | * |
161 | | * @returns none |
162 | | * |
163 | | * @remarks |
164 | | * |
165 | | ******************************************************************************* |
166 | | */ |
167 | | void ih264e_rc_init(void *pv_rc_api, |
168 | | void *pv_frame_time, |
169 | | void *pv_time_stamp, |
170 | | void *pv_pd_frm_rate, |
171 | | UWORD32 u4_max_frm_rate, |
172 | | UWORD32 u4_src_frm_rate, |
173 | | UWORD32 u4_tgt_frm_rate, |
174 | | rc_type_e e_rate_control_type, |
175 | | UWORD32 u4_avg_bit_rate, |
176 | | UWORD32 u4_peak_bit_rate, |
177 | | UWORD32 u4_max_delay, |
178 | | UWORD32 u4_intra_frame_interval, |
179 | | WORD32 i4_inter_frm_int, |
180 | | UWORD8 *pu1_init_qp, |
181 | | WORD32 i4_max_inter_frm_int, |
182 | | UWORD8 *pu1_min_max_qp, |
183 | | UWORD8 u1_profile_level) |
184 | 15.6k | { |
185 | | // UWORD8 u1_is_mb_level_rc_on = 0; |
186 | 15.6k | UWORD32 au4_peak_bit_rate[2] = {0,0}; |
187 | 15.6k | UWORD32 u4_min_bit_rate = 0; |
188 | 15.6k | WORD32 i4_is_gop_closed = 1; |
189 | | // WORD32 i4_use_est_intra_sad = 1; |
190 | 15.6k | UWORD32 u4_src_ticks = 0; |
191 | 15.6k | UWORD32 u4_tgt_ticks = 0; |
192 | 15.6k | UWORD8 u1_level_idx = ih264e_get_lvl_idx(u1_profile_level); |
193 | 15.6k | UWORD32 u4_max_cpb_size = 1200 * gas_ih264_lvl_tbl[u1_level_idx].u4_max_cpb_size; |
194 | | |
195 | | /* Fill the params needed for the RC init */ |
196 | 15.6k | if (e_rate_control_type == CBR_NLDRC) |
197 | 4.43k | { |
198 | 4.43k | au4_peak_bit_rate[0] = u4_avg_bit_rate; |
199 | 4.43k | au4_peak_bit_rate[1] = u4_avg_bit_rate; |
200 | 4.43k | } |
201 | 11.1k | else |
202 | 11.1k | { |
203 | 11.1k | au4_peak_bit_rate[0] = u4_peak_bit_rate; |
204 | 11.1k | au4_peak_bit_rate[1] = u4_peak_bit_rate; |
205 | 11.1k | } |
206 | | |
207 | | /* Initialize frame time computation module*/ |
208 | 15.6k | ih264e_init_frame_time(pv_frame_time, |
209 | 15.6k | u4_src_frm_rate, /* u4_src_frm_rate */ |
210 | 15.6k | u4_tgt_frm_rate); /* u4_tgt_frm_rate */ |
211 | | |
212 | | /* Initialize the pull_down frame rate */ |
213 | 15.6k | ih264e_init_pd_frm_rate(pv_pd_frm_rate, |
214 | 15.6k | u4_src_frm_rate); /* u4_input_frm_rate */ |
215 | | |
216 | | /* Initialize time stamp structure */ |
217 | 15.6k | ih264e_init_time_stamp(pv_time_stamp, |
218 | 15.6k | u4_max_frm_rate, /* u4_max_frm_rate */ |
219 | 15.6k | u4_src_frm_rate); /* u4_src_frm_rate */ |
220 | | |
221 | 15.6k | u4_src_ticks = ih264e_frame_time_get_src_ticks(pv_frame_time); |
222 | 15.6k | u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(pv_frame_time); |
223 | | |
224 | | /* Init max_inter_frame int */ |
225 | 15.6k | i4_max_inter_frm_int = (i4_inter_frm_int == 1) ? 2 : (i4_inter_frm_int + 2); |
226 | | |
227 | | /* Initialize the rate control */ |
228 | 15.6k | irc_initialise_rate_control(pv_rc_api, /* RC handle */ |
229 | 15.6k | e_rate_control_type, /* RC algo type */ |
230 | 15.6k | 0, /* MB activity on/off */ |
231 | 15.6k | u4_avg_bit_rate, /* Avg Bitrate */ |
232 | 15.6k | au4_peak_bit_rate, /* Peak bitrate array[2]:[I][P] */ |
233 | 15.6k | u4_min_bit_rate, /* Min Bitrate */ |
234 | 15.6k | u4_src_frm_rate, /* Src frame_rate */ |
235 | 15.6k | u4_max_delay, /* Max buffer delay */ |
236 | 15.6k | u4_intra_frame_interval, /* Intra frm_interval */ |
237 | 15.6k | i4_inter_frm_int, /* Inter frame interval */ |
238 | 15.6k | pu1_init_qp, /* Init QP array[3]:[I][P][B] */ |
239 | 15.6k | u4_max_cpb_size, /* Max VBV/CPB Buffer Size */ |
240 | 15.6k | i4_max_inter_frm_int, /* Max inter frm_interval */ |
241 | 15.6k | i4_is_gop_closed, /* Open/Closed GOP */ |
242 | 15.6k | pu1_min_max_qp, /* Min-max QP array[6]:[Imax][Imin][Pmax][Pmin][Bmax][Bmin] */ |
243 | 15.6k | 0, /* How to calc the I-frame estimated_sad */ |
244 | 15.6k | u4_src_ticks, /* Src_ticks = LCM(src_frm_rate,tgt_frm_rate)/src_frm_rate */ |
245 | 15.6k | u4_tgt_ticks); /* Tgt_ticks = LCM(src_frm_rate,tgt_frm_rate)/tgt_frm_rate */ |
246 | 15.6k | } |
247 | | |
248 | | /** |
249 | | ******************************************************************************* |
250 | | * |
251 | | * @brief Function to get picture details |
252 | | * |
253 | | * @par Description |
254 | | * This function returns the Picture type(I/P/B) |
255 | | * |
256 | | * @param[in] pv_rc_api |
257 | | * Handle to Rate control api |
258 | | * |
259 | | * @returns |
260 | | * Picture type |
261 | | * |
262 | | * @remarks none |
263 | | * |
264 | | ******************************************************************************* |
265 | | */ |
266 | | picture_type_e ih264e_rc_get_picture_details(void *pv_rc_api, |
267 | | WORD32 *pi4_pic_id, |
268 | | WORD32 *pi4_pic_disp_order_no) |
269 | 48.1k | { |
270 | 48.1k | picture_type_e e_rc_pic_type = P_PIC; |
271 | | |
272 | 48.1k | irc_get_picture_details(pv_rc_api, pi4_pic_id, pi4_pic_disp_order_no, |
273 | 48.1k | &e_rc_pic_type); |
274 | | |
275 | 48.1k | return (e_rc_pic_type); |
276 | 48.1k | } |
277 | | |
278 | | /** |
279 | | ******************************************************************************* |
280 | | * |
281 | | * @brief Function to catch frame skips before encoding due to source framerate |
282 | | * pulldown |
283 | | * |
284 | | * @par Description |
285 | | * This function is called before queuing the current frame. It decides if we |
286 | | * should skip the current input buffer due to frame rate mismatch. It also |
287 | | * updates RC about the framerate pulldown |
288 | | * |
289 | | * @param[in] ps_rate_control_api |
290 | | * Handle to rate control api |
291 | | * |
292 | | * @param[in] ps_pd_frm_rate |
293 | | * Handle to pull down frm rate context |
294 | | * |
295 | | * @param[in] ps_time_stamp |
296 | | * Handle to time stamp context |
297 | | * |
298 | | * @param[in] ps_frame_time |
299 | | * Handle to frame time context |
300 | | * |
301 | | * @returns |
302 | | * Skip or queue the current frame |
303 | | * |
304 | | * @remarks |
305 | | * |
306 | | ******************************************************************************* |
307 | | */ |
308 | | WORD32 ih264e_update_rc_framerates(void *ps_rate_control_api, |
309 | | void *ps_pd_frm_rate, |
310 | | void *ps_time_stamp, |
311 | | void *ps_frame_time) |
312 | 57.6k | { |
313 | 57.6k | WORD8 i4_skip_src = 0; |
314 | 57.6k | UWORD32 u4_src_not_skipped_for_dts = 0; |
315 | | |
316 | | /* Update the time stamp for the current frame */ |
317 | 57.6k | ih264e_update_time_stamp(ps_time_stamp); |
318 | | |
319 | | /* Check if a src not needs to be skipped */ |
320 | 57.6k | i4_skip_src = ih264e_should_src_be_skipped(ps_frame_time, |
321 | 57.6k | 1, |
322 | 57.6k | &u4_src_not_skipped_for_dts); |
323 | | |
324 | 57.6k | if (i4_skip_src) |
325 | 287 | { |
326 | | /*********************************************************************** |
327 | | *Based on difference in source and target frame rate frames are skipped |
328 | | ***********************************************************************/ |
329 | | /*update the missing frames frm_rate with 0 */ |
330 | 287 | ih264e_update_pd_frm_rate(ps_pd_frm_rate, 0); |
331 | 287 | } |
332 | 57.4k | else |
333 | 57.4k | { |
334 | 57.4k | WORD32 i4_avg_frm_rate, i4_source_frame_rate; |
335 | | |
336 | 57.4k | i4_source_frame_rate = ih264e_frame_time_get_src_frame_rate( |
337 | 57.4k | ps_frame_time); |
338 | | |
339 | | /* Update the frame rate of the frame present with the tgt_frm_rate */ |
340 | | /* If the frm was not skipped due to delta_time_stamp, update the |
341 | | frame_rate with double the tgt_frame_rate value, so that it makes |
342 | | up for one of the frames skipped by the application */ |
343 | 57.4k | ih264e_update_pd_frm_rate(ps_pd_frm_rate, i4_source_frame_rate); |
344 | | |
345 | | /* Based on the update get the average frame rate */ |
346 | 57.4k | i4_avg_frm_rate = ih264e_get_pd_avg_frm_rate(ps_pd_frm_rate); |
347 | | |
348 | | /* Call the RC library function to change the frame_rate to the |
349 | | actually achieved frm_rate */ |
350 | 57.4k | irc_change_frm_rate_for_bit_alloc(ps_rate_control_api, i4_avg_frm_rate); |
351 | 57.4k | } |
352 | | |
353 | 57.6k | return (i4_skip_src); |
354 | 57.6k | } |
355 | | |
356 | | /** |
357 | | ******************************************************************************* |
358 | | * |
359 | | * @brief Function to update mb info for rate control context |
360 | | * |
361 | | * @par Description |
362 | | * After encoding a mb, information such as mb type, qp used, mb distortion |
363 | | * resulted in encoding the block and so on needs to be preserved for modeling |
364 | | * RC. This is preserved via this function call. |
365 | | * |
366 | | * @param[in] ps_frame_info |
367 | | * Handle Frame info context |
368 | | * |
369 | | * @param[in] ps_proc |
370 | | * Process context |
371 | | * |
372 | | * @returns |
373 | | * |
374 | | * @remarks |
375 | | * |
376 | | ******************************************************************************* |
377 | | */ |
378 | | void ih264e_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc) |
379 | 7.17M | { |
380 | | /* proc ctxt */ |
381 | 7.17M | process_ctxt_t *ps_proc = pv_proc; |
382 | | |
383 | | /* is intra or inter */ |
384 | 7.17M | WORD32 mb_type = !ps_proc->u4_is_intra; |
385 | | |
386 | | /* distortion */ |
387 | 7.17M | ps_frame_info->tot_mb_sad[mb_type] += ps_proc->i4_mb_distortion; |
388 | | |
389 | | /* qp */ |
390 | 7.17M | ps_frame_info->qp_sum[mb_type] += gau1_h264_to_mpeg2_qmap[ps_proc->u4_mb_qp]; |
391 | | |
392 | | /* mb cnt */ |
393 | 7.17M | ps_frame_info->num_mbs[mb_type]++; |
394 | | |
395 | | /* cost */ |
396 | 7.17M | if (ps_proc->i4_mb_intra_cost != INT_MAX) |
397 | 7.13M | { |
398 | 7.13M | ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_intra_cost; |
399 | 7.13M | } |
400 | 43.1k | else |
401 | 43.1k | { |
402 | | /* codec context */ |
403 | 43.1k | codec_t *ps_codec = ps_proc->ps_codec; |
404 | | |
405 | | /* temp var */ |
406 | 43.1k | WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * ps_proc->i4_wd_mbs; |
407 | | |
408 | 43.1k | ps_frame_info->intra_mb_cost_sum += ps_codec->pi4_mb_intra_cost[i4_mb_id]; |
409 | 43.1k | } |
410 | 7.17M | } |
411 | | |
412 | | /** |
413 | | ******************************************************************************* |
414 | | * |
415 | | * @brief Function to get rate control buffer status |
416 | | * |
417 | | * @par Description |
418 | | * This function is used to get buffer status(underflow/overflow) by rate |
419 | | * control module |
420 | | * |
421 | | * @param[in] pv_rc_api |
422 | | * Handle to rate control api context |
423 | | * |
424 | | * @param[in] i4_total_frame_bits |
425 | | * Total frame bits |
426 | | * |
427 | | * @param[in] u1_pic_type |
428 | | * Picture type |
429 | | * |
430 | | * @param[in] pi4_num_bits_to_prevent_vbv_underflow |
431 | | * Number of bits to prevent underflow |
432 | | * |
433 | | * @param[out] pu1_is_enc_buf_overflow |
434 | | * Buffer overflow indication flag |
435 | | * |
436 | | * @param[out] pu1_is_enc_buf_underflow |
437 | | * Buffer underflow indication flag |
438 | | * |
439 | | * @returns |
440 | | * |
441 | | * @remarks |
442 | | * |
443 | | ******************************************************************************* |
444 | | */ |
445 | | void ih264e_rc_get_buffer_status(void *pv_rc_api, |
446 | | WORD32 i4_total_frame_bits, |
447 | | picture_type_e e_pic_type, |
448 | | WORD32 *pi4_num_bits_to_prevent_vbv_underflow, |
449 | | UWORD8 *pu1_is_enc_buf_overflow, |
450 | | UWORD8 *pu1_is_enc_buf_underflow) |
451 | 0 | { |
452 | 0 | vbv_buf_status_e e_vbv_buf_status = VBV_NORMAL; |
453 | |
|
454 | 0 | e_vbv_buf_status = irc_get_buffer_status(pv_rc_api, |
455 | 0 | i4_total_frame_bits, |
456 | 0 | e_pic_type, |
457 | 0 | pi4_num_bits_to_prevent_vbv_underflow); |
458 | |
|
459 | 0 | if (e_vbv_buf_status == VBV_OVERFLOW) |
460 | 0 | { |
461 | 0 | *pu1_is_enc_buf_underflow = 1; |
462 | 0 | *pu1_is_enc_buf_overflow = 0; |
463 | 0 | } |
464 | 0 | else if (e_vbv_buf_status == VBV_UNDERFLOW) |
465 | 0 | { |
466 | 0 | *pu1_is_enc_buf_underflow = 0; |
467 | 0 | *pu1_is_enc_buf_overflow = 1; |
468 | 0 | } |
469 | 0 | else |
470 | 0 | { |
471 | 0 | *pu1_is_enc_buf_underflow = 0; |
472 | 0 | *pu1_is_enc_buf_overflow = 0; |
473 | 0 | } |
474 | 0 | } |
475 | | |
476 | | /** |
477 | | ******************************************************************************* |
478 | | * |
479 | | * @brief Function to update rate control module after encoding |
480 | | * |
481 | | * @par Description |
482 | | * This function is used to update the rate control module after the current |
483 | | * frame encoding is done with details such as bits consumed, SAD for I/P/B, |
484 | | * intra cost, mb type and other |
485 | | * |
486 | | * @param[in] ps_rate_control_api |
487 | | * Handle to rate control api context |
488 | | * |
489 | | * @param[in] ps_frame_info |
490 | | * Handle to frame info context |
491 | | * |
492 | | * @param[in] ps_pd_frm_rate |
493 | | * Handle to pull down frame rate context |
494 | | * |
495 | | * @param[in] ps_time_stamp |
496 | | * Handle to time stamp context |
497 | | * |
498 | | * @param[in] ps_frame_time |
499 | | * Handle to frame time context |
500 | | * |
501 | | * @param[in] i4_total_mb_in_frame |
502 | | * Total mb in frame |
503 | | * |
504 | | * @param[in] pe_vop_coding_type |
505 | | * Picture coding type |
506 | | * |
507 | | * @param[in] i4_is_first_frame |
508 | | * Is first frame |
509 | | * |
510 | | * @param[out] pi4_is_post_encode_skip |
511 | | * Post encoding skip flag |
512 | | * |
513 | | * @param[in] u1_frame_qp |
514 | | * Frame qp |
515 | | * |
516 | | * @param[in] pi4_num_intra_in_prev_frame |
517 | | * Numberf of intra mbs in previous frame |
518 | | * |
519 | | * @param[in] pi4_avg_activity |
520 | | * Average activity |
521 | | * |
522 | | * @returns In case of underflow, number of stuffing bytes to be added and in |
523 | | * case of overflow, flag signalling the encoder to avoid this frame from |
524 | | * sending |
525 | | * |
526 | | * @remarks |
527 | | * |
528 | | ******************************************************************************* |
529 | | */ |
530 | | WORD32 ih264e_rc_post_enc(void * ps_rate_control_api, |
531 | | frame_info_t *ps_frame_info, |
532 | | void * ps_pd_frm_rate, |
533 | | void * ps_time_stamp, |
534 | | void * ps_frame_time, |
535 | | WORD32 i4_total_mb_in_frame, |
536 | | picture_type_e *pe_vop_coding_type, |
537 | | WORD32 i4_is_first_frame, |
538 | | WORD32 *pi4_is_post_encode_skip, |
539 | | UWORD8 u1_frame_qp, |
540 | | WORD32 *pi4_num_intra_in_prev_frame, |
541 | | WORD32 *pi4_avg_activity) |
542 | 43.3k | { |
543 | | /* Variables for the update_frm_level_info */ |
544 | 43.3k | WORD32 ai4_tot_mb_in_type[MAX_MB_TYPE]; |
545 | 43.3k | WORD32 ai4_tot_mb_type_qp[MAX_MB_TYPE] = {0, 0}; |
546 | 43.3k | WORD32 ai4_mb_type_sad[MAX_MB_TYPE] = {0, 0}; |
547 | 43.3k | WORD32 ai4_mb_type_tex_bits[MAX_MB_TYPE] = {0, 0}; |
548 | 43.3k | WORD32 i4_total_frame_bits = 0; |
549 | 43.3k | WORD32 i4_total_hdr_bits = 0; |
550 | 43.3k | WORD32 i4_total_texturebits; |
551 | 43.3k | WORD32 i4_avg_mb_activity = 0; |
552 | 43.3k | WORD32 i4_intra_frm_cost = 0; |
553 | 43.3k | UWORD8 u1_is_scd = 0; |
554 | 43.3k | WORD32 i4_cbr_bits_to_stuff = 0; |
555 | 43.3k | UWORD32 u4_num_intra_in_prev_frame = *pi4_num_intra_in_prev_frame; |
556 | 43.3k | UNUSED(ps_pd_frm_rate); |
557 | 43.3k | UNUSED(ps_time_stamp); |
558 | 43.3k | UNUSED(ps_frame_time); |
559 | 43.3k | UNUSED(u1_frame_qp); |
560 | | /* Accumulate RC stats */ |
561 | 43.3k | ai4_tot_mb_in_type[MB_TYPE_INTRA] = irc_fi_get_total_mb(ps_frame_info,MB_TYPE_INTRA); |
562 | 43.3k | ai4_tot_mb_in_type[MB_TYPE_INTER] = irc_fi_get_total_mb(ps_frame_info,MB_TYPE_INTER); |
563 | | /* ai4_tot_mb_type_qp[MB_TYPE_INTRA] = 0; |
564 | | ai4_tot_mb_type_qp[MB_TYPE_INTER] = ps_enc->pu1_h264_mpg2quant[u1_frame_qp] * i4_total_mb_in_frame;*/ |
565 | 43.3k | ai4_tot_mb_type_qp[MB_TYPE_INTRA] = irc_fi_get_total_mb_qp(ps_frame_info,MB_TYPE_INTRA); |
566 | 43.3k | ai4_tot_mb_type_qp[MB_TYPE_INTER] = irc_fi_get_total_mb_qp(ps_frame_info,MB_TYPE_INTER); |
567 | 43.3k | ai4_mb_type_sad[MB_TYPE_INTRA] = irc_fi_get_total_mb_sad(ps_frame_info,MB_TYPE_INTRA); |
568 | 43.3k | ai4_mb_type_sad[MB_TYPE_INTER] = irc_fi_get_total_mb_sad(ps_frame_info,MB_TYPE_INTER); |
569 | 43.3k | i4_intra_frm_cost = irc_fi_get_total_intra_mb_cost(ps_frame_info); |
570 | 43.3k | i4_avg_mb_activity = irc_fi_get_avg_activity(ps_frame_info); |
571 | 43.3k | i4_total_hdr_bits = irc_fi_get_total_header_bits(ps_frame_info); |
572 | 43.3k | ai4_mb_type_tex_bits[MB_TYPE_INTRA] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTRA); |
573 | 43.3k | ai4_mb_type_tex_bits[MB_TYPE_INTER] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTER); |
574 | 43.3k | i4_total_texturebits = ai4_mb_type_tex_bits[MB_TYPE_INTRA] + ai4_mb_type_tex_bits[MB_TYPE_INTER]; |
575 | 43.3k | i4_total_frame_bits = i4_total_hdr_bits + i4_total_texturebits ; |
576 | | |
577 | 43.3k | *pi4_avg_activity = i4_avg_mb_activity; |
578 | | |
579 | | /* Set post encode skip to zero */ |
580 | 43.3k | pi4_is_post_encode_skip[0]= 0; |
581 | | |
582 | | /* For NLDRC, get the buffer status for stuffing or skipping */ |
583 | | /* Default NLDRC to CBR with no frame drops so the '0 &&'. */ |
584 | 43.3k | if (0 && irc_get_rc_type(ps_rate_control_api) == CBR_NLDRC) |
585 | 0 | { |
586 | 0 | WORD32 i4_get_num_bit_to_prevent_vbv_overflow; |
587 | 0 | UWORD8 u1_enc_buf_overflow,u1_enc_buf_underflow; |
588 | | |
589 | | /* Getting the buffer status */ |
590 | 0 | ih264e_rc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits, |
591 | 0 | pe_vop_coding_type[0], &i4_get_num_bit_to_prevent_vbv_overflow, |
592 | 0 | &u1_enc_buf_overflow,&u1_enc_buf_underflow); |
593 | | |
594 | | /* We skip the frame if decoder buffer is underflowing. But we never skip first I frame */ |
595 | 0 | if ((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 1)) |
596 | | // if ((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 0)) |
597 | 0 | { |
598 | 0 | irc_post_encode_frame_skip(ps_rate_control_api, (picture_type_e)pe_vop_coding_type[0]); |
599 | | // i4_total_frame_bits = imp4_write_skip_frame_header(ps_enc); |
600 | 0 | i4_total_frame_bits = 0; |
601 | |
|
602 | 0 | *pi4_is_post_encode_skip = 1; |
603 | | |
604 | | /* Adjust the GOP if in case we skipped an I-frame */ |
605 | 0 | if (*pe_vop_coding_type == I_PIC) |
606 | 0 | irc_force_I_frame(ps_rate_control_api); |
607 | | |
608 | | /* Since this frame is skipped by writing 7 bytes header, we say this is a P frame */ |
609 | | // *pe_vop_coding_type = P; |
610 | | |
611 | | /* Getting the buffer status again,to check if it underflows */ |
612 | 0 | irc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits, |
613 | 0 | (picture_type_e)pe_vop_coding_type[0], &i4_get_num_bit_to_prevent_vbv_overflow); |
614 | |
|
615 | 0 | } |
616 | | |
617 | | /* In this case we stuff bytes as buffer is overflowing */ |
618 | 0 | if (u1_enc_buf_underflow == 1) |
619 | 0 | { |
620 | | /* The stuffing function is directly pulled out from split controller workspace. |
621 | | encode_vop_data() function makes sure alignment data is dumped at the end of a |
622 | | frame. Split controller was identifying this alignment byte, overwriting it with |
623 | | the stuff data and then finally aligning the buffer. Here every thing is inside |
624 | | the DSP. So, ideally encode_vop_data needn't align, and we can start stuffing directly. |
625 | | But in that case, it'll break the logic for a normal frame. |
626 | | Hence for simplicity, not changing this part since it is ok to align and |
627 | | then overwrite since stuffing is not done for every frame */ |
628 | 0 | i4_cbr_bits_to_stuff = irc_get_bits_to_stuff(ps_rate_control_api, i4_total_frame_bits, pe_vop_coding_type[0]); |
629 | | |
630 | | /* Just add extra 32 bits to make sure we don't stuff lesser */ |
631 | 0 | i4_cbr_bits_to_stuff += 32; |
632 | | |
633 | | /* We can not stuff more than the outbuf size. So have a check here */ |
634 | | /* Add stuffed bits to total bits */ |
635 | 0 | i4_total_frame_bits += i4_cbr_bits_to_stuff; |
636 | 0 | } |
637 | 0 | } |
638 | | |
639 | 43.3k | #define ENABLE_SCD 1 |
640 | 43.3k | #if ENABLE_SCD |
641 | | /* If number of intra MBs are more than 2/3rd of total MBs, assume it as a scene change */ |
642 | 43.3k | if ((ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((2 * i4_total_mb_in_frame) / 3)) && |
643 | 43.3k | (*pe_vop_coding_type == P_PIC) && |
644 | 43.3k | (ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((11 * (WORD32)u4_num_intra_in_prev_frame) / 10))) |
645 | 3.47k | { |
646 | 3.47k | u1_is_scd = 1; |
647 | 3.47k | } |
648 | 43.3k | #endif |
649 | | |
650 | | /* Update num intra mbs of this frame */ |
651 | 43.3k | if (pi4_is_post_encode_skip[0] == 0) |
652 | 43.3k | { |
653 | 43.3k | *pi4_num_intra_in_prev_frame = ai4_tot_mb_in_type[MB_TYPE_INTRA]; |
654 | 43.3k | } |
655 | | |
656 | | /* Reset intra count to zero, if u encounter an I frame */ |
657 | 43.3k | if (*pe_vop_coding_type == I_PIC) |
658 | 11.6k | { |
659 | 11.6k | *pi4_num_intra_in_prev_frame = 0; |
660 | 11.6k | } |
661 | | |
662 | | /* Do an update of rate control after post encode */ |
663 | 43.3k | irc_update_frame_level_info(ps_rate_control_api, /* RC state */ |
664 | 43.3k | pe_vop_coding_type[0], /* PIC type */ |
665 | 43.3k | ai4_mb_type_sad, /* SAD for [Intra/Inter] */ |
666 | 43.3k | i4_total_frame_bits, /* Total frame bits */ |
667 | 43.3k | i4_total_hdr_bits, /* header bits for */ |
668 | 43.3k | ai4_mb_type_tex_bits, /* for MB[Intra/Inter] */ |
669 | 43.3k | ai4_tot_mb_type_qp, /* for MB[Intra/Inter] */ |
670 | 43.3k | ai4_tot_mb_in_type, /* for MB[Intra/Inter] */ |
671 | 43.3k | i4_avg_mb_activity, /* Average mb activity in frame */ |
672 | 43.3k | u1_is_scd, /* Is a scene change detected */ |
673 | 43.3k | 0, /* Pre encode skip */ |
674 | 43.3k | (WORD32)i4_intra_frm_cost, /* Intra cost for frame */ |
675 | 43.3k | 0); /* Not done outside */ |
676 | | |
677 | 43.3k | return (i4_cbr_bits_to_stuff >> 3); |
678 | 43.3k | } |
679 | | |
680 | | /** |
681 | | ******************************************************************************* |
682 | | * |
683 | | * @brief Function to update total header and texture bits consumed information |
684 | | * to rate control context |
685 | | * |
686 | | * @par Description |
687 | | * Function to update total header and texture bits consumed information |
688 | | * to rate control context |
689 | | * |
690 | | * @param[in] ps_frame_info |
691 | | * Frame info context |
692 | | * |
693 | | * @param[in] ps_entropy |
694 | | * Entropy context |
695 | | * |
696 | | * @returns none |
697 | | * |
698 | | * @remarks |
699 | | * |
700 | | ******************************************************************************* |
701 | | */ |
702 | | void ih264e_update_rc_bits_info(frame_info_t *ps_frame_info, void *pv_entropy) |
703 | 100k | { |
704 | 100k | entropy_ctxt_t *ps_entropy = pv_entropy; |
705 | | |
706 | 100k | ps_frame_info->mb_header_bits[MB_TYPE_INTRA] += ps_entropy->u4_header_bits[MB_TYPE_INTRA]; |
707 | | |
708 | 100k | ps_frame_info->mb_texture_bits[MB_TYPE_INTRA] += ps_entropy->u4_residue_bits[MB_TYPE_INTRA]; |
709 | | |
710 | 100k | ps_frame_info->mb_header_bits[MB_TYPE_INTER] += ps_entropy->u4_header_bits[MB_TYPE_INTER]; |
711 | | |
712 | 100k | ps_frame_info->mb_texture_bits[MB_TYPE_INTER] += ps_entropy->u4_residue_bits[MB_TYPE_INTER]; |
713 | | |
714 | 100k | return; |
715 | 100k | } |
716 | | |