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