Coverage Report

Created: 2025-12-29 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}