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