libavc/encoder/ih264e_rate_control.c
Ram Mohan M 50fd862b8d libavcenc: Remove duplicate code and improve readability
This commit does not introduce any new functionality w.r.t previous
commit. But it fixes few things. They are listed below:
1. Guard Bands in header files are fixed
2. Header files contains function definition comments. These are same
as in source file. Maintaining same comment at two locations is
unnecessary. These are removed.
3. Improved consistency and code indentation
4. Removed comments that dont align with implementation
5. Grouped headers of a workspace together
2023-10-01 01:37:17 +05:30

716 lines
25 KiB
C

/******************************************************************************
*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
/**
*******************************************************************************
* @file
* ih264e_rate_control.c
*
* @brief
* Contains api function definitions for h264 rate control
*
* @author
* ittiam
*
* @par List of Functions:
* - ih264e_rc_init
* - ih264e_rc_get_picture_details
* - ih264e_update_rc_framerates
* - ih264e_update_rc_mb_info
* - ih264e_rc_get_buffer_status
* - ih264e_rc_post_enc
* - ih264e_update_rc_bits_info
*
* @remarks
* none
*
*******************************************************************************
*/
/*****************************************************************************/
/* File Includes */
/*****************************************************************************/
/* System Include Files */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
/* User Include Files */
#include "ih264_typedefs.h"
#include "iv2.h"
#include "ive2.h"
#include "ih264_macros.h"
#include "ih264_defs.h"
#include "ih264_mem_fns.h"
#include "ih264_padding.h"
#include "ih264_structs.h"
#include "ih264_trans_quant_itrans_iquant.h"
#include "ih264_inter_pred_filters.h"
#include "ih264_intra_pred_filters.h"
#include "ih264_deblk_edge_filters.h"
#include "ih264_common_tables.h"
#include "ih264_cabac_tables.h"
#include "ime_defs.h"
#include "ime_distortion_metrics.h"
#include "ime_structs.h"
#include "irc_mem_req_and_acq.h"
#include "irc_cntrl_param.h"
#include "irc_frame_info_collector.h"
#include "irc_rate_control_api.h"
#include "ih264e.h"
#include "ih264e_error.h"
#include "ih264e_defs.h"
#include "ih264e_globals.h"
#include "ih264e_rate_control.h"
#include "ih264e_bitstream.h"
#include "ih264e_cabac_structs.h"
#include "ih264e_structs.h"
#include "ih264e_utils.h"
#include "ih264e_time_stamp.h"
#include "ih264e_modify_frm_rate.h"
/*****************************************************************************/
/* Function Definitions */
/*****************************************************************************/
/**
*******************************************************************************
*
* @brief
* This function initializes rate control context and variables
*
* @par Description
* This function initializes rate control type, source and target frame rate,
* average and peak bitrate, intra-inter frame interval and initial
* quantization parameter
*
* @param[in] pv_rc_api
* Handle to rate control api
*
* @param[in] pv_frame_time
* Handle to frame time context
*
* @param[in] pv_time_stamp
* Handle to time stamp context
*
* @param[in] pv_pd_frm_rate
* Handle to pull down frame time context
*
* @param[in] u4_max_frm_rate
* Maximum frame rate
*
* @param[in] u4_src_frm_rate
* Source frame rate
*
* @param[in] u4_tgt_frm_rate
* Target frame rate
*
* @param[in] e_rate_control_type
* Rate control type
*
* @param[in] u4_avg_bit_rate
* Average bit rate
*
* @param[in] u4_peak_bit_rate
* Peak bit rate
*
* @param[in] u4_max_delay
* Maximum delay between frames
*
* @param[in] u4_intra_frame_interval
* Intra frame interval
*
* @param[in] pu1_init_qp
* Initial qp
*
* @param[in] i4_max_inter_frm_int
* Maximum inter frame interval
*
* @param[in] pu1_min_max_qp
* Array of min/max qp
*
* @param[in] u1_profile_level
* Encoder profile level
*
* @returns none
*
* @remarks
*
*******************************************************************************
*/
void ih264e_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)
{
// UWORD8 u1_is_mb_level_rc_on = 0;
UWORD32 au4_peak_bit_rate[2] = {0,0};
UWORD32 u4_min_bit_rate = 0;
WORD32 i4_is_gop_closed = 1;
// WORD32 i4_use_est_intra_sad = 1;
UWORD32 u4_src_ticks = 0;
UWORD32 u4_tgt_ticks = 0;
UWORD8 u1_level_idx = ih264e_get_lvl_idx(u1_profile_level);
UWORD32 u4_max_cpb_size = 1200 * gas_ih264_lvl_tbl[u1_level_idx].u4_max_cpb_size;
/* Fill the params needed for the RC init */
if (e_rate_control_type == CBR_NLDRC)
{
au4_peak_bit_rate[0] = u4_avg_bit_rate;
au4_peak_bit_rate[1] = u4_avg_bit_rate;
}
else
{
au4_peak_bit_rate[0] = u4_peak_bit_rate;
au4_peak_bit_rate[1] = u4_peak_bit_rate;
}
/* Initialize frame time computation module*/
ih264e_init_frame_time(pv_frame_time,
u4_src_frm_rate, /* u4_src_frm_rate */
u4_tgt_frm_rate); /* u4_tgt_frm_rate */
/* Initialize the pull_down frame rate */
ih264e_init_pd_frm_rate(pv_pd_frm_rate,
u4_src_frm_rate); /* u4_input_frm_rate */
/* Initialize time stamp structure */
ih264e_init_time_stamp(pv_time_stamp,
u4_max_frm_rate, /* u4_max_frm_rate */
u4_src_frm_rate); /* u4_src_frm_rate */
u4_src_ticks = ih264e_frame_time_get_src_ticks(pv_frame_time);
u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(pv_frame_time);
/* Init max_inter_frame int */
i4_max_inter_frm_int = (i4_inter_frm_int == 1) ? 2 : (i4_inter_frm_int + 2);
/* Initialize the rate control */
irc_initialise_rate_control(pv_rc_api, /* RC handle */
e_rate_control_type, /* RC algo type */
0, /* MB activity on/off */
u4_avg_bit_rate, /* Avg Bitrate */
au4_peak_bit_rate, /* Peak bitrate array[2]:[I][P] */
u4_min_bit_rate, /* Min Bitrate */
u4_src_frm_rate, /* Src frame_rate */
u4_max_delay, /* Max buffer delay */
u4_intra_frame_interval, /* Intra frm_interval */
i4_inter_frm_int, /* Inter frame interval */
pu1_init_qp, /* Init QP array[3]:[I][P][B] */
u4_max_cpb_size, /* Max VBV/CPB Buffer Size */
i4_max_inter_frm_int, /* Max inter frm_interval */
i4_is_gop_closed, /* Open/Closed GOP */
pu1_min_max_qp, /* Min-max QP array[6]:[Imax][Imin][Pmax][Pmin][Bmax][Bmin] */
0, /* How to calc the I-frame estimated_sad */
u4_src_ticks, /* Src_ticks = LCM(src_frm_rate,tgt_frm_rate)/src_frm_rate */
u4_tgt_ticks); /* Tgt_ticks = LCM(src_frm_rate,tgt_frm_rate)/tgt_frm_rate */
}
/**
*******************************************************************************
*
* @brief Function to get picture details
*
* @par Description
* This function returns the Picture type(I/P/B)
*
* @param[in] pv_rc_api
* Handle to Rate control api
*
* @returns
* Picture type
*
* @remarks none
*
*******************************************************************************
*/
picture_type_e ih264e_rc_get_picture_details(void *pv_rc_api,
WORD32 *pi4_pic_id,
WORD32 *pi4_pic_disp_order_no)
{
picture_type_e e_rc_pic_type = P_PIC;
irc_get_picture_details(pv_rc_api, pi4_pic_id, pi4_pic_disp_order_no,
&e_rc_pic_type);
return (e_rc_pic_type);
}
/**
*******************************************************************************
*
* @brief Function to catch frame skips before encoding due to source framerate
* pulldown
*
* @par Description
* This function is called before queuing the current frame. It decides if we
* should skip the current input buffer due to frame rate mismatch. It also
* updates RC about the framerate pulldown
*
* @param[in] ps_rate_control_api
* Handle to rate control api
*
* @param[in] ps_pd_frm_rate
* Handle to pull down frm rate context
*
* @param[in] ps_time_stamp
* Handle to time stamp context
*
* @param[in] ps_frame_time
* Handle to frame time context
*
* @returns
* Skip or queue the current frame
*
* @remarks
*
*******************************************************************************
*/
WORD32 ih264e_update_rc_framerates(void *ps_rate_control_api,
void *ps_pd_frm_rate,
void *ps_time_stamp,
void *ps_frame_time)
{
WORD8 i4_skip_src = 0;
UWORD32 u4_src_not_skipped_for_dts = 0;
/* Update the time stamp for the current frame */
ih264e_update_time_stamp(ps_time_stamp);
/* Check if a src not needs to be skipped */
i4_skip_src = ih264e_should_src_be_skipped(ps_frame_time,
1,
&u4_src_not_skipped_for_dts);
if (i4_skip_src)
{
/***********************************************************************
*Based on difference in source and target frame rate frames are skipped
***********************************************************************/
/*update the missing frames frm_rate with 0 */
ih264e_update_pd_frm_rate(ps_pd_frm_rate, 0);
}
else
{
WORD32 i4_avg_frm_rate, i4_source_frame_rate;
i4_source_frame_rate = ih264e_frame_time_get_src_frame_rate(
ps_frame_time);
/* Update the frame rate of the frame present with the tgt_frm_rate */
/* If the frm was not skipped due to delta_time_stamp, update the
frame_rate with double the tgt_frame_rate value, so that it makes
up for one of the frames skipped by the application */
ih264e_update_pd_frm_rate(ps_pd_frm_rate, i4_source_frame_rate);
/* Based on the update get the average frame rate */
i4_avg_frm_rate = ih264e_get_pd_avg_frm_rate(ps_pd_frm_rate);
/* Call the RC library function to change the frame_rate to the
actually achieved frm_rate */
irc_change_frm_rate_for_bit_alloc(ps_rate_control_api, i4_avg_frm_rate);
}
return (i4_skip_src);
}
/**
*******************************************************************************
*
* @brief Function to update mb info for rate control context
*
* @par Description
* After encoding a mb, information such as mb type, qp used, mb distortion
* resulted in encoding the block and so on needs to be preserved for modeling
* RC. This is preserved via this function call.
*
* @param[in] ps_frame_info
* Handle Frame info context
*
* @param[in] ps_proc
* Process context
*
* @returns
*
* @remarks
*
*******************************************************************************
*/
void ih264e_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc)
{
/* proc ctxt */
process_ctxt_t *ps_proc = pv_proc;
/* is intra or inter */
WORD32 mb_type = !ps_proc->u4_is_intra;
/* distortion */
ps_frame_info->tot_mb_sad[mb_type] += ps_proc->i4_mb_distortion;
/* qp */
ps_frame_info->qp_sum[mb_type] += gau1_h264_to_mpeg2_qmap[ps_proc->u4_mb_qp];
/* mb cnt */
ps_frame_info->num_mbs[mb_type]++;
/* cost */
if (ps_proc->i4_mb_intra_cost != INT_MAX)
{
ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_intra_cost;
}
else
{
/* codec context */
codec_t *ps_codec = ps_proc->ps_codec;
/* temp var */
WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * ps_proc->i4_wd_mbs;
ps_frame_info->intra_mb_cost_sum += ps_codec->pi4_mb_intra_cost[i4_mb_id];
}
}
/**
*******************************************************************************
*
* @brief Function to get rate control buffer status
*
* @par Description
* This function is used to get buffer status(underflow/overflow) by rate
* control module
*
* @param[in] pv_rc_api
* Handle to rate control api context
*
* @param[in] i4_total_frame_bits
* Total frame bits
*
* @param[in] u1_pic_type
* Picture type
*
* @param[in] pi4_num_bits_to_prevent_vbv_underflow
* Number of bits to prevent underflow
*
* @param[out] pu1_is_enc_buf_overflow
* Buffer overflow indication flag
*
* @param[out] pu1_is_enc_buf_underflow
* Buffer underflow indication flag
*
* @returns
*
* @remarks
*
*******************************************************************************
*/
void ih264e_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)
{
vbv_buf_status_e e_vbv_buf_status = VBV_NORMAL;
e_vbv_buf_status = irc_get_buffer_status(pv_rc_api,
i4_total_frame_bits,
e_pic_type,
pi4_num_bits_to_prevent_vbv_underflow);
if (e_vbv_buf_status == VBV_OVERFLOW)
{
*pu1_is_enc_buf_underflow = 1;
*pu1_is_enc_buf_overflow = 0;
}
else if (e_vbv_buf_status == VBV_UNDERFLOW)
{
*pu1_is_enc_buf_underflow = 0;
*pu1_is_enc_buf_overflow = 1;
}
else
{
*pu1_is_enc_buf_underflow = 0;
*pu1_is_enc_buf_overflow = 0;
}
}
/**
*******************************************************************************
*
* @brief Function to update rate control module after encoding
*
* @par Description
* This function is used to update the rate control module after the current
* frame encoding is done with details such as bits consumed, SAD for I/P/B,
* intra cost, mb type and other
*
* @param[in] ps_rate_control_api
* Handle to rate control api context
*
* @param[in] ps_frame_info
* Handle to frame info context
*
* @param[in] ps_pd_frm_rate
* Handle to pull down frame rate context
*
* @param[in] ps_time_stamp
* Handle to time stamp context
*
* @param[in] ps_frame_time
* Handle to frame time context
*
* @param[in] i4_total_mb_in_frame
* Total mb in frame
*
* @param[in] pe_vop_coding_type
* Picture coding type
*
* @param[in] i4_is_first_frame
* Is first frame
*
* @param[out] pi4_is_post_encode_skip
* Post encoding skip flag
*
* @param[in] u1_frame_qp
* Frame qp
*
* @param[in] pi4_num_intra_in_prev_frame
* Numberf of intra mbs in previous frame
*
* @param[in] pi4_avg_activity
* Average activity
*
* @returns In case of underflow, number of stuffing bytes to be added and in
* case of overflow, flag signalling the encoder to avoid this frame from
* sending
*
* @remarks
*
*******************************************************************************
*/
WORD32 ih264e_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)
{
/* Variables for the update_frm_level_info */
WORD32 ai4_tot_mb_in_type[MAX_MB_TYPE];
WORD32 ai4_tot_mb_type_qp[MAX_MB_TYPE] = {0, 0};
WORD32 ai4_mb_type_sad[MAX_MB_TYPE] = {0, 0};
WORD32 ai4_mb_type_tex_bits[MAX_MB_TYPE] = {0, 0};
WORD32 i4_total_frame_bits = 0;
WORD32 i4_total_hdr_bits = 0;
WORD32 i4_total_texturebits;
WORD32 i4_avg_mb_activity = 0;
WORD32 i4_intra_frm_cost = 0;
UWORD8 u1_is_scd = 0;
WORD32 i4_cbr_bits_to_stuff = 0;
UWORD32 u4_num_intra_in_prev_frame = *pi4_num_intra_in_prev_frame;
UNUSED(ps_pd_frm_rate);
UNUSED(ps_time_stamp);
UNUSED(ps_frame_time);
UNUSED(u1_frame_qp);
/* Accumulate RC stats */
ai4_tot_mb_in_type[MB_TYPE_INTRA] = irc_fi_get_total_mb(ps_frame_info,MB_TYPE_INTRA);
ai4_tot_mb_in_type[MB_TYPE_INTER] = irc_fi_get_total_mb(ps_frame_info,MB_TYPE_INTER);
/* ai4_tot_mb_type_qp[MB_TYPE_INTRA] = 0;
ai4_tot_mb_type_qp[MB_TYPE_INTER] = ps_enc->pu1_h264_mpg2quant[u1_frame_qp] * i4_total_mb_in_frame;*/
ai4_tot_mb_type_qp[MB_TYPE_INTRA] = irc_fi_get_total_mb_qp(ps_frame_info,MB_TYPE_INTRA);
ai4_tot_mb_type_qp[MB_TYPE_INTER] = irc_fi_get_total_mb_qp(ps_frame_info,MB_TYPE_INTER);
ai4_mb_type_sad[MB_TYPE_INTRA] = irc_fi_get_total_mb_sad(ps_frame_info,MB_TYPE_INTRA);
ai4_mb_type_sad[MB_TYPE_INTER] = irc_fi_get_total_mb_sad(ps_frame_info,MB_TYPE_INTER);
i4_intra_frm_cost = irc_fi_get_total_intra_mb_cost(ps_frame_info);
i4_avg_mb_activity = irc_fi_get_avg_activity(ps_frame_info);
i4_total_hdr_bits = irc_fi_get_total_header_bits(ps_frame_info);
ai4_mb_type_tex_bits[MB_TYPE_INTRA] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTRA);
ai4_mb_type_tex_bits[MB_TYPE_INTER] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTER);
i4_total_texturebits = ai4_mb_type_tex_bits[MB_TYPE_INTRA] + ai4_mb_type_tex_bits[MB_TYPE_INTER];
i4_total_frame_bits = i4_total_hdr_bits + i4_total_texturebits ;
*pi4_avg_activity = i4_avg_mb_activity;
/* Set post encode skip to zero */
pi4_is_post_encode_skip[0]= 0;
/* For NLDRC, get the buffer status for stuffing or skipping */
/* Default NLDRC to CBR with no frame drops so the '0 &&'. */
if (0 && irc_get_rc_type(ps_rate_control_api) == CBR_NLDRC)
{
WORD32 i4_get_num_bit_to_prevent_vbv_overflow;
UWORD8 u1_enc_buf_overflow,u1_enc_buf_underflow;
/* Getting the buffer status */
ih264e_rc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits,
pe_vop_coding_type[0], &i4_get_num_bit_to_prevent_vbv_overflow,
&u1_enc_buf_overflow,&u1_enc_buf_underflow);
/* We skip the frame if decoder buffer is underflowing. But we never skip first I frame */
if ((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 1))
// if ((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 0))
{
irc_post_encode_frame_skip(ps_rate_control_api, (picture_type_e)pe_vop_coding_type[0]);
// i4_total_frame_bits = imp4_write_skip_frame_header(ps_enc);
i4_total_frame_bits = 0;
*pi4_is_post_encode_skip = 1;
/* Adjust the GOP if in case we skipped an I-frame */
if (*pe_vop_coding_type == I_PIC)
irc_force_I_frame(ps_rate_control_api);
/* Since this frame is skipped by writing 7 bytes header, we say this is a P frame */
// *pe_vop_coding_type = P;
/* Getting the buffer status again,to check if it underflows */
irc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits,
(picture_type_e)pe_vop_coding_type[0], &i4_get_num_bit_to_prevent_vbv_overflow);
}
/* In this case we stuff bytes as buffer is overflowing */
if (u1_enc_buf_underflow == 1)
{
/* The stuffing function is directly pulled out from split controller workspace.
encode_vop_data() function makes sure alignment data is dumped at the end of a
frame. Split controller was identifying this alignment byte, overwriting it with
the stuff data and then finally aligning the buffer. Here every thing is inside
the DSP. So, ideally encode_vop_data needn't align, and we can start stuffing directly.
But in that case, it'll break the logic for a normal frame.
Hence for simplicity, not changing this part since it is ok to align and
then overwrite since stuffing is not done for every frame */
i4_cbr_bits_to_stuff = irc_get_bits_to_stuff(ps_rate_control_api, i4_total_frame_bits, pe_vop_coding_type[0]);
/* Just add extra 32 bits to make sure we don't stuff lesser */
i4_cbr_bits_to_stuff += 32;
/* We can not stuff more than the outbuf size. So have a check here */
/* Add stuffed bits to total bits */
i4_total_frame_bits += i4_cbr_bits_to_stuff;
}
}
#define ENABLE_SCD 1
#if ENABLE_SCD
/* If number of intra MBs are more than 2/3rd of total MBs, assume it as a scene change */
if ((ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((2 * i4_total_mb_in_frame) / 3)) &&
(*pe_vop_coding_type == P_PIC) &&
(ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((11 * (WORD32)u4_num_intra_in_prev_frame) / 10)))
{
u1_is_scd = 1;
}
#endif
/* Update num intra mbs of this frame */
if (pi4_is_post_encode_skip[0] == 0)
{
*pi4_num_intra_in_prev_frame = ai4_tot_mb_in_type[MB_TYPE_INTRA];
}
/* Reset intra count to zero, if u encounter an I frame */
if (*pe_vop_coding_type == I_PIC)
{
*pi4_num_intra_in_prev_frame = 0;
}
/* Do an update of rate control after post encode */
irc_update_frame_level_info(ps_rate_control_api, /* RC state */
pe_vop_coding_type[0], /* PIC type */
ai4_mb_type_sad, /* SAD for [Intra/Inter] */
i4_total_frame_bits, /* Total frame bits */
i4_total_hdr_bits, /* header bits for */
ai4_mb_type_tex_bits, /* for MB[Intra/Inter] */
ai4_tot_mb_type_qp, /* for MB[Intra/Inter] */
ai4_tot_mb_in_type, /* for MB[Intra/Inter] */
i4_avg_mb_activity, /* Average mb activity in frame */
u1_is_scd, /* Is a scene change detected */
0, /* Pre encode skip */
(WORD32)i4_intra_frm_cost, /* Intra cost for frame */
0); /* Not done outside */
return (i4_cbr_bits_to_stuff >> 3);
}
/**
*******************************************************************************
*
* @brief Function to update total header and texture bits consumed information
* to rate control context
*
* @par Description
* Function to update total header and texture bits consumed information
* to rate control context
*
* @param[in] ps_frame_info
* Frame info context
*
* @param[in] ps_entropy
* Entropy context
*
* @returns none
*
* @remarks
*
*******************************************************************************
*/
void ih264e_update_rc_bits_info(frame_info_t *ps_frame_info, void *pv_entropy)
{
entropy_ctxt_t *ps_entropy = pv_entropy;
ps_frame_info->mb_header_bits[MB_TYPE_INTRA] += ps_entropy->u4_header_bits[MB_TYPE_INTRA];
ps_frame_info->mb_texture_bits[MB_TYPE_INTRA] += ps_entropy->u4_residue_bits[MB_TYPE_INTRA];
ps_frame_info->mb_header_bits[MB_TYPE_INTER] += ps_entropy->u4_header_bits[MB_TYPE_INTER];
ps_frame_info->mb_texture_bits[MB_TYPE_INTER] += ps_entropy->u4_residue_bits[MB_TYPE_INTER];
return;
}