Add option to encoder to force max frame w/h Prior to this patch: when writing the sequence header at the start of each sequence, max_frame_width and max_frame_height were set from the dimensions of the current frame. This posed a problem for a resizing video source, where the dimensions of the frames could have increased within a sequence. This patch adds an option to the encoder to force the values of max_frame_width and max_frame_height. This feature is then used to fix the resize tests that otherwise caused errors. The number of frames tested (limit_) has been increased again to 350 after it was reduced in a previous patch to avoid the frames that were causing errors. BUG=aomedia:1431 Change-Id: Ic1d347a33ae8bf93c0ca5f631cfb1eeb09d25d30
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h index c32e515..67e718f 100644 --- a/aom/aom_encoder.h +++ b/aom/aom_encoder.h
@@ -282,6 +282,20 @@ */ unsigned int g_h; + /*!\brief Forced maximum width of the frame + * + * If this value is non-zero then it is used to force the maximum frame + * width written in write_sequence_header(). + */ + unsigned int g_forced_max_frame_width; + + /*!\brief Forced maximum height of the frame + * + * If this value is non-zero then it is used to force the maximum frame + * height written in write_sequence_header(). + */ + unsigned int g_forced_max_frame_height; + /*!\brief Bit-depth of the codec * * This value identifies the bit_depth of the codec,
diff --git a/aomenc.c b/aomenc.c index 2b1cdda..7e4aff4 100644 --- a/aomenc.c +++ b/aomenc.c
@@ -247,6 +247,12 @@ ARG_DEF(NULL, "profile", 1, "Bitstream profile number to use"); static const arg_def_t width = ARG_DEF("w", "width", 1, "Frame width"); static const arg_def_t height = ARG_DEF("h", "height", 1, "Frame height"); +#if CONFIG_FRAME_SIZE +static const arg_def_t forced_max_frame_width = ARG_DEF( + NULL, "forced_max_frame_width", 0, "Maximum frame width value to force"); +static const arg_def_t forced_max_frame_height = ARG_DEF( + NULL, "forced_max_frame_height", 0, "Maximum frame height value to force"); +#endif #if CONFIG_WEBM_IO static const struct arg_enum_list stereo_mode_enum[] = { { "mono", STEREO_FORMAT_MONO }, @@ -285,6 +291,10 @@ &profile, &width, &height, +#if CONFIG_FRAME_SIZE + &forced_max_frame_width, + &forced_max_frame_height, +#endif #if CONFIG_WEBM_IO &stereo_mode, #endif @@ -1215,6 +1225,12 @@ config->cfg.g_w = arg_parse_uint(&arg); } else if (arg_match(&arg, &height, argi)) { config->cfg.g_h = arg_parse_uint(&arg); +#if CONFIG_FRAME_SIZE + } else if (arg_match(&arg, &forced_max_frame_width, argi)) { + config->cfg.g_forced_max_frame_width = arg_parse_uint(&arg); + } else if (arg_match(&arg, &forced_max_frame_height, argi)) { + config->cfg.g_forced_max_frame_height = arg_parse_uint(&arg); +#endif } else if (arg_match(&arg, &bitdeptharg, argi)) { config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg); } else if (arg_match(&arg, &inbitdeptharg, argi)) {
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index 620b3f7..de7f8c7 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -512,6 +512,10 @@ oxcf->max_threads = (int)cfg->g_threads; oxcf->width = cfg->g_w; oxcf->height = cfg->g_h; +#if CONFIG_FRAME_SIZE + oxcf->forced_max_frame_width = cfg->g_forced_max_frame_width; + oxcf->forced_max_frame_height = cfg->g_forced_max_frame_height; +#endif oxcf->bit_depth = cfg->g_bit_depth; oxcf->input_bit_depth = cfg->g_input_bit_depth; // guess a frame rate if out of whack, use 30 @@ -1771,6 +1775,8 @@ 320, // g_width 240, // g_height + 0, // g_forced_max_frame_width + 0, // g_forced_max_frame_height AOM_BITS_8, // g_bit_depth 8, // g_input_bit_depth
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 64acf61..cad191d 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -2836,8 +2836,12 @@ #if CONFIG_FRAME_SIZE int num_bits_width = 16; int num_bits_height = 16; - int max_frame_width = cpi->oxcf.width; - int max_frame_height = cpi->oxcf.height; + int max_frame_width = cpi->oxcf.forced_max_frame_width + ? cpi->oxcf.forced_max_frame_width + : cpi->oxcf.width; + int max_frame_height = cpi->oxcf.forced_max_frame_height + ? cpi->oxcf.forced_max_frame_height + : cpi->oxcf.height; seq_params->num_bits_width = num_bits_width; seq_params->num_bits_height = num_bits_height;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 91a30fb..5bc7675 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -136,9 +136,13 @@ typedef struct AV1EncoderConfig { BITSTREAM_PROFILE profile; - aom_bit_depth_t bit_depth; // Codec bit-depth. - int width; // width of data passed to the compressor - int height; // height of data passed to the compressor + aom_bit_depth_t bit_depth; // Codec bit-depth. + int width; // width of data passed to the compressor + int height; // height of data passed to the compressor +#if CONFIG_FRAME_SIZE + int forced_max_frame_width; // forced maximum width of frame (if != 0) + int forced_max_frame_height; // forced maximum height of frame (if != 0) +#endif unsigned int input_bit_depth; // Input bit depth. double init_framerate; // set to passed in framerate int64_t target_bandwidth; // bandwidth to be used in bits per second
diff --git a/test/resize_test.cc b/test/resize_test.cc index 5fc6fe0..534025d 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc
@@ -11,6 +11,7 @@ #include <climits> #include <vector> +#include "aom_dsp/aom_dsp_common.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" #include "test/encode_test_driver.h" @@ -247,7 +248,7 @@ public: ResizingVideoSource() { SetSize(kInitialWidth, kInitialHeight); - limit_ = 250; + limit_ = 350; } int flag_codec_; virtual ~ResizingVideoSource() {} @@ -289,6 +290,10 @@ ResizingVideoSource video; video.flag_codec_ = 0; cfg_.g_lag_in_frames = 0; + // We use max(kInitialWidth, kInitialHeight) because during the test + // the width and height of the frame are swapped + cfg_.g_forced_max_frame_width = cfg_.g_forced_max_frame_height = + AOMMAX(kInitialWidth, kInitialHeight); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // Check we decoded the same number of frames as we attempted to encode @@ -490,6 +495,10 @@ cfg_.g_error_resilient = 0; // Run at low bitrate. cfg_.rc_target_bitrate = 200; + // We use max(kInitialWidth, kInitialHeight) because during the test + // the width and height of the frame are swapped + cfg_.g_forced_max_frame_width = cfg_.g_forced_max_frame_height = + AOMMAX(kInitialWidth, kInitialHeight); } std::vector<FrameInfo> frame_info_list_;