aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWonsik Kim <wonsik@google.com>2019-05-28 18:41:54 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-05-28 18:41:54 +0000
commit1e1bf6f80da829536cfbb14d28e45e7c587ae36e (patch)
tree4623c362ccdf22ddbc4ad33792820e8202948cb6
parent74e2f929371931e4342f8446fd547cdc95d59dbd (diff)
parent5c55da991363746f6cfe7ac856dde785c12bf414 (diff)
downloadlibhevc-1e1bf6f80da829536cfbb14d28e45e7c587ae36e.tar.gz
Merge "libhevcenc: Add support for dynamic change in bitrate" into qt-dev
-rw-r--r--encoder/ihevce_frame_process_utils.c52
-rw-r--r--encoder/ihevce_frame_process_utils.h2
-rw-r--r--encoder/ihevce_hle_interface.c5
-rw-r--r--encoder/ihevce_lap_interface.c85
-rw-r--r--encoder/ihevce_lap_interface.h27
-rw-r--r--encoder/ihevce_plugin.c55
-rw-r--r--test/encoder/main.c12
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);