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_;