Spatial resamping of ZEROMV predictors
This patch allows coding frames using references of different
resolution, in ZEROMV mode. For compound prediction, either
reference may be scaled.
To test, I use the resize_test and enable WRITE_RECON_BUFFER
in vp9_onyxd_if.c. It's also useful to apply this patch to
test/i420_video_source.h:
--- a/test/i420_video_source.h
+++ b/test/i420_video_source.h
@@ -93,6 +93,7 @@ class I420VideoSource : public VideoSource {
virtual void FillFrame() {
// Read a frame from input_file.
+ if (frame_ != 3)
if (fread(img_->img_data, raw_sz_, 1, input_file_) == 0) {
limit_ = frame_;
}
This forces the frame that the resolution changes on to be coded
with no motion, only scaling, and improves the quality of the
result.
Change-Id: I1ee75d19a437ff801192f767fd02a36bcbd1d496
diff --git a/vp9/common/vp9_convolve.c b/vp9/common/vp9_convolve.c
index ac5d5cb..f1b5915 100644
--- a/vp9/common/vp9_convolve.c
+++ b/vp9/common/vp9_convolve.c
@@ -206,16 +206,25 @@
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h, int taps) {
- /* Fixed size intermediate buffer places limits on parameters. */
- uint8_t temp[16 * 23];
+ /* Fixed size intermediate buffer places limits on parameters.
+ * Maximum intermediate_height is 39, for y_step_q4 == 32,
+ * h == 16, taps == 8.
+ */
+ uint8_t temp[16 * 39];
+ int intermediate_height = ((h * y_step_q4) >> 4) + taps - 1;
+
assert(w <= 16);
assert(h <= 16);
assert(taps <= 8);
+ assert(y_step_q4 <= 32);
+
+ if (intermediate_height < h)
+ intermediate_height = h;
convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride,
temp, 16,
filter_x, x_step_q4, filter_y, y_step_q4,
- w, h + taps - 1, taps);
+ w, intermediate_height, taps);
convolve_vert_c(temp + 16 * (taps / 2 - 1), 16, dst, dst_stride,
filter_x, x_step_q4, filter_y, y_step_q4,
w, h, taps);
@@ -226,16 +235,25 @@
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h, int taps) {
- /* Fixed size intermediate buffer places limits on parameters. */
- uint8_t temp[16 * 23];
+ /* Fixed size intermediate buffer places limits on parameters.
+ * Maximum intermediate_height is 39, for y_step_q4 == 32,
+ * h == 16, taps == 8.
+ */
+ uint8_t temp[16 * 39];
+ int intermediate_height = ((h * y_step_q4) >> 4) + taps - 1;
+
assert(w <= 16);
assert(h <= 16);
assert(taps <= 8);
+ assert(y_step_q4 <= 32);
+
+ if (intermediate_height < h)
+ intermediate_height = h;
convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride,
temp, 16,
filter_x, x_step_q4, filter_y, y_step_q4,
- w, h + taps - 1, taps);
+ w, intermediate_height, taps);
convolve_avg_vert_c(temp + 16 * (taps / 2 - 1), 16, dst, dst_stride,
filter_x, x_step_q4, filter_y, y_step_q4,
w, h, taps);