From f0b559e4dc5c9f1ce0c1e5c6d9ee3e06321dfef7 Mon Sep 17 00:00:00 2001 From: Ram Mohan M Date: Fri, 29 Sep 2023 15:10:04 +0530 Subject: [PATCH] libavcenc: forward current frame intra cost to rc accurately --- encoder/ih264e_api.c | 24 ++++++++++++++++++++++++ encoder/ih264e_defs.h | 5 +++++ encoder/ih264e_intra_modes_eval.c | 16 ++++++++++++++++ encoder/ih264e_process.c | 9 +++++++-- encoder/ih264e_rate_control.c | 31 +++++++++++++++++++++---------- encoder/ih264e_structs.h | 7 +++++++ encoder/ih264e_utils.c | 6 ++++++ 7 files changed, 86 insertions(+), 12 deletions(-) diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index ab7f8c3f..010004c5 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -3602,6 +3602,25 @@ static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) } DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size); + /************************************************************************ + * Frame level Intra Cost Map. During intra/inter analysis preserve the* + * intra mb cost for future complexity estimation. * + * NOTE: The cost map is a overlay on the previous frame. In case if an* + * mb is not intra analyzed, the cost here represents its collocated mb* + * intra cost. This traversal can go till the latest I frame at worse * + ************************************************************************/ + ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_COST]; + { + /* total size of the mem record */ + WORD32 total_size = 0; + + /* size in bytes to mb core coding status of an entire frame */ + total_size = max_mb_cnt * sizeof(WORD32); + + ps_mem_rec->u4_mem_size = total_size; + } + DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_COST, ps_mem_rec->u4_mem_size); + /************************************************************************ * Request memory for SPS * ***********************************************************************/ @@ -4519,6 +4538,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, } } + ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_COST]; + { + ps_codec->pi4_mb_intra_cost = ps_mem_rec->pv_base; + } + ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; { ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base; diff --git a/encoder/ih264e_defs.h b/encoder/ih264e_defs.h index 7f695544..1ed57797 100644 --- a/encoder/ih264e_defs.h +++ b/encoder/ih264e_defs.h @@ -347,6 +347,11 @@ enum */ MEM_REC_MVBITS, + /** + * Overlay Intra Cost Map + */ + MEM_REC_INTRA_COST, + /** * Holds mem records passed to the codec. */ diff --git a/encoder/ih264e_intra_modes_eval.c b/encoder/ih264e_intra_modes_eval.c index 3edf98fe..6023aea3 100644 --- a/encoder/ih264e_intra_modes_eval.c +++ b/encoder/ih264e_intra_modes_eval.c @@ -479,6 +479,10 @@ void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps ps_proc->i4_mb_distortion = i4_mb_distortion_least; ps_proc->u4_mb_type = I16x16; } + if (i4_mb_cost_least < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_mb_cost_least; + } return ; } @@ -727,6 +731,10 @@ void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I8x8; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } @@ -998,6 +1006,10 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I4x4; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } @@ -1336,6 +1348,10 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_pr ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I4x4; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index 406f5631..abeea1e7 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -1092,6 +1092,11 @@ WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc) ih264_list_terminate(ps_codec->pv_entropy_jobq); } + /* update intra cost if valid */ + if (ps_proc->i4_mb_intra_cost != INT_MAX) { + ps_codec->pi4_mb_intra_cost[(i4_mb_y * i4_wd_mbs) + i4_mb_x] = ps_proc->i4_mb_intra_cost; + } + /* update proc map */ pu1_proc_map[i4_mb_x] = 1; @@ -1126,10 +1131,9 @@ WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->apu1_ref_buf_chroma[0] += MB_SIZE; ps_proc->apu1_ref_buf_chroma[1] += MB_SIZE; - - /* Reset cost, distortion params */ ps_proc->i4_mb_cost = INT_MAX; + ps_proc->i4_mb_intra_cost = INT_MAX; ps_proc->i4_mb_distortion = SHRT_MAX; ps_proc->ps_pu += *ps_proc->pu4_mb_pu_cnt; @@ -1473,6 +1477,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) /* mb cost */ ps_proc->i4_mb_cost = INT_MAX; + ps_proc->i4_mb_intra_cost = INT_MAX; /**********************/ /* init deblk context */ diff --git a/encoder/ih264e_rate_control.c b/encoder/ih264e_rate_control.c index 4e7b4e92..1c96f69e 100644 --- a/encoder/ih264e_rate_control.c +++ b/encoder/ih264e_rate_control.c @@ -48,6 +48,14 @@ /* File Includes */ /*****************************************************************************/ +/* System include files */ +#include +#include +#include +#include +#include +#include + /* User include files */ #include "irc_datatypes.h" #include "iv2.h" @@ -417,9 +425,16 @@ void ih264e_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc) ps_frame_info->num_mbs[mb_type]++; /* cost */ - if (ps_proc->u4_is_intra) - { - ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_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]; } } @@ -581,17 +596,13 @@ WORD32 ih264e_rc_post_enc(void * ps_rate_control_api, 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); - i4_total_texturebits = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTRA); - i4_total_texturebits += irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTER); + 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; - - /* Texture bits are not accumulated. Hence subtracting hdr bits from total bits */ - ai4_mb_type_tex_bits[MB_TYPE_INTRA] = 0; - ai4_mb_type_tex_bits[MB_TYPE_INTER] = i4_total_frame_bits - i4_total_hdr_bits; - /* Set post encode skip to zero */ pi4_is_post_encode_skip[0]= 0; diff --git a/encoder/ih264e_structs.h b/encoder/ih264e_structs.h index 898387d4..2920b172 100644 --- a/encoder/ih264e_structs.h +++ b/encoder/ih264e_structs.h @@ -1705,6 +1705,7 @@ struct _proc_t * mb cost */ WORD32 i4_mb_cost; + WORD32 i4_mb_intra_cost; /********************************************************************/ /* i4_ngbr_avbl_mb_16 - ngbr avbl of curr mb */ @@ -2585,6 +2586,12 @@ struct _codec_t */ UWORD16 *pu2_intr_rfrsh_map; + /* + * Intra MB Cost Map + * Stores the intra cost of all mb of a frame + */ + WORD32 *pi4_mb_intra_cost; + /* * Indicates if the current frame is used as a reference frame */ diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index 5c9dc33e..aec55764 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -1283,6 +1283,12 @@ IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) ps_codec->i4_air_pic_cnt = -1; } + /*****************************************************************/ + /* Initialize Intra Cost Map */ + /*****************************************************************/ + memset(ps_codec->pi4_mb_intra_cost, 0, ps_codec->s_cfg.i4_wd_mbs * + ps_codec->s_cfg.i4_ht_mbs * sizeof(*ps_codec->pi4_mb_intra_cost)); + /****************************************************/ /* INITIALIZE RATE CONTROL */ /****************************************************/