diff options
author | Wonsik Kim <wonsik@google.com> | 2019-05-28 18:41:54 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-05-28 18:41:54 +0000 |
commit | 1e1bf6f80da829536cfbb14d28e45e7c587ae36e (patch) | |
tree | 4623c362ccdf22ddbc4ad33792820e8202948cb6 | |
parent | 74e2f929371931e4342f8446fd547cdc95d59dbd (diff) | |
parent | 5c55da991363746f6cfe7ac856dde785c12bf414 (diff) | |
download | libhevc-1e1bf6f80da829536cfbb14d28e45e7c587ae36e.tar.gz |
Merge "libhevcenc: Add support for dynamic change in bitrate" into qt-dev
-rw-r--r-- | encoder/ihevce_frame_process_utils.c | 52 | ||||
-rw-r--r-- | encoder/ihevce_frame_process_utils.h | 2 | ||||
-rw-r--r-- | encoder/ihevce_hle_interface.c | 5 | ||||
-rw-r--r-- | encoder/ihevce_lap_interface.c | 85 | ||||
-rw-r--r-- | encoder/ihevce_lap_interface.h | 27 | ||||
-rw-r--r-- | encoder/ihevce_plugin.c | 55 | ||||
-rw-r--r-- | test/encoder/main.c | 12 |
7 files changed, 237 insertions, 1 deletions
diff --git a/encoder/ihevce_frame_process_utils.c b/encoder/ihevce_frame_process_utils.c index 7aa7d1d..a9c618b 100644 --- a/encoder/ihevce_frame_process_utils.c +++ b/encoder/ihevce_frame_process_utils.c @@ -395,6 +395,58 @@ void ihevce_fill_sei_payload( /*! ****************************************************************************** +* \if Function name : ihevce_dyn_bitrate \endif +* +* \brief +* Call back function to be called for changing the bitrate +* +* +* \return +* None +* +* \author +* Ittiam +* +***************************************************************************** +*/ +void ihevce_dyn_bitrate(void *pv_hle_ctxt, void *pv_dyn_bitrate_prms) +{ + ihevce_hle_ctxt_t *ps_hle_ctxt = (ihevce_hle_ctxt_t *)pv_hle_ctxt; + ihevce_dyn_config_prms_t *ps_dyn_bitrate_prms = (ihevce_dyn_config_prms_t *)pv_dyn_bitrate_prms; + enc_ctxt_t *ps_enc_ctxt = + (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[ps_dyn_bitrate_prms->i4_tgt_res_id]; + ihevce_static_cfg_params_t *ps_static_cfg_params = ps_hle_ctxt->ps_static_cfg_prms; + + if(ps_enc_ctxt->ps_stat_prms->i4_log_dump_level > 0) + { + ps_static_cfg_params->s_sys_api.ihevce_printf( + ps_static_cfg_params->s_sys_api.pv_cb_handle, + "\n Average Bitrate changed to %d", + ps_dyn_bitrate_prms->i4_new_tgt_bitrate); + ps_static_cfg_params->s_sys_api.ihevce_printf( + ps_static_cfg_params->s_sys_api.pv_cb_handle, + "\n Peak Bitrate changed to %d", + ps_dyn_bitrate_prms->i4_new_peak_bitrate); + } + + + /* acquire mutex lock for rate control calls */ + osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl); + + ihevce_rc_register_dyn_change_bitrate( + ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[ps_dyn_bitrate_prms->i4_tgt_br_id], + (LWORD64)ps_dyn_bitrate_prms->i4_new_tgt_bitrate, + (LWORD64)ps_dyn_bitrate_prms->i4_new_peak_bitrate, + ps_dyn_bitrate_prms->i4_new_rate_factor, + ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode); + + /*unlock rate control context*/ + osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl); + return; +} + +/*! +****************************************************************************** * \if Function name : ihevce_validate_encoder_parameters \endif * * \brief diff --git a/encoder/ihevce_frame_process_utils.h b/encoder/ihevce_frame_process_utils.h index abbd104..fef5b44 100644 --- a/encoder/ihevce_frame_process_utils.h +++ b/encoder/ihevce_frame_process_utils.h @@ -81,4 +81,6 @@ void ihevce_fill_sei_payload( ihevce_lap_enc_buf_t *ps_curr_inp, frm_proc_ent_cod_ctxt_t *ps_curr_out); +void ihevce_dyn_bitrate(void *pv_hle_ctxt, void *pv_dyn_bitrate_prms); + #endif /* _IHEVCE_FRAME_PROCESS_UTILS_H_ */ diff --git a/encoder/ihevce_hle_interface.c b/encoder/ihevce_hle_interface.c index cc35f64..3d9926e 100644 --- a/encoder/ihevce_hle_interface.c +++ b/encoder/ihevce_hle_interface.c @@ -1211,8 +1211,13 @@ WORD32 ihevce_hle_interface_thrd(void *pv_proc_intf_ctxt) ps_lap_interface_ctxt->pv_hle_ctxt = ps_hle_ctxt; ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0]; ps_lap_interface_ctxt->pv_lap_module_ctxt = ps_enc_ctxt->s_module_ctxt.pv_lap_ctxt; + ps_lap_interface_ctxt->i4_ctrl_in_que_id = IHEVCE_INPUT_ASYNCH_CTRL_Q; + ps_lap_interface_ctxt->i4_ctrl_out_que_id = IHEVCE_OUTPUT_STATUS_Q; + ps_lap_interface_ctxt->i4_ctrl_cmd_buf_size = ENC_COMMAND_BUFF_SIZE; + ps_lap_interface_ctxt->i4_ctrl_in_que_blocking_mode = BUFF_QUE_BLOCKING_MODE; ps_lap_interface_ctxt->ps_sys_api = &ps_enc_ctxt_base->ps_stat_prms->s_sys_api; ps_enc_ctxt_base->pv_lap_interface_ctxt = (void *)ps_lap_interface_ctxt; + ps_lap_interface_ctxt->ihevce_dyn_bitrate_cb = ihevce_dyn_bitrate; } /* --------------------------------------------------------------------- */ diff --git a/encoder/ihevce_lap_interface.c b/encoder/ihevce_lap_interface.c index f716b45..5125e03 100644 --- a/encoder/ihevce_lap_interface.c +++ b/encoder/ihevce_lap_interface.c @@ -705,6 +705,56 @@ void ihevce_lap_parse_sync_cmd( /*! ************************************************************************ * \brief +* lap parse Async commands +************************************************************************ +*/ +void ihevce_lap_parse_async_cmd( + ihevce_hle_ctxt_t *ps_hle_ctxt, + WORD32 *pi4_cmd_buf, + WORD32 i4_length, + WORD32 i4_buf_id, + WORD32 *pi4_num_set_bitrate_cmds, + ihevce_dyn_config_prms_t *ps_dyn_br) +{ + WORD32 i4_end_flag = 0; + WORD32 *pi4_end = pi4_cmd_buf + (i4_length >> 2) - 1; + WORD32 *pi4_tag_parse = pi4_cmd_buf; + + while(pi4_tag_parse != pi4_end) + { + switch(*pi4_tag_parse) + { + case IHEVCE_ASYNCH_API_SETBITRATE_TAG: + if((*(pi4_tag_parse + 1)) != sizeof(ihevce_dyn_config_prms_t)) + ps_hle_ctxt->ihevce_cmds_error_report( + ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_BR_NOT_BYTE, 1, i4_buf_id); + + memcpy( + (void *)ps_dyn_br, (void *)(pi4_tag_parse + 2), sizeof(ihevce_dyn_config_prms_t)); + pi4_tag_parse += 2; + pi4_tag_parse += (sizeof(ihevce_dyn_config_prms_t) >> 2); + *pi4_num_set_bitrate_cmds = *pi4_num_set_bitrate_cmds + 1; + ps_dyn_br++; + + break; + case IHEVCE_ASYNCH_API_END_TAG: + i4_end_flag = 1; + break; + default: + ps_hle_ctxt->ihevce_cmds_error_report( + ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_TLV_ERROR, 1, i4_buf_id); + } + if(i4_end_flag) + break; + } + if(!i4_end_flag) + ps_hle_ctxt->ihevce_cmds_error_report( + ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_NO_END_TAG, 1, i4_buf_id); +} + +/*! +************************************************************************ +* \brief * ref pics weight offset calculation ************************************************************************ */ @@ -2011,12 +2061,47 @@ ihevce_lap_enc_buf_t *ihevce_lap_process(void *pv_interface_ctxt, ihevce_lap_enc WORD32 i4_force_idr_check = 0; WORD32 i4_set_res_check = 0; WORD32 i4_tree_num = 0; + iv_input_ctrl_buffs_t *ps_ctrl_buf = NULL; + WORD32 buf_id = 0; + + ps_lap_interface->i4_ctrl_in_que_blocking_mode = BUFF_QUE_NON_BLOCKING_MODE; /* ----------- LAP processing ----------- */ if(ps_lap_struct->end_flag != 1) { ASSERT(NULL != ps_curr_inp); + /* ---------- get the filled control command buffer ------------ */ + ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_filled_buff( + ps_hle_ctxt->apv_enc_hdl[0], + ps_lap_interface->i4_ctrl_in_que_id, + &buf_id, + ps_lap_interface->i4_ctrl_in_que_blocking_mode); + + /* ----------- check the command ---------------------- */ + if(NULL != ps_ctrl_buf) + { + /* check for async errors */ + ihevce_dyn_config_prms_t as_dyn_br[MAX_NUM_DYN_BITRATE_CMDS]; + WORD32 i4_num_set_bitrate_cmds = 0; + WORD32 bitrt_ctr = 0; + + ihevce_lap_parse_async_cmd( + ps_hle_ctxt, + (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs, + ps_ctrl_buf->i4_cmd_buf_size, + ps_ctrl_buf->i4_buf_id, + &i4_num_set_bitrate_cmds, + &as_dyn_br[0]); + + /* Call the call back function to register the new bitrate */ + for(bitrt_ctr = 0; bitrt_ctr < i4_num_set_bitrate_cmds; bitrt_ctr++) + { + ps_lap_interface->ihevce_dyn_bitrate_cb( + (void *)ps_hle_ctxt, (void *)&as_dyn_br[bitrt_ctr]); + } + } + { WORD32 *pi4_cmd_buf = (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs; diff --git a/encoder/ihevce_lap_interface.h b/encoder/ihevce_lap_interface.h index dadf429..748e1bf 100644 --- a/encoder/ihevce_lap_interface.h +++ b/encoder/ihevce_lap_interface.h @@ -49,6 +49,33 @@ typedef struct ihevce_sys_api_t *ps_sys_api; void *pv_hle_ctxt; void *pv_lap_module_ctxt; + + /** + * Control Input buffer Queue id + */ + + WORD32 i4_ctrl_in_que_id; + /** + * + *EnC and application owned command buffer size + */ + WORD32 i4_ctrl_cmd_buf_size; + + /** + * Control Input buffer blocking mode + */ + WORD32 i4_ctrl_in_que_blocking_mode; + + /** + * Control output buffer Queue id + */ + WORD32 i4_ctrl_out_que_id; + + /** + * Dynamic bitrate change Callback function + */ + void (*ihevce_dyn_bitrate_cb)(void *pv_hle_ctxt, void *pv_dyn_bitrate_prms); + } lap_intface_t; /*****************************************************************************/ diff --git a/encoder/ihevce_plugin.c b/encoder/ihevce_plugin.c index 68a4d16..4f0e532 100644 --- a/encoder/ihevce_plugin.c +++ b/encoder/ihevce_plugin.c @@ -81,8 +81,10 @@ #include "ihevce_multi_thrd_structs.h" #include "ihevce_me_common_defs.h" #include "ihevce_error_codes.h" +#include "ihevce_error_checks.h" #include "ihevce_function_selector.h" #include "ihevce_enc_structs.h" +#include "ihevce_global_tables.h" #include "cast_types.h" #include "osal.h" @@ -2002,6 +2004,59 @@ IHEVCE_PLUGIN_STATUS_T if(IV_SUCCESS != result) return (IHEVCE_EFAIL); + + if(3 != ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_rate_control_mode) + { + /* Dynamic Change in bitrate not supported for multi res/MBR */ + /*** Check for change in bitrate command ***/ + if(ps_ctxt->ai4_old_bitrate[0][0] != ps_inp->i4_curr_bitrate) + { + WORD32 buf_id; + WORD32 *pi4_cmd_buf; + iv_input_ctrl_buffs_t *ps_ctrl_buf; + ihevce_dyn_config_prms_t *ps_dyn_br; + WORD32 codec_level_index = ihevce_get_level_index( + ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0] + .i4_codec_level); + WORD32 max_bitrate = + g_as_level_data[codec_level_index].i4_max_bit_rate + [ps_ctxt->ps_static_cfg_prms->s_out_strm_prms.i4_codec_tier] * + 1000; + + /* ---------- get a free buffer from command Q ------ */ + ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_free_inp_ctrl_buff( + ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE); + /* store the buffer id */ + ps_ctrl_buf->i4_buf_id = buf_id; + + /* get the buffer pointer */ + pi4_cmd_buf = (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs; + + /* store the set default command, encoder should use create time prms */ + *pi4_cmd_buf = IHEVCE_ASYNCH_API_SETBITRATE_TAG; + *(pi4_cmd_buf + 1) = sizeof(ihevce_dyn_config_prms_t); + + ps_dyn_br = (ihevce_dyn_config_prms_t *)(pi4_cmd_buf + 2); + ps_dyn_br->i4_size = sizeof(ihevce_dyn_config_prms_t); + ps_dyn_br->i4_tgt_br_id = 0; + ps_dyn_br->i4_tgt_res_id = 0; + ps_dyn_br->i4_new_tgt_bitrate = + MIN(ps_inp->i4_curr_bitrate, max_bitrate); + ps_dyn_br->i4_new_peak_bitrate = + MIN((ps_dyn_br->i4_new_tgt_bitrate << 1), max_bitrate); + + pi4_cmd_buf += 2; + pi4_cmd_buf += (sizeof(ihevce_dyn_config_prms_t) >> 2); + + *(pi4_cmd_buf) = IHEVCE_ASYNCH_API_END_TAG; + + /* ---------- set the buffer as produced ---------- */ + ihevce_q_set_inp_ctrl_buff_prod(ps_interface_ctxt, buf_id); + + ps_ctxt->ai4_old_bitrate[0][0] = ps_inp->i4_curr_bitrate; + } + } + ps_ctxt->u8_num_frames_queued++; } else diff --git a/test/encoder/main.c b/test/encoder/main.c index 68945d1..975b2ac 100644 --- a/test/encoder/main.c +++ b/test/encoder/main.c @@ -58,6 +58,11 @@ #include "app.h" /*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ +#define DYN_BITRATE_TEST 0 + +/*****************************************************************************/ /* Global definitions */ /*****************************************************************************/ @@ -1027,7 +1032,12 @@ IHEVCE_PLUGIN_STATUS_T libihevce_encode_frame(appl_ctxt_t *ps_ctxt, FILE *pf_inp { ps_inp_pic = NULL; } - +#if DYN_BITRATE_TEST + if((i4_num_frames == 200) && (ps_inp_pic != NULL)) + { + ps_inp_pic->i4_curr_bitrate = ps_inp_pic->i4_curr_bitrate << 1; + } +#endif /* call encoder process frame */ PROFILE_START(&s_profile_data); status = ihevce_encode(ps_ctxt->ihevceHdl, ps_inp_pic, &out_pic); |