Merge "VP9 motion vector unit test"

This commit is contained in:
Yunqing Wang 2017-04-07 16:46:22 +00:00 committed by Gerrit Code Review
commit f496032686
11 changed files with 229 additions and 2 deletions

View File

@ -23,6 +23,7 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += noisy_clip_640_360.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
# Test vectors
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
@ -814,7 +815,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += kirland_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcomoving_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv

View File

@ -48,6 +48,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/yuv_video_source.h"
namespace {
#define MAX_EXTREME_MV 1
#define MIN_EXTREME_MV 2
// Encoding modes
const libvpx_test::TestMode kEncodingModeVectors[] = {
::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime,
};
// Encoding speeds
const int kCpuUsedVectors[] = { 0, 1, 2, 3, 4, 5, 6 };
// MV test modes: 1 - always use maximum MV; 2 - always use minimum MV.
const int kMVTestModes[] = { MAX_EXTREME_MV, MIN_EXTREME_MV };
class MotionVectorTestLarge
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, int,
int> {
protected:
MotionVectorTestLarge()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
cpu_used_(GET_PARAM(2)), mv_test_mode_(GET_PARAM(3)) {}
virtual ~MotionVectorTestLarge() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
cfg_.g_lag_in_frames = 3;
cfg_.rc_end_usage = VPX_VBR;
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
}
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, mv_test_mode_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
}
}
}
libvpx_test::TestMode encoding_mode_;
int cpu_used_;
int mv_test_mode_;
};
TEST_P(MotionVectorTestLarge, OverallTest) {
cfg_.rc_target_bitrate = 24000;
cfg_.g_profile = 0;
init_flags_ = VPX_CODEC_USE_PSNR;
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
video.reset(new libvpx_test::YUVVideoSource(
"niklas_640_480_30.yuv", VPX_IMG_FMT_I420, 3840, 2160, // 2048, 1080,
30, 1, 0, 5));
ASSERT_TRUE(video.get() != NULL);
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
}
VP9_INSTANTIATE_TEST_CASE(MotionVectorTestLarge,
::testing::ValuesIn(kEncodingModeVectors),
::testing::ValuesIn(kCpuUsedVectors),
::testing::ValuesIn(kMVTestModes));
} // namespace

View File

@ -34,7 +34,7 @@ static void print_mi_data(VP9_COMMON *cm, FILE *file, const char *descriptor,
for (mi_row = 0; mi_row < rows; mi_row++) {
fprintf(file, "%c ", prefix);
for (mi_col = 0; mi_col < cols; mi_col++) {
fprintf(file, "%2d ", *((int *)((char *)(mi[0]) + member_offset)));
fprintf(file, "%2d ", *((char *)((char *)(mi[0]) + member_offset)));
mi++;
}
fprintf(file, "\n");

View File

@ -269,6 +269,7 @@ typedef struct VP9EncoderConfig {
int row_mt;
unsigned int row_mt_bit_exact;
unsigned int motion_vector_unit_test;
} VP9EncoderConfig;
static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) {

View File

@ -21,6 +21,7 @@
#include "vpx_ports/mem.h"
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/encoder/vp9_encoder.h"
@ -2477,3 +2478,85 @@ int vp9_full_pixel_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
return var;
}
// Note(yunqingwang): The following 2 functions are only used in the motion
// vector unit test, which return extreme motion vectors allowed by the MV
// limits.
#define COMMON_MV_TEST \
SETUP_SUBPEL_SEARCH; \
\
(void)error_per_bit; \
(void)vfp; \
(void)z; \
(void)src_stride; \
(void)y; \
(void)y_stride; \
(void)second_pred; \
(void)w; \
(void)h; \
(void)offset; \
(void)mvjcost; \
(void)mvcost; \
(void)sse1; \
(void)distortion; \
\
(void)halfiters; \
(void)quarteriters; \
(void)eighthiters; \
(void)whichdir; \
(void)allow_hp; \
(void)forced_stop; \
(void)hstep; \
(void)rr; \
(void)rc; \
\
(void)tr; \
(void)tc; \
(void)sse; \
(void)thismse; \
(void)cost_list;
// Return the maximum MV.
uint32_t vp9_return_max_sub_pixel_mv(
const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp,
int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop,
int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2],
uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w,
int h) {
COMMON_MV_TEST;
(void)minr;
(void)minc;
bestmv->row = maxr;
bestmv->col = maxc;
besterr = 0;
// In the sub-pel motion search, if hp is not used, then the last bit of mv
// has to be 0.
lower_mv_precision(bestmv, allow_hp && use_mv_hp(ref_mv));
return besterr;
}
// Return the minimum MV.
uint32_t vp9_return_min_sub_pixel_mv(
const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp,
int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop,
int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2],
uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w,
int h) {
COMMON_MV_TEST;
(void)maxr;
(void)maxc;
bestmv->row = minr;
bestmv->col = minc;
besterr = 0;
// In the sub-pel motion search, if hp is not used, then the last bit of mv
// has to be 0.
lower_mv_precision(bestmv, allow_hp && use_mv_hp(ref_mv));
return besterr;
}

