From 10910bf9106eff724390255faa48f9f61dcfc744 Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Wed, 10 Mar 2021 10:03:39 +0530 Subject: [PATCH 1/2] avcenc: Add bitstream overflow check during emulation prevention Bug: 176533109 Test: poc in the bug description Change-Id: Ia83383f9b65cbde8d7a50a1af8a054936daa4d78 (cherry picked from commit b59de5a25f28f0fe411526b2e50bb8052957c517) --- encoder/ih264e_bitstream.c | 51 ++++----------------------- encoder/ih264e_bitstream.h | 72 ++++++++++++++++++++++++++------------ encoder/ih264e_cabac.c | 61 ++++++++++++++------------------ encoder/ih264e_cabac.h | 4 +-- encoder/ih264e_process.c | 4 +-- 5 files changed, 86 insertions(+), 106 deletions(-) diff --git a/encoder/ih264e_bitstream.c b/encoder/ih264e_bitstream.c index d79f637..9f73f69 100644 --- a/encoder/ih264e_bitstream.c +++ b/encoder/ih264e_bitstream.c @@ -182,27 +182,9 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* 4. insert remaining bits of code starting from msb of cur word */ /* 5. update bitsleft in current word and stream buffer offset */ /********************************************************************/ - UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; - - UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; - - WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; - - UWORD8* pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; - + IH264E_ERROR_T status = IH264E_SUCCESS; WORD32 i, rem_bits = (code_len - bits_left_in_cw); - - /*********************************************************************/ - /* Bitstream overflow check */ - /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ - /*********************************************************************/ - if((u4_strm_buf_offset + (WORD_SIZE>>3)) >= u4_max_strm_size) - { - /* return without corrupting the buffer beyond its size */ - return(IH264E_BITSTREAM_BUFFER_OVERFLOW); - } - /* insert parital code corresponding to bits left in cur word */ u4_cur_word |= u4_code_val >> rem_bits; @@ -211,7 +193,7 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); + status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); } /* insert the remaining bits from code val into current word */ @@ -220,9 +202,8 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* update the state variables and return success */ ps_bitstrm->u4_cur_word = u4_cur_word; ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits; - ps_bitstrm->i4_zero_bytes_run = zero_run; - ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; - return (IH264E_SUCCESS); + return (status); + } } @@ -281,22 +262,7 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word; WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw; WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3; - - UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; - UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; - WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; - UWORD8* pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; - - /*********************************************************************/ - /* Bitstream overflow check */ - /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ - /*********************************************************************/ - if((u4_strm_buf_offset + (WORD_SIZE>>3) - bytes_left_in_cw) >= - u4_max_strm_size) - { - /* return without corrupting the buffer beyond its size */ - return(IH264E_BITSTREAM_BUFFER_OVERFLOW); - } + IH264E_ERROR_T status = IH264E_SUCCESS; /* insert a 1 at the end of current word and flush all the bits */ u4_cur_word |= (1 << (bits_left_in_cw - 1)); @@ -309,18 +275,15 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); + status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); } - /* update the stream offset */ - ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; - /* Default init values for scratch variables of bitstream context */ ps_bitstrm->u4_cur_word = 0; ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; ps_bitstrm->i4_zero_bytes_run = 0; - return (IH264E_SUCCESS); + return (status); } /** diff --git a/encoder/ih264e_bitstream.h b/encoder/ih264e_bitstream.h index 9cd2b81..5b5c700 100644 --- a/encoder/ih264e_bitstream.h +++ b/encoder/ih264e_bitstream.h @@ -169,29 +169,7 @@ { \ const WORD32 len = (WORD32)((ps_bitstrm->i4_bits_left_in_cw) & 0x07);\ ih264e_put_bits(ps_bitstrm, (UWORD32)((1 << len) - 1), len); \ - } - - -/** -****************************************************************************** -* flush the bits in cur word byte by byte and copy to stream * -* (current word is assumed to be byte aligned) * -****************************************************************************** -*/ -#define BITSTREAM_FLUSH(ps_bitstrm) \ -{ \ - WORD32 i; \ - for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \ - { \ - UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \ - PUTBYTE_EPB(ps_bitstrm->pu1_strm_buffer, ps_bitstrm->u4_strm_buf_offset,\ - u1_next_byte, ps_bitstrm->i4_zero_bytes_run); \ - } \ - ps_bitstrm->u4_cur_word = 0; \ - ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ -} \ - - + } \ /*****************************************************************************/ @@ -245,6 +223,54 @@ typedef struct bitstrm } bitstrm_t; +/** +****************************************************************************** +* @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream +* Increments the stream offset and zero run correspondingly +****************************************************************************** +*/ +static inline IH264E_ERROR_T ih264e_put_byte_epb(bitstrm_t *ps_bitstrm, UWORD8 byte) +{ + if (INSERT_EPB(ps_bitstrm->i4_zero_bytes_run, byte)) + { + if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size) + { + return IH264E_BITSTREAM_BUFFER_OVERFLOW; + } + ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = EPB_BYTE; + ps_bitstrm->i4_zero_bytes_run = 0; + } + + if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size) + { + return IH264E_BITSTREAM_BUFFER_OVERFLOW; + } + ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = byte; + ps_bitstrm->i4_zero_bytes_run = byte ? 0 : ps_bitstrm->i4_zero_bytes_run + 1; + + return IH264E_SUCCESS; +} + +/** +****************************************************************************** +* flush the bits in cur word byte by byte and copy to stream * +* (current word is assumed to be byte aligned) * +****************************************************************************** +*/ +#define BITSTREAM_FLUSH(ps_bitstrm, err) \ +{ \ + WORD32 i; \ + for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \ + { \ + UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \ + err |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); \ + } \ + ps_bitstrm->u4_cur_word = 0; \ + ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ +} \ + + + /*****************************************************************************/ /* Extern Function Declarations */ /*****************************************************************************/ diff --git a/encoder/ih264e_cabac.c b/encoder/ih264e_cabac.c index 26ded4d..2d91058 100644 --- a/encoder/ih264e_cabac.c +++ b/encoder/ih264e_cabac.c @@ -242,18 +242,16 @@ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type) * ******************************************************************************* */ -void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) +IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen; UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; - UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset; - WORD32 zero_run = ps_stream->i4_zero_bytes_run; UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes; + IH264E_ERROR_T status = IH264E_SUCCESS; /************************************************************************/ /* Insert the carry (propogated in previous byte) along with */ @@ -274,17 +272,17 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) as per standard */ /* so check for previous four bytes and if it is equal to 0x00000303 then subtract u4_strm_buf_offset by 1 */ - if (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 - && pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) + if (pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 2] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 3] == 0x00 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 4] == 0x00) { - u4_strm_buf_offset -= 1; + ps_stream->u4_strm_buf_offset -= 1; } /* previous byte carry add will not result in overflow to */ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ - pu1_strm_buf[u4_strm_buf_offset - 1] += carry; - zero_run = 0; + pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] += carry; + ps_stream->i4_zero_bytes_run = 0; } /* Insert outstanding bytes (if any) */ @@ -292,7 +290,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) { UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); + status |= ih264e_put_byte_epb(ps_stream, u1_0_or_ff); u4_out_standing_bytes--; } @@ -307,7 +305,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) if (bits_left >= 8) { last_byte = (rem_bits >> (bits_left - 8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); + status |= ih264e_put_byte_epb(ps_stream, last_byte); bits_left -= 8; } @@ -315,16 +313,16 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) last_byte = (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left) | (1 << (7 - bits_left - 1))); last_byte &= 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); + status |= ih264e_put_byte_epb(ps_stream, last_byte); /* update the state variables and return success */ - ps_stream->u4_strm_buf_offset = u4_strm_buf_offset; ps_stream->i4_zero_bytes_run = 0; /* Default init values for scratch variables of bitstream context */ ps_stream->u4_cur_word = 0; ps_stream->i4_bits_left_in_cw = WORD_SIZE; } + return status; } /** @@ -349,15 +347,16 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) * ****************************************************************************** */ -void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) +IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen; + UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8); + IH264E_ERROR_T status = IH264E_SUCCESS; /* Sanity checks */ ASSERT((ps_cab_enc_env->u4_code_int_range >= 256) @@ -381,15 +380,11 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { /* actual bits depend on carry propogration */ ps_cab_enc_env->u4_out_standing_bytes++; - return ; } else { /* carry = 1 => putbit(1); carry propogated due to L renorm */ WORD32 carry = (lead_byte >> 8) & 0x1; - UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; - UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset; - WORD32 zero_run = ps_stream->i4_zero_bytes_run; UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes; @@ -407,17 +402,17 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) as per standard */ /* so check for previous four bytes and if it is equal to 0x00000303 then subtract u4_strm_buf_offset by 1 */ - if (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 - && pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) + if (pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 2] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 3] == 0x00 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 4] == 0x00) { - u4_strm_buf_offset -= 1; + ps_stream->u4_strm_buf_offset -= 1; } /* previous byte carry add will not result in overflow to */ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ - pu1_strm_buf[u4_strm_buf_offset - 1] += carry; - zero_run = 0; + pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] += carry; + ps_stream->i4_zero_bytes_run = 0; } /* Insert outstanding bytes (if any) */ @@ -425,7 +420,7 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); + status |= ih264e_put_byte_epb(ps_stream, u1_0_or_ff); u4_out_standing_bytes--; } @@ -433,13 +428,9 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) /* Insert the leading byte */ lead_byte &= 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run); - - /* update the state variables and return success */ - ps_stream->u4_strm_buf_offset = u4_strm_buf_offset; - ps_stream->i4_zero_bytes_run = zero_run; - + status |= ih264e_put_byte_epb(ps_stream, lead_byte); } + return status; } diff --git a/encoder/ih264e_cabac.h b/encoder/ih264e_cabac.h index e4722fa..bc4b07c 100644 --- a/encoder/ih264e_cabac.h +++ b/encoder/ih264e_cabac.h @@ -190,7 +190,7 @@ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type); * ******************************************************************************* */ -void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); +IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); /** @@ -215,7 +215,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); * ****************************************************************************** */ -void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt); +IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt); /** diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index 5fb0b88..c405b7f 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -395,7 +395,7 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) if (CABAC == ps_entropy->u1_entropy_coding_mode_flag) { BITSTREAM_BYTE_ALIGN(ps_bitstrm); - BITSTREAM_FLUSH(ps_bitstrm); + BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code); ih264e_init_cabac_ctxt(ps_entropy); } } @@ -515,7 +515,7 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) if (CABAC == ps_entropy->u1_entropy_coding_mode_flag) { BITSTREAM_BYTE_ALIGN(ps_bitstrm); - BITSTREAM_FLUSH(ps_bitstrm); + BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code); ih264e_init_cabac_ctxt(ps_entropy); } } From a073696092f26e5060af792b917738602d85686d Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Tue, 17 Nov 2020 06:44:57 +0530 Subject: [PATCH 2/2] 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 06c30b33c400afcf175916dea34f8b09599b58e5 Bug: 172908358 Test: Poc in bug Test: atest android.mediav2.cts Test: atest android.media.cts Change-Id: Icf3f296ab24432c680427a82da3505491acca3bd --- encoder/ih264e_api.c | 110 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 61ef6b5..53067e0 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -138,6 +138,101 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, /* 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: { + codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); ih264e_video_encode_ip_t *ps_ip = pv_api_ip; 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; 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; } @@ -4059,6 +4164,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, /* Update config params as per input */ 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); + + /* 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_ht_mbs = ps_cfg->u4_max_ht >> 4; ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;