Skip to content

Commit 090dd8b

Browse files
committed
vp9: Add check to validate source input
Return invalid_params. The check is wrapped around a new control: VP9E_SET_VALIDATE_INPUT_HBD, and is enabled by default. Check is done only CONFIG_VP9_HIGHBITDEPTH build and for bitdepth > 8. Bug: 488585490 Change-Id: Ic79dff1bd314d4b197087d3c46d315ece8fd355c
1 parent 3fce57e commit 090dd8b

3 files changed

Lines changed: 59 additions & 2 deletions

File tree

test/encode_api_test.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,7 +2533,11 @@ TEST(EncodeAPI, Buganizer487259772ScaledRefs) {
25332533
encoder.Encode(/*key_frame=*/false, &rng);
25342534
}
25352535

2536-
TEST(EncodeAPI, DISABLED_Buganizer488585490CostTableOverflow) {
2536+
#if CONFIG_VP9_HIGHBITDEPTH
2537+
// This test uses source input based on the issue: 488585490,
2538+
// which is invalid for 10 bit. This test checks that the
2539+
// encoder correctly returns VPX_CODEC_INVALID_PARAM.
2540+
TEST(EncodeAPI, Buganizer488585490CostTableOverflow) {
25372541
// Initialize libvpx encoder.
25382542
vpx_codec_iface_t *const iface = vpx_codec_vp9_cx();
25392543
vpx_codec_ctx_t enc;
@@ -2562,10 +2566,12 @@ TEST(EncodeAPI, DISABLED_Buganizer488585490CostTableOverflow) {
25622566
video.Begin();
25632567
ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), /*duration=*/66666,
25642568
/*flags=*/0, VPX_DL_REALTIME),
2565-
VPX_CODEC_OK);
2569+
VPX_CODEC_INVALID_PARAM);
25662570

25672571
ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
25682572
}
2573+
#endif
2574+
25692575
#endif // CONFIG_VP9_ENCODER
25702576

25712577
} // namespace

vp9/vp9_cx_iface.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef struct vp9_extracfg {
7272
unsigned int row_mt;
7373
unsigned int motion_vector_unit_test;
7474
int delta_q_uv;
75+
unsigned int validate_input_hbd;
7576
} vp9_extracfg;
7677

7778
static struct vp9_extracfg default_extra_cfg = {
@@ -112,6 +113,7 @@ static struct vp9_extracfg default_extra_cfg = {
112113
0, // row_mt
113114
0, // motion_vector_unit_test
114115
0, // delta_q_uv
116+
1, // validate_input_hbd
115117
};
116118

117119
struct vpx_codec_alg_priv {
@@ -984,6 +986,12 @@ static vpx_codec_err_t ctrl_set_keyframe_filtering(vpx_codec_alg_priv_t *ctx,
984986
return update_extra_cfg(ctx, &extra_cfg);
985987
}
986988

989+
static vpx_codec_err_t ctrl_set_validate_input_hbd(vpx_codec_alg_priv_t *ctx,
990+
va_list args) {
991+
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
992+
extra_cfg.validate_input_hbd = CAST(VP9E_SET_VALIDATE_INPUT_HBD, args);
993+
return update_extra_cfg(ctx, &extra_cfg);
994+
}
987995
static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx,
988996
va_list args) {
989997
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
@@ -1452,6 +1460,36 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx,
14521460
if (img != NULL) {
14531461
YV12_BUFFER_CONFIG sd;
14541462

1463+
#if CONFIG_VP9_HIGHBITDEPTH
1464+
if (ctx->extra_cfg.validate_input_hbd &&
1465+
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) &&
1466+
ctx->oxcf.input_bit_depth > 8) {
1467+
const unsigned int h = img->d_h;
1468+
const unsigned int w = img->d_w;
1469+
const unsigned int bit_depth = ctx->oxcf.input_bit_depth;
1470+
const int max_val = 1 << bit_depth;
1471+
for (int plane = 0; plane < 3; ++plane) {
1472+
const unsigned short *src =
1473+
(const unsigned short *)img->planes[plane];
1474+
const unsigned int stride = img->stride[plane] / 2;
1475+
const unsigned int ph =
1476+
(plane == 0) ? h
1477+
: (h + img->y_chroma_shift) >> img->y_chroma_shift;
1478+
const unsigned int pw =
1479+
(plane == 0) ? w
1480+
: (w + img->x_chroma_shift) >> img->x_chroma_shift;
1481+
for (unsigned int i = 0; i < ph; ++i) {
1482+
for (unsigned int j = 0; j < pw; ++j) {
1483+
if (src[j] >= max_val) {
1484+
return VPX_CODEC_INVALID_PARAM;
1485+
}
1486+
}
1487+
src += stride;
1488+
}
1489+
}
1490+
}
1491+
#endif // CONFIG_VP9_HIGHBITDEPTH
1492+
14551493
if (!ctx->pts_offset_initialized) {
14561494
ctx->pts_offset = pts;
14571495
ctx->pts_offset_initialized = 1;
@@ -2158,6 +2196,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
21582196
{ VP9E_SET_TILE_ROWS, ctrl_set_tile_rows },
21592197
{ VP9E_SET_TPL, ctrl_set_tpl_model },
21602198
{ VP9E_SET_KEY_FRAME_FILTERING, ctrl_set_keyframe_filtering },
2199+
{ VP9E_SET_VALIDATE_INPUT_HBD, ctrl_set_validate_input_hbd },
21612200
{ VP8E_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
21622201
{ VP8E_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
21632202
{ VP8E_SET_ARNR_TYPE, ctrl_set_arnr_type },

vpx/vp8cx.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,16 @@ enum vp8e_enc_control_id {
776776
* 1. The default value is set to be 0.
777777
*/
778778
VP9E_SET_KEY_FRAME_FILTERING,
779+
780+
/*!\brief Codec control function to validate HBD input.
781+
*
782+
* VP9 allows the encoder to validate the high bitdepth (HBD) input and
783+
* ensure that every pixel is within the valid range. To disable/enable,
784+
* set this parameter to 0/1. The default value is set to be 1.
785+
*
786+
* Supported in codecs: VP9
787+
*/
788+
VP9E_SET_VALIDATE_INPUT_HBD,
779789
};
780790

781791
/*!\brief vpx 1-D scaling mode
@@ -1108,6 +1118,8 @@ VPX_CTRL_USE_TYPE(VP9E_SET_QUANTIZER_ONE_PASS, int)
11081118
#define VPX_CTRL_VP9E_SET_QUANTIZER_ONE_PASS
11091119
VPX_CTRL_USE_TYPE(VP9E_SET_KEY_FRAME_FILTERING, int)
11101120
#define VPX_CTRL_VP9E_SET_KEY_FRAME_FILTERING
1121+
VPX_CTRL_USE_TYPE(VP9E_SET_VALIDATE_INPUT_HBD, int)
1122+
#define VPX_CTRL_VP9E_SET_VALIDATE_INPUT_HBD
11111123

11121124
/*!\endcond */
11131125
/*! @} - end defgroup vp8_encoder */

0 commit comments

Comments
 (0)