diff --git a/test/resize_test.cc b/test/resize_test.cc index c5f05f31048eeaa2b9964d1c84494057b8917501..017730899b6b525f5682952720684a5538a0ac6b 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc @@ -90,74 +90,178 @@ struct FrameInfo { unsigned int h; }; -unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) { - if (frame < 10) - return val; - if (frame < 20) - return val * 3 / 4; - if (frame < 30) - return val / 2; - if (frame < 40) - return val; - if (frame < 50) - return val * 3 / 4; - if (frame < 60) - return val / 2; - if (frame < 70) - return val * 3 / 4; - if (frame < 80) - return val; - if (frame < 90) - return val * 3 / 4; - if (frame < 100) - return val / 2; - if (frame < 110) - return val * 3 / 4; - if (frame < 120) - return val; - if (frame < 130) - return val * 3 / 4; - if (frame < 140) - return val / 2; - if (frame < 150) - return val * 3 / 4; - if (frame < 160) - return val; - if (frame < 170) - return val / 2; - if (frame < 180) - return val * 3 / 4; - if (frame < 190) - return val; - if (frame < 200) - return val * 3 / 4; - if (frame < 210) - return val / 2; - if (frame < 220) - return val * 3 / 4; - if (frame < 230) - return val; - if (frame < 240) - return val / 2; - if (frame < 250) - return val * 3 / 4; - return val; +void ScaleForFrameNumber(unsigned int frame, + unsigned int initial_w, + unsigned int initial_h, + unsigned int *w, + unsigned int *h, + int flag_codec) { + if (frame < 10) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 20) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 30) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 40) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 50) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 60) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 70) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 80) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 90) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 100) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 110) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 120) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 130) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 140) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 150) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 160) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 170) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 180) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 190) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 200) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 210) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 220) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 230) { + *w = initial_w; + *h = initial_h; + return; + } + if (frame < 240) { + *w = initial_w * 3 / 4; + *h = initial_h * 3 / 4; + return; + } + if (frame < 250) { + *w = initial_w / 2; + *h = initial_h / 2; + return; + } + if (frame < 260) { + *w = initial_w; + *h = initial_h; + return; + } + // Go down very low. + if (frame < 270) { + *w = initial_w / 4; + *h = initial_h / 4; + return; + } + if (flag_codec == 1) { + // Cases that only works for VP9. + // For VP9: Swap width and height of original. + if (frame < 320) { + *w = initial_h; + *h = initial_w; + return; + } + } + *w = initial_w; + *h = initial_h; } class ResizingVideoSource : public ::libvpx_test::DummyVideoSource { public: ResizingVideoSource() { SetSize(kInitialWidth, kInitialHeight); - limit_ = 300; + limit_ = 350; } - + int flag_codec_; virtual ~ResizingVideoSource() {} protected: virtual void Next() { ++frame_; - SetSize(ScaleForFrameNumber(frame_, kInitialWidth), - ScaleForFrameNumber(frame_, kInitialHeight)); + unsigned int width; + unsigned int height; + ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height, + flag_codec_); + SetSize(width, height); FillFrame(); } }; @@ -184,15 +288,17 @@ class ResizeTest : public ::libvpx_test::EncoderTest, TEST_P(ResizeTest, TestExternalResizeWorks) { ResizingVideoSource video; + video.flag_codec_ = 0; cfg_.g_lag_in_frames = 0; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (std::vector::const_iterator info = frame_info_list_.begin(); info != frame_info_list_.end(); ++info) { const unsigned int frame = static_cast(info->pts); - const unsigned int expected_w = ScaleForFrameNumber(frame, kInitialWidth); - const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight); - + unsigned int expected_w; + unsigned int expected_h; + ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, + &expected_w, &expected_h, 0); EXPECT_EQ(expected_w, info->w) << "Frame " << frame << " had unexpected width"; EXPECT_EQ(expected_h, info->h) @@ -386,6 +492,7 @@ class ResizeRealtimeTest : public ::libvpx_test::EncoderTest, TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) { ResizingVideoSource video; + video.flag_codec_ = 1; DefaultConfig(); // Disable internal resize for this test. cfg_.rc_resize_allowed = 0; @@ -395,9 +502,10 @@ TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) { for (std::vector::const_iterator info = frame_info_list_.begin(); info != frame_info_list_.end(); ++info) { const unsigned int frame = static_cast(info->pts); - const unsigned int expected_w = ScaleForFrameNumber(frame, kInitialWidth); - const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight); - + unsigned int expected_w; + unsigned int expected_h; + ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, + &expected_w, &expected_h, 1); EXPECT_EQ(expected_w, info->w) << "Frame " << frame << " had unexpected width"; EXPECT_EQ(expected_h, info->h) diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index 24c6c54edd40dca33d4f96ffe1771ad7826eb71a..7dd1005d3febe8fe0c6fb3ba0a04f3a0e7514e34 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -119,6 +119,20 @@ void vp9_free_context_buffers(VP9_COMMON *cm) { cm->lf.lfm = NULL; } + +int vp9_alloc_loop_filter(VP9_COMMON *cm) { + vpx_free(cm->lf.lfm); + // Each lfm holds bit masks for all the 8x8 blocks in a 64x64 region. The + // stride and rows are rounded up / truncated to a multiple of 8. + cm->lf.lfm_stride = (cm->mi_cols + (MI_BLOCK_SIZE - 1)) >> 3; + cm->lf.lfm = (LOOP_FILTER_MASK *)vpx_calloc( + ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride, + sizeof(*cm->lf.lfm)); + if (!cm->lf.lfm) + return 1; + return 0; +} + int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { int new_mi_size; @@ -151,15 +165,8 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { cm->above_context_alloc_cols = cm->mi_cols; } - vpx_free(cm->lf.lfm); - - // Each lfm holds bit masks for all the 8x8 blocks in a 64x64 region. The - // stride and rows are rounded up / truncated to a multiple of 8. - cm->lf.lfm_stride = (cm->mi_cols + (MI_BLOCK_SIZE - 1)) >> 3; - cm->lf.lfm = (LOOP_FILTER_MASK *)vpx_calloc( - ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride, - sizeof(*cm->lf.lfm)); - if (!cm->lf.lfm) goto fail; + if (vp9_alloc_loop_filter(cm)) + goto fail; return 0; diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h index c0e51a6ce64082fbe0c5a640c77484cea760247e..e53955b99883d3683451b8d3ec62bab20160709d 100644 --- a/vp9/common/vp9_alloccommon.h +++ b/vp9/common/vp9_alloccommon.h @@ -23,6 +23,7 @@ struct BufferPool; void vp9_remove_common(struct VP9Common *cm); +int vp9_alloc_loop_filter(struct VP9Common *cm); int vp9_alloc_context_buffers(struct VP9Common *cm, int width, int height); void vp9_init_context_buffers(struct VP9Common *cm); void vp9_free_context_buffers(struct VP9Common *cm); diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index ff176fb9376e98cf6df233c225c3d76525fa710b..429a9cecd6579796729d31ddf3a6def73cc0496d 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -1538,8 +1538,12 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { realloc_segmentation_maps(cpi); cpi->initial_width = cpi->initial_height = 0; cpi->external_resize = 0; + } else if (cm->mi_alloc_size == new_mi_size && + (cpi->oxcf.width > last_w || cpi->oxcf.height > last_h)) { + vp9_alloc_loop_filter(cm); } } + update_frame_size(cpi); if ((last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) &&