View File

@ -81,6 +81,8 @@ extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned;
extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned_more;
extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned_evenmore;
extern fractional_mv_step_fp vp9_skip_sub_pixel_tree;
extern fractional_mv_step_fp vp9_return_max_sub_pixel_mv;
extern fractional_mv_step_fp vp9_return_min_sub_pixel_mv;
typedef int (*vp9_full_search_fn_t)(const MACROBLOCK *x, const MV *ref_mv,
int sad_per_bit, int distance,

View File

@ -3241,6 +3241,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data,
if (best_rd < mode_threshold[mode_index]) continue;
// This is only used in motion vector unit test.
if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
if (sf->motion_field_mode_search) {
const int mi_width = VPXMIN(num_8x8_blocks_wide_lookup[bsize],
tile_info->mi_col_end - mi_col);
@ -3924,6 +3927,9 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, TileDataEnc *tile_data,
&rd_thresh_freq_fact[ref_index]))
continue;
// This is only used in motion vector unit test.
if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
if (!cpi->allow_comp_inter_inter) continue;

View File

@ -609,6 +609,12 @@ void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) {
sf->allow_exhaustive_searches = 0;
sf->adaptive_pred_interp_filter = 0;
}
// This is only used in motion vector unit test.
if (cpi->oxcf.motion_vector_unit_test == 1)
cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv;
else if (cpi->oxcf.motion_vector_unit_test == 2)
cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv;
}
void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
@ -779,4 +785,10 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
sf->allow_exhaustive_searches = 0;
sf->adaptive_pred_interp_filter = 0;
}
// This is only used in motion vector unit test.
if (cpi->oxcf.motion_vector_unit_test == 1)
cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv;
else if (cpi->oxcf.motion_vector_unit_test == 2)
cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv;
}

View File

@ -53,6 +53,7 @@ struct vp9_extracfg {
int render_height;
unsigned int row_mt;
unsigned int row_mt_bit_exact;
unsigned int motion_vector_unit_test;
};
static struct vp9_extracfg default_extra_cfg = {
@ -86,6 +87,7 @@ static struct vp9_extracfg default_extra_cfg = {
0, // render height
0, // row_mt
0, // row_mt_bit_exact
0, // motion_vector_unit_test
};
struct vpx_codec_alg_priv {
@ -251,6 +253,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK(extra_cfg, row_mt, 0, 1);
RANGE_CHECK(extra_cfg, row_mt_bit_exact, 0, 1);
RANGE_CHECK(extra_cfg, motion_vector_unit_test, 0, 2);
RANGE_CHECK(extra_cfg, enable_auto_alt_ref, 0, 2);
RANGE_CHECK(extra_cfg, cpu_used, -8, 8);
RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
@ -562,6 +565,7 @@ static vpx_codec_err_t set_encoder_config(
oxcf->row_mt = extra_cfg->row_mt;
oxcf->row_mt_bit_exact = extra_cfg->row_mt_bit_exact;
oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
#if CONFIG_SPATIAL_SVC
@ -865,6 +869,14 @@ static vpx_codec_err_t ctrl_enable_row_mt_bit_exact(vpx_codec_alg_priv_t *ctx,
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_err_t ctrl_enable_motion_vector_unit_test(
vpx_codec_alg_priv_t *ctx, va_list args) {
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.motion_vector_unit_test =
CAST(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_err_t ctrl_get_level(vpx_codec_alg_priv_t *ctx, va_list args) {
int *const arg = va_arg(args, int *);
if (arg == NULL) return VPX_CODEC_INVALID_PARAM;
@ -1622,6 +1634,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP9E_SET_TARGET_LEVEL, ctrl_set_target_level },
{ VP9E_SET_ROW_MT, ctrl_set_row_mt },
{ VP9E_ENABLE_ROW_MT_BIT_EXACT, ctrl_enable_row_mt_bit_exact },
{ VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
// Getters
{ VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },

View File

@ -594,6 +594,15 @@ enum vp8e_enc_control_id {
* Supported in codecs: VP8
*/
VP8E_SET_GF_CBR_BOOST_PCT,
/*!\brief Codec control function to enable the extreme motion vector unit test
* in VP9. Please note that this is only used in motion vector unit test.
*
* 0 : off, 1 : MAX_EXTREME_MV, 2 : MIN_EXTREME_MV
*
* Supported in codecs: VP9
*/
VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST,
};
/*!\brief vpx 1-D scaling mode
@ -864,6 +873,9 @@ VPX_CTRL_USE_TYPE(VP9E_ENABLE_ROW_MT_BIT_EXACT, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_GET_LEVEL, int *)
#define VPX_CTRL_VP9E_GET_LEVEL
VPX_CTRL_USE_TYPE(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
#define VPX_CTRL_VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST
/*!\endcond */
/*! @} - end defgroup vp8_encoder */
#ifdef __cplusplus