Validate input dimensions in process()

Input dimensions are checked for supported range in set_dimensions
control call. Encoder returns an error for unsupported values in
this control call. But if the caller ignores this error and proceeds
to call process(), encoder wasn't checking the dimensions again.

Unsupported dimensions are now checked in process() call as well.

Note: This is relanding previously reverted commit
06c30b33c4

Bug: 172908358
Test: Poc in bug
Test: atest android.mediav2.cts
Test: atest android.media.cts
Change-Id: Icf3f296ab24432c680427a82da3505491acca3bd
This commit is contained in:
Harish Mahendrakar 2020-11-17 06:44:57 +05:30 committed by Ray Essick
parent c74dab7a5a
commit daa5c36657

View file

@ -138,6 +138,101 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control,
/* Function Definitions */ /* Function Definitions */
/*****************************************************************************/ /*****************************************************************************/
/**
*******************************************************************************
*
* @brief
* Used to test validity of input dimensions
*
* @par Description:
* Dimensions of the input buffer passed to encode call are validated
*
* @param[in] ps_codec
* Codec context
*
* @param[in] ps_ip
* Pointer to input structure
*
* @param[out] ps_op
* Pointer to output structure
*
* @returns error status
*
* @remarks none
*
*******************************************************************************
*/
static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec,
ih264e_video_encode_ip_t *ps_ip,
ih264e_video_encode_op_t *ps_op)
{
UWORD32 u4_wd, u4_ht;
cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf;
u4_wd = ps_inp_buf->au4_wd[0];
u4_ht = ps_inp_buf->au4_ht[0];
switch (ps_inp_buf->e_color_fmt)
{
case IV_YUV_420P:
if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) ||
((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) ||
(ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2]))
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
return (IV_FAIL);
}
if (((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) ||
((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) ||
(ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2]))
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
return (IV_FAIL);
}
break;
case IV_YUV_420SP_UV:
case IV_YUV_420SP_VU:
if ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1])
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
return (IV_FAIL);
}
if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1])
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
return (IV_FAIL);
}
break;
case IV_YUV_422ILE:
u4_wd = ps_inp_buf->au4_wd[0] / 2;
break;
default:
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
return (IV_FAIL);
}
if (u4_wd != ps_curr_cfg->u4_disp_wd)
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
return (IV_FAIL);
}
if (u4_ht != ps_curr_cfg->u4_disp_ht)
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
return (IV_FAIL);
}
return IV_SUCCESS;
}
/** /**
******************************************************************************* *******************************************************************************
* *
@ -818,6 +913,7 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
case IVE_CMD_VIDEO_ENCODE: case IVE_CMD_VIDEO_ENCODE:
{ {
codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle);
ih264e_video_encode_ip_t *ps_ip = pv_api_ip; ih264e_video_encode_ip_t *ps_ip = pv_api_ip;
ih264e_video_encode_op_t *ps_op = pv_api_op; ih264e_video_encode_op_t *ps_op = pv_api_op;
@ -836,6 +932,15 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL); return (IV_FAIL);
} }
if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] &&
ps_codec->i4_header_mode != 1 &&
IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op))
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
break; break;
} }
@ -4059,6 +4164,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj,
/* Update config params as per input */ /* Update config params as per input */
ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
/* Initialize dimensions to max dimensions during init */
ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd;
ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_ht;
ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt; ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;