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