update libaom to rev 5bdd95475e07ac8641114cb139105b8d734a1b60 (without moz.build and aom_ports/aom_once.h)

This commit is contained in:
Roy Tam 2019-03-29 21:53:07 +08:00
commit fb515ea77b
177 changed files with 21088 additions and 11681 deletions

View file

@ -288,6 +288,68 @@ void AV1FwdTxfm2dMatchTest(TX_SIZE tx_size, lowbd_fwd_txfm_func target_func) {
}
}
void AV1FwdTxfm2dSpeedTest(TX_SIZE tx_size, lowbd_fwd_txfm_func target_func) {
TxfmParam param;
memset(&param, 0, sizeof(param));
const int rows = tx_size_high[tx_size];
const int cols = tx_size_wide[tx_size];
const int num_loops = 1000000 / (rows * cols);
for (int i = 0; i < 2; ++i) {
const int bd = 8;
for (int tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
if (libaom_test::IsTxSizeTypeValid(
tx_size, static_cast<TX_TYPE>(tx_type)) == false) {
continue;
}
FwdTxfm2dFunc ref_func = libaom_test::fwd_txfm_func_ls[tx_size];
if (ref_func != NULL) {
DECLARE_ALIGNED(32, int16_t, input[64 * 64]) = { 0 };
DECLARE_ALIGNED(32, int32_t, output[64 * 64]);
DECLARE_ALIGNED(32, int32_t, ref_output[64 * 64]);
int input_stride = 64;
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
input[r * input_stride + c] = rnd.Rand16() % (1 << bd);
}
}
param.tx_type = (TX_TYPE)tx_type;
param.tx_size = (TX_SIZE)tx_size;
param.tx_set_type = EXT_TX_SET_ALL16;
param.bd = bd;
aom_usec_timer ref_timer, test_timer;
aom_usec_timer_start(&ref_timer);
for (int i = 0; i < num_loops; ++i) {
ref_func(input, ref_output, input_stride, (TX_TYPE)tx_type, bd);
}
aom_usec_timer_mark(&ref_timer);
const int elapsed_time_c =
static_cast<int>(aom_usec_timer_elapsed(&ref_timer));
aom_usec_timer_start(&test_timer);
for (int i = 0; i < num_loops; ++i) {
target_func(input, output, input_stride, &param);
}
aom_usec_timer_mark(&test_timer);
const int elapsed_time_simd =
static_cast<int>(aom_usec_timer_elapsed(&test_timer));
printf(
"txfm_size[%d] \t txfm_type[%d] \t c_time=%d \t simd_time=%d \t "
"gain=%d \n",
tx_size, tx_type, elapsed_time_c, elapsed_time_simd,
(elapsed_time_c / elapsed_time_simd));
}
}
}
}
typedef ::testing::tuple<TX_SIZE, lowbd_fwd_txfm_func> LbdFwdTxfm2dParam;
class AV1FwdTxfm2dTest : public ::testing::TestWithParam<LbdFwdTxfm2dParam> {};
@ -295,7 +357,9 @@ class AV1FwdTxfm2dTest : public ::testing::TestWithParam<LbdFwdTxfm2dParam> {};
TEST_P(AV1FwdTxfm2dTest, match) {
AV1FwdTxfm2dMatchTest(GET_PARAM(0), GET_PARAM(1));
}
TEST_P(AV1FwdTxfm2dTest, DISABLED_Speed) {
AV1FwdTxfm2dSpeedTest(GET_PARAM(0), GET_PARAM(1));
}
using ::testing::Combine;
using ::testing::Values;
using ::testing::ValuesIn;

View file

@ -308,7 +308,8 @@ INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdInvTxfm2d,
::testing::Values(av1_highbd_inv_txfm_add_sse4_1));
#endif
#if HAVE_AVX2
// TODO(http://crbug.com/aomedia/2350): these cause test vector mismatches.
#if 0 // HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdInvTxfm2d,
::testing::Values(av1_highbd_inv_txfm_add_avx2));
#endif

View file

@ -59,7 +59,9 @@ typedef void (*Z1_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
template <Z1_Lbd fn>
void z1_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left, int upsample_above,
int /*upsample_left*/, int dx, int dy, int /*bd*/) {
int upsample_left, int dx, int dy, int bd) {
(void)bd;
(void)upsample_left;
fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy);
}
@ -69,7 +71,9 @@ typedef void (*Z2_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
template <Z2_Lbd fn>
void z2_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left, int upsample_above,
int upsample_left, int dx, int dy, int /*bd*/) {
int upsample_left, int dx, int dy, int bd) {
(void)bd;
(void)upsample_left;
fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy);
}
@ -78,9 +82,10 @@ typedef void (*Z3_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
int upsample_left, int dx, int dy);
template <Z3_Lbd fn>
void z3_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left,
int /*upsample_above*/, int upsample_left, int dx, int dy,
int /*bd*/) {
const uint8_t *above, const uint8_t *left, int upsample_above,
int upsample_left, int dx, int dy, int bd) {
(void)bd;
(void)upsample_above;
fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy);
}
@ -90,8 +95,10 @@ typedef void (*Z1_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
template <Z1_Hbd fn>
void z1_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
const uint16_t *above, const uint16_t *left,
int upsample_above, int /*upsample_left*/, int dx, int dy,
int upsample_above, int upsample_left, int dx, int dy,
int bd) {
(void)bd;
(void)upsample_left;
fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy, bd);
}
@ -104,6 +111,7 @@ void z2_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
const uint16_t *above, const uint16_t *left,
int upsample_above, int upsample_left, int dx, int dy,
int bd) {
(void)bd;
fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy,
bd);
}
@ -114,8 +122,10 @@ typedef void (*Z3_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
template <Z3_Hbd fn>
void z3_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
const uint16_t *above, const uint16_t *left,
int /*upsample_above*/, int upsample_left, int dx, int dy,
int upsample_above, int upsample_left, int dx, int dy,
int bd) {
(void)bd;
(void)upsample_above;
fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy, bd);
}
@ -172,6 +182,9 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > {
const int kNumTests = speedtest ? kMaxNumTests : 1;
aom_usec_timer timer;
int tst_time = 0;
bd_ = params_.bit_depth;
aom_usec_timer_start(&timer);
for (int k = 0; k < kNumTests; ++k) {
params_.ref_fn(dst_ref_, dst_stride_, bw_, bh_, above_, left_,
@ -199,6 +212,8 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > {
}
void RunTest(bool speedtest, bool needsaturation, int p_angle) {
bd_ = params_.bit_depth;
if (needsaturation) {
for (int i = 0; i < kBufSize; ++i) {
above_data_[i] = left_data_[i] = (1 << bd_) - 1;
@ -350,9 +365,11 @@ INSTANTIATE_TEST_CASE_P(
::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
&z1_wrapper<av1_dr_prediction_z1_avx2>,
AOM_BITS_8, kZ1Start),
/* TODO(niva213@gmail.com): Re-enable this test after
fixing valgrind issue: https://crbug.com/aomedia/2316
DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>,
&z2_wrapper<av1_dr_prediction_z2_avx2>,
AOM_BITS_8, kZ2Start),
AOM_BITS_8, kZ2Start), */
DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
&z3_wrapper<av1_dr_prediction_z3_avx2>,
AOM_BITS_8, kZ3Start)));
@ -397,7 +414,8 @@ INSTANTIATE_TEST_CASE_P(
&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>,
AOM_BITS_12, kZ1Start),
/* TODO(https://crbug.com/aomedia/2288)
/* TODO(niva213@gmail.com): Re-enable these tests after
fixing valgrind issue: https://crbug.com/aomedia/2316
DrPredFunc<DrPred_Hbd>(
&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>,
@ -409,8 +427,7 @@ INSTANTIATE_TEST_CASE_P(
DrPredFunc<DrPred_Hbd>(
&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>,
AOM_BITS_12, kZ2Start),
*/
AOM_BITS_12, kZ2Start),*/
DrPredFunc<DrPred_Hbd>(
&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>,

View file

@ -185,8 +185,9 @@ TEST_P(EdgeDetectBrightnessTest, DetectUniformBrightness) {
const bool high_bd = GET_PARAM(3);
const int bd = GET_PARAM(4);
ASSERT_EQ(0, av1_edge_exists(input_, stride_8tap(width), width, height,
high_bd, bd));
ASSERT_EQ(
0, av1_edge_exists(input_, stride_8tap(width), width, height, high_bd, bd)
.magnitude);
}
INSTANTIATE_TEST_CASE_P(ImageBrightnessTests, EdgeDetectBrightnessTest,
@ -245,9 +246,11 @@ TEST_P(EdgeDetectImageTest, BlackWhite) {
free(orig);
// Value should be between 556 and 560.
ASSERT_LE(556, av1_edge_exists(padded, stride_8tap(width), width, height,
high_bd, bd));
high_bd, bd)
.magnitude);
ASSERT_GE(560, av1_edge_exists(padded, stride_8tap(width), width, height,
high_bd, bd));
high_bd, bd)
.magnitude);
free_pad_8tap(padded, width, high_bd);
}

View file

@ -50,7 +50,7 @@ TEST(EncodeAPI, InvalidParams) {
EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
aom_codec_enc_init(&enc, kCodecs[i], NULL, 0));
EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
aom_codec_enc_config_default(kCodecs[i], &cfg, 1));
aom_codec_enc_config_default(kCodecs[i], &cfg, 2));
EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(kCodecs[i], &cfg, 0));
EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, kCodecs[i], &cfg, 0));

View file

@ -156,6 +156,70 @@ TEST_P(ErrorBlockTest, ExtremeValues) {
<< "First failed at test case " << first_failure;
}
TEST_P(ErrorBlockTest, DISABLED_Speed) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
intptr_t block_size;
int64_t ssz;
int num_iters = 100000;
int64_t ref_ssz;
int k;
const int msb = bit_depth_ + 8 - 1;
for (int i = 0; i < 9; ++i) {
block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64
for (k = 0; k < 9; k++) {
for (int j = 0; j < block_size; j++) {
if (k < 5) {
if (rnd(2)) {
// Positive number
coeff[j] = rnd(1 << msb);
dqcoeff[j] = rnd(1 << msb);
} else {
// Negative number
coeff[j] = -rnd(1 << msb);
dqcoeff[j] = -rnd(1 << msb);
}
} else {
if (rnd(2)) {
// Positive number
coeff[j] = rnd(1 << 14);
dqcoeff[j] = rnd(1 << 14);
} else {
// Negative number
coeff[j] = -rnd(1 << 14);
dqcoeff[j] = -rnd(1 << 14);
}
}
}
aom_usec_timer ref_timer, test_timer;
aom_usec_timer_start(&ref_timer);
for (int i = 0; i < num_iters; ++i) {
ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_);
}
aom_usec_timer_mark(&ref_timer);
const int elapsed_time_c =
static_cast<int>(aom_usec_timer_elapsed(&ref_timer));
aom_usec_timer_start(&test_timer);
for (int i = 0; i < num_iters; ++i) {
error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_);
}
aom_usec_timer_mark(&test_timer);
const int elapsed_time_simd =
static_cast<int>(aom_usec_timer_elapsed(&test_timer));
printf(
" c_time=%d \t simd_time=%d \t "
"gain=%d \n",
elapsed_time_c, elapsed_time_simd,
(elapsed_time_c / elapsed_time_simd));
}
}
}
#if (HAVE_SSE2 || HAVE_AVX)
using ::testing::make_tuple;
@ -168,4 +232,17 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&av1_highbd_block_error_sse2,
&av1_highbd_block_error_c, AOM_BITS_8)));
#endif // HAVE_SSE2
#if (HAVE_AVX2)
using ::testing::make_tuple;
INSTANTIATE_TEST_CASE_P(
AVX2, ErrorBlockTest,
::testing::Values(make_tuple(&av1_highbd_block_error_avx2,
&av1_highbd_block_error_c, AOM_BITS_10),
make_tuple(&av1_highbd_block_error_avx2,
&av1_highbd_block_error_c, AOM_BITS_12),
make_tuple(&av1_highbd_block_error_avx2,
&av1_highbd_block_error_c, AOM_BITS_8)));
#endif // HAVE_AVX2
} // namespace

110
third_party/aom/test/fwd_kf_test.cc vendored Normal file
View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {
typedef struct {
const int max_kf_dist;
const double psnr_thresh;
} FwdKfTestParam;
const FwdKfTestParam kTestParams[] = {
{ 4, 37.3 }, { 6, 36.5 }, { 8, 35.8 },
{ 12, 34.3 }, { 16, 34.3 }, { 18, 33.7 }
};
// Params: encoding mode and index into the kMaxKfDists array to control
// kf-max-dist
class ForwardKeyTest
: public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
public ::libaom_test::EncoderTest {
protected:
ForwardKeyTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
kf_max_dist_ind_(GET_PARAM(2)) {}
virtual ~ForwardKeyTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
const aom_rational timebase = { 1, 30 };
cfg_.g_timebase = timebase;
cpu_used_ = 2;
kf_max_dist_ = kTestParams[kf_max_dist_ind_].max_kf_dist;
psnr_threshold_ = kTestParams[kf_max_dist_ind_].psnr_thresh;
cfg_.rc_end_usage = AOM_VBR;
cfg_.rc_target_bitrate = 200;
cfg_.g_lag_in_frames = 10;
cfg_.fwd_kf_enabled = 1;
cfg_.kf_max_dist = kf_max_dist_;
cfg_.g_threads = 0;
init_flags_ = AOM_CODEC_USE_PSNR;
}
virtual void BeginPassHook(unsigned int) {
psnr_ = 0.0;
nframes_ = 0;
}
virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
psnr_ += pkt->data.psnr.psnr[0];
nframes_++;
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, cpu_used_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
}
}
}
double GetAveragePsnr() const {
if (nframes_) return psnr_ / nframes_;
return 0.0;
}
double GetPsnrThreshold() { return psnr_threshold_; }
::libaom_test::TestMode encoding_mode_;
const int kf_max_dist_ind_;
double psnr_threshold_;
int kf_max_dist_;
int cpu_used_;
int nframes_;
double psnr_;
};
TEST_P(ForwardKeyTest, ForwardKeyEncodeTest) {
libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
cfg_.g_timebase.den, cfg_.g_timebase.num,
0, 20);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// TODO(sarahparker) Add functionality to assert the minimum number of
// keyframes were placed.
EXPECT_GT(GetAveragePsnr(), GetPsnrThreshold())
<< "kf max dist = " << kf_max_dist_;
}
AV1_INSTANTIATE_TEST_CASE(
ForwardKeyTest, ::testing::Values(::libaom_test::kTwoPassGood),
::testing::Range(0, static_cast<int>(GTEST_ARRAY_SIZE_(kTestParams))));
} // namespace

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {
static const struct GFMaxPyrHeightTestParam {
int gf_max_pyr_height;
double psnr_thresh;
} kTestParams[] = {
{ 0, 34.75 }, { 1, 34.75 }, { 2, 35.25 }, { 3, 35.50 }, { 4, 35.50 },
};
// Compiler may decide to add some padding to the struct above for alignment,
// which the gtest may try to print (on error for example). This would cause
// valgrind to complain that the padding is uninitialized. To avoid that, we
// provide our own function to print the struct.
// This also makes '--gtest_list_tests' output more understandable.
std::ostream &operator<<(std::ostream &os, const GFMaxPyrHeightTestParam &p) {
os << "GFMaxPyrHeightTestParam { "
<< "gf_max_pyr_height = " << p.gf_max_pyr_height << ", "
<< "psnr_thresh = " << p.psnr_thresh << " }";
return os;
}
// Params: encoding mode and GFMaxPyrHeightTestParam object.
class GFMaxPyrHeightTest
: public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode,
GFMaxPyrHeightTestParam>,
public ::libaom_test::EncoderTest {
protected:
GFMaxPyrHeightTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
gf_max_pyr_height_ = GET_PARAM(2).gf_max_pyr_height;
psnr_threshold_ = GET_PARAM(2).psnr_thresh;
}
virtual ~GFMaxPyrHeightTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
const aom_rational timebase = { 1, 30 };
cfg_.g_timebase = timebase;
cpu_used_ = 4;
cfg_.rc_end_usage = AOM_VBR;
cfg_.rc_target_bitrate = 200;
cfg_.g_lag_in_frames = 19;
cfg_.g_threads = 0;
init_flags_ = AOM_CODEC_USE_PSNR;
}
virtual void BeginPassHook(unsigned int) {
psnr_ = 0.0;
nframes_ = 0;
}
virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
psnr_ += pkt->data.psnr.psnr[0];
nframes_++;
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, cpu_used_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
}
encoder->Control(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, gf_max_pyr_height_);
}
}
double GetAveragePsnr() const {
if (nframes_) return psnr_ / nframes_;
return 0.0;
}
double GetPsnrThreshold() { return psnr_threshold_; }
::libaom_test::TestMode encoding_mode_;
double psnr_threshold_;
int gf_max_pyr_height_;
int cpu_used_;
int nframes_;
double psnr_;
};
TEST_P(GFMaxPyrHeightTest, EncodeAndVerifyPSNR) {
libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
cfg_.g_timebase.den, cfg_.g_timebase.num,
0, 32);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
EXPECT_GT(GetAveragePsnr(), GetPsnrThreshold())
<< "GF Max Pyramid Height = " << gf_max_pyr_height_;
}
AV1_INSTANTIATE_TEST_CASE(GFMaxPyrHeightTest,
::testing::Values(::libaom_test::kTwoPassGood),
::testing::ValuesIn(kTestParams));
} // namespace

View file

@ -31,7 +31,7 @@ static void generate_kernels(ACMRandom *rnd, InterpKernel hkernel,
hkernel[2] = hkernel[4] =
WIENER_FILT_TAP2_MINV +
rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 1 - WIENER_FILT_TAP2_MINV);
hkernel[3] = -2 * (hkernel[0] + hkernel[1] + hkernel[2]);
hkernel[3] = -(hkernel[0] + hkernel[1] + hkernel[2]);
hkernel[7] = 0;
vkernel[0] = vkernel[6] =
@ -43,7 +43,7 @@ static void generate_kernels(ACMRandom *rnd, InterpKernel hkernel,
vkernel[2] = vkernel[4] =
WIENER_FILT_TAP2_MINV +
rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 1 - WIENER_FILT_TAP2_MINV);
vkernel[3] = -2 * (vkernel[0] + vkernel[1] + vkernel[2]);
vkernel[3] = -(vkernel[0] + vkernel[1] + vkernel[2]);
vkernel[7] = 0;
}

View file

@ -28,13 +28,8 @@ using ::testing::tuple;
/* TESTING PARAMETERS */
#define NUM_TEST_VIDEOS 3
const int kBitrate = 40;
// PSNR thresholds found by experiment
const double kPSNRThresholds[] = { 26.0, 28.0, 20.0 };
typedef struct {
const char *filename;
aom_img_fmt fmt;
@ -42,18 +37,20 @@ typedef struct {
unsigned int profile;
unsigned int limit;
unsigned int screen_content;
double psnr_threshold;
} TestVideoParam;
const TestVideoParam kTestVideoVectors[] = {
{ "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0 },
{ "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0 },
{ "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1 },
{ "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0, 26.0 },
{ "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0, 28.0 },
{ "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1, 20.0 },
// Image coding (single frame).
{ "niklas_1280_720_30.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 1, 0, 32.0 },
};
// Superres modes tested
// SUPERRES_QTHRESH is not included, as it has its own test
const SUPERRES_MODE kSuperresModesNotQThresh[] = { SUPERRES_FIXED,
SUPERRES_RANDOM };
// Modes with extra params have their own tests.
const SUPERRES_MODE kSuperresModesWithoutParams[] = { SUPERRES_RANDOM,
SUPERRES_AUTO };
// Superres denominators and superres kf denominators to be tested
typedef tuple<int, int> SuperresDenominatorPair;
@ -74,10 +71,8 @@ const SuperresQThresholdPair kSuperresQThresholds[] = {
/* END (TESTING PARAMETERS) */
// Test parameter list:
// <[needed for EncoderTest], test_video_idx_, superres_mode_,
// tuple(superres_denom_, superres_kf_denom_)>
typedef tuple<const libaom_test::CodecFactory *, int, SUPERRES_MODE,
SuperresDenominatorPair>
// <[needed for EncoderTest], test_video_param_, superres_mode_>
typedef tuple<const libaom_test::CodecFactory *, TestVideoParam, SUPERRES_MODE>
HorzSuperresTestParam;
class HorzSuperresEndToEndTest
@ -85,16 +80,113 @@ class HorzSuperresEndToEndTest
public ::libaom_test::EncoderTest {
protected:
HorzSuperresEndToEndTest()
: EncoderTest(GET_PARAM(0)), test_video_idx_(GET_PARAM(1)),
superres_mode_(GET_PARAM(2)), psnr_(0.0), frame_count_(0) {
test_video_param_ = kTestVideoVectors[test_video_idx_];
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
superres_mode_(GET_PARAM(2)), psnr_(0.0), frame_count_(0) {}
SuperresDenominatorPair denoms = GET_PARAM(3);
virtual ~HorzSuperresEndToEndTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libaom_test::kTwoPassGood);
cfg_.g_lag_in_frames = 5;
cfg_.rc_end_usage = AOM_Q;
cfg_.rc_target_bitrate = kBitrate;
cfg_.g_error_resilient = 0;
cfg_.g_profile = test_video_param_.profile;
cfg_.g_input_bit_depth = (unsigned int)test_video_param_.bit_depth;
cfg_.g_bit_depth = test_video_param_.bit_depth;
init_flags_ = AOM_CODEC_USE_PSNR;
if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH;
// Set superres parameters
cfg_.rc_superres_mode = superres_mode_;
}
virtual void BeginPassHook(unsigned int) {
psnr_ = 0.0;
frame_count_ = 0;
}
virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
psnr_ += pkt->data.psnr.psnr[0];
frame_count_++;
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(AV1E_SET_TILE_COLUMNS, 4);
// Set cpu-used = 8 for speed
encoder->Control(AOME_SET_CPUUSED, 8);
// Test screen coding tools
if (test_video_param_.screen_content)
encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
else
encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT);
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
}
}
double GetAveragePsnr() const {
if (frame_count_) return psnr_ / frame_count_;
return 0.0;
}
void DoTest() {
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0,
test_video_param_.limit));
ASSERT_TRUE(video.get() != NULL);
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
const double psnr = GetAveragePsnr();
EXPECT_GT(psnr, test_video_param_.psnr_threshold)
<< "superres_mode_ = " << superres_mode_;
EXPECT_EQ(test_video_param_.limit, frame_count_)
<< "superres_mode_ = " << superres_mode_;
}
TestVideoParam test_video_param_;
SUPERRES_MODE superres_mode_;
private:
double psnr_;
unsigned int frame_count_;
};
TEST_P(HorzSuperresEndToEndTest, HorzSuperresEndToEndPSNRTest) { DoTest(); }
AV1_INSTANTIATE_TEST_CASE(HorzSuperresEndToEndTest,
::testing::ValuesIn(kTestVideoVectors),
::testing::ValuesIn(kSuperresModesWithoutParams));
// Test parameter list:
// <[needed for EncoderTest], test_video_param_, tuple(superres_denom_,
// superres_kf_denom_)>
typedef tuple<const libaom_test::CodecFactory *, TestVideoParam,
SuperresDenominatorPair>
HorzSuperresFixedTestParam;
class HorzSuperresFixedEndToEndTest
: public ::testing::TestWithParam<HorzSuperresFixedTestParam>,
public ::libaom_test::EncoderTest {
protected:
HorzSuperresFixedEndToEndTest()
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
superres_mode_(SUPERRES_FIXED), psnr_(0.0), frame_count_(0) {
SuperresDenominatorPair denoms = GET_PARAM(2);
superres_denom_ = ::testing::get<0>(denoms);
superres_kf_denom_ = ::testing::get<1>(denoms);
}
virtual ~HorzSuperresEndToEndTest() {}
virtual ~HorzSuperresFixedEndToEndTest() {}
virtual void SetUp() {
InitializeConfig();
@ -151,8 +243,6 @@ class HorzSuperresEndToEndTest
return 0.0;
}
double GetPsnrThreshold() { return kPSNRThresholds[test_video_idx_]; }
void DoTest() {
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0,
@ -161,7 +251,7 @@ class HorzSuperresEndToEndTest
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
const double psnr = GetAveragePsnr();
EXPECT_GT(psnr, GetPsnrThreshold())
EXPECT_GT(psnr, test_video_param_.psnr_threshold)
<< "superres_mode_ = " << superres_mode_
<< ", superres_denom_ = " << superres_denom_
<< ", superres_kf_denom_ = " << superres_kf_denom_;
@ -172,7 +262,6 @@ class HorzSuperresEndToEndTest
<< ", superres_kf_denom_ = " << superres_kf_denom_;
}
int test_video_idx_;
TestVideoParam test_video_param_;
SUPERRES_MODE superres_mode_;
int superres_denom_;
@ -183,17 +272,16 @@ class HorzSuperresEndToEndTest
unsigned int frame_count_;
};
TEST_P(HorzSuperresEndToEndTest, HorzSuperresEndToEndPSNRTest) { DoTest(); }
TEST_P(HorzSuperresFixedEndToEndTest, HorzSuperresFixedTestParam) { DoTest(); }
AV1_INSTANTIATE_TEST_CASE(HorzSuperresEndToEndTest,
::testing::Range(0, NUM_TEST_VIDEOS),
::testing::ValuesIn(kSuperresModesNotQThresh),
AV1_INSTANTIATE_TEST_CASE(HorzSuperresFixedEndToEndTest,
::testing::ValuesIn(kTestVideoVectors),
::testing::ValuesIn(kSuperresDenominators));
// Test parameter list:
// <[needed for EncoderTest], test_video_idx_, tuple(superres_denom_,
// superres_kf_denom_), tuple(superres_qthresh_,superres_kf_qthresh_)>
typedef tuple<const libaom_test::CodecFactory *, int, SuperresDenominatorPair,
// <[needed for EncoderTest], test_video_param_,
// tuple(superres_qthresh_,superres_kf_qthresh_)>
typedef tuple<const libaom_test::CodecFactory *, TestVideoParam,
SuperresQThresholdPair>
HorzSuperresQThreshTestParam;
@ -202,15 +290,9 @@ class HorzSuperresQThreshEndToEndTest
public ::libaom_test::EncoderTest {
protected:
HorzSuperresQThreshEndToEndTest()
: EncoderTest(GET_PARAM(0)), test_video_idx_(GET_PARAM(1)),
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
superres_mode_(SUPERRES_QTHRESH), psnr_(0.0), frame_count_(0) {
test_video_param_ = kTestVideoVectors[test_video_idx_];
SuperresDenominatorPair denoms = GET_PARAM(2);
superres_denom_ = ::testing::get<0>(denoms);
superres_kf_denom_ = ::testing::get<1>(denoms);
SuperresQThresholdPair qthresholds = GET_PARAM(3);
SuperresQThresholdPair qthresholds = GET_PARAM(2);
superres_qthresh_ = ::testing::get<0>(qthresholds);
superres_kf_qthresh_ = ::testing::get<1>(qthresholds);
}
@ -232,8 +314,6 @@ class HorzSuperresQThreshEndToEndTest
// Set superres parameters
cfg_.rc_superres_mode = superres_mode_;
cfg_.rc_superres_denominator = superres_denom_;
cfg_.rc_superres_kf_denominator = superres_kf_denom_;
cfg_.rc_superres_qthresh = superres_qthresh_;
cfg_.rc_superres_kf_qthresh = superres_kf_qthresh_;
}
@ -274,8 +354,6 @@ class HorzSuperresQThreshEndToEndTest
return 0.0;
}
double GetPsnrThreshold() { return kPSNRThresholds[test_video_idx_]; }
void DoTest() {
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0,
@ -284,26 +362,19 @@ class HorzSuperresQThreshEndToEndTest
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
const double psnr = GetAveragePsnr();
EXPECT_GT(psnr, GetPsnrThreshold())
EXPECT_GT(psnr, test_video_param_.psnr_threshold)
<< "superres_mode_ = " << superres_mode_
<< ", superres_denom_ = " << superres_denom_
<< ", superres_kf_denom_ = " << superres_kf_denom_
<< ", superres_qthresh_ = " << superres_qthresh_
<< ", superres_kf_qthresh_ = " << superres_kf_qthresh_;
EXPECT_EQ(test_video_param_.limit, frame_count_)
<< "superres_mode_ = " << superres_mode_
<< ", superres_denom_ = " << superres_denom_
<< ", superres_kf_denom_ = " << superres_kf_denom_
<< ", superres_qthresh_ = " << superres_qthresh_
<< ", superres_kf_qthresh_ = " << superres_kf_qthresh_;
}
int test_video_idx_;
TestVideoParam test_video_param_;
SUPERRES_MODE superres_mode_;
int superres_denom_;
int superres_kf_denom_;
int superres_qthresh_;
int superres_kf_qthresh_;
@ -317,8 +388,7 @@ TEST_P(HorzSuperresQThreshEndToEndTest, HorzSuperresQThreshEndToEndPSNRTest) {
}
AV1_INSTANTIATE_TEST_CASE(HorzSuperresQThreshEndToEndTest,
::testing::Range(0, NUM_TEST_VIDEOS),
::testing::ValuesIn(kSuperresDenominators),
::testing::ValuesIn(kTestVideoVectors),
::testing::ValuesIn(kSuperresQThresholds));
} // namespace

108
third_party/aom/test/level_test.cc vendored Normal file
View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <memory>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "test/yuv_video_source.h"
namespace {
// Speed settings tested
static const int kCpuUsedVectors[] = {
1,
2,
3,
4,
};
class LevelTest
: public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
public ::libaom_test::EncoderTest {
protected:
LevelTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
cpu_used_(GET_PARAM(2)), target_level_(31) {}
virtual ~LevelTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
cfg_.g_lag_in_frames = 5;
cfg_.rc_end_usage = AOM_VBR;
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = AOM_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
}
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, cpu_used_);
encoder->Control(AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
}
}
}
libaom_test::TestMode encoding_mode_;
int cpu_used_;
int target_level_;
};
TEST_P(LevelTest, TestTargetLevelApi) {
static const aom_codec_iface_t *codec = &aom_codec_av1_cx_algo;
aom_codec_ctx_t enc;
aom_codec_enc_cfg_t cfg;
EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(codec, &cfg, 0));
EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, codec, &cfg, 0));
for (int operating_point = 0; operating_point <= 32; ++operating_point) {
for (int level = 0; level <= 32; ++level) {
const int target_level = operating_point * 100 + level;
if ((level >= 0 && level <= 23) || level == 31 || operating_point > 31) {
EXPECT_EQ(AOM_CODEC_OK,
aom_codec_control(&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX,
target_level));
} else {
EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
aom_codec_control(&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX,
target_level));
}
}
}
EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
}
TEST_P(LevelTest, TestTargetLevel19) {
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource("park_joy_90p_8_420.y4m", 0, 10));
ASSERT_TRUE(video.get() != NULL);
// Level index 19 corresponding to level 6.3.
target_level_ = 19;
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
}
AV1_INSTANTIATE_TEST_CASE(LevelTest,
::testing::Values(::libaom_test::kTwoPassGood),
::testing::ValuesIn(kCpuUsedVectors));
} // namespace

View file

@ -191,6 +191,13 @@ class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
}
}
void FillCoeffRandomRows(int num) {
FillCoeffZero();
for (int i = 0; i < num; ++i) {
coeff_[i] = GetRandomCoeff();
}
}
void FillCoeffZero() { FillCoeff(0); }
void FillCoeffConstant() {
@ -287,28 +294,31 @@ TEST_P(QuantizeTest, DISABLED_Speed) {
const int16_t *dequant = qtab_->dequant.y_dequant_QTX[q];
const int kNumTests = 5000000;
aom_usec_timer timer, simd_timer;
int rows = tx_size_high[tx_size_];
int cols = tx_size_wide[tx_size_];
for (int cnt = 0; cnt <= rows; cnt++) {
FillCoeffRandomRows(cnt * cols);
FillCoeffRandom();
aom_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
quant_ref_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift,
qcoeff, dqcoeff, dequant, eob, sc->scan, sc->iscan);
}
aom_usec_timer_mark(&timer);
aom_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
quant_ref_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift,
qcoeff, dqcoeff, dequant, eob, sc->scan, sc->iscan);
aom_usec_timer_start(&simd_timer);
for (int n = 0; n < kNumTests; ++n) {
quant_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, qcoeff,
dqcoeff, dequant, eob, sc->scan, sc->iscan);
}
aom_usec_timer_mark(&simd_timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
const int simd_elapsed_time =
static_cast<int>(aom_usec_timer_elapsed(&simd_timer));
printf("c_time = %d \t simd_time = %d \t Gain = %d \n", elapsed_time,
simd_elapsed_time, (elapsed_time / simd_elapsed_time));
}
aom_usec_timer_mark(&timer);
aom_usec_timer_start(&simd_timer);
for (int n = 0; n < kNumTests; ++n) {
quant_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, qcoeff,
dqcoeff, dequant, eob, sc->scan, sc->iscan);
}
aom_usec_timer_mark(&simd_timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
const int simd_elapsed_time =
static_cast<int>(aom_usec_timer_elapsed(&simd_timer));
printf("c_time = %d \t simd_time = %d \t Gain = %d \n", elapsed_time,
simd_elapsed_time, (elapsed_time / simd_elapsed_time));
}
using ::testing::make_tuple;
@ -398,6 +408,24 @@ const QuantizeParam kQParamArraySSE2[] = {
TX_32X32, TYPE_B, AOM_BITS_10),
make_tuple(&aom_highbd_quantize_b_32x32_c, &aom_highbd_quantize_b_32x32_sse2,
TX_32X32, TYPE_B, AOM_BITS_12),
make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2,
TX_64X64, TYPE_B, AOM_BITS_8),
make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2,
TX_64X64, TYPE_B, AOM_BITS_10),
make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2,
TX_64X64, TYPE_B, AOM_BITS_12),
make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2,
TX_16X16, TYPE_B, AOM_BITS_8),
make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2, TX_8X8,
TYPE_B, AOM_BITS_8),
make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2, TX_4X4,
TYPE_B, AOM_BITS_8),
make_tuple(&aom_quantize_b_32x32_adaptive_c,
&aom_quantize_b_32x32_adaptive_sse2, TX_32X16, TYPE_B, AOM_BITS_8),
make_tuple(&aom_quantize_b_32x32_adaptive_c,
&aom_quantize_b_32x32_adaptive_sse2, TX_16X32, TYPE_B, AOM_BITS_8),
make_tuple(&aom_quantize_b_32x32_adaptive_c,
&aom_quantize_b_32x32_adaptive_sse2, TX_32X32, TYPE_B, AOM_BITS_8)
};
INSTANTIATE_TEST_CASE_P(SSE2, QuantizeTest,

View file

@ -374,6 +374,7 @@ class ResizeRealtimeTest
if (video->frame() == 0) {
encoder->Control(AV1E_SET_AQ_MODE, 3);
encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1);
}
if (change_bitrate_ && video->frame() == 120) {

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <memory>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "test/yuv_video_source.h"
namespace {
const unsigned int kFrames = 10;
const int kBitrate = 500;
// List of psnr thresholds for speed settings 0-8
const double kPsnrThreshold[9] = { 36.9, 36.9, 36.85, 36.8, 36.6,
36.4, 36.0, 35.5, 35.0 };
typedef struct {
const char *filename;
unsigned int input_bit_depth;
aom_img_fmt fmt;
aom_bit_depth_t bit_depth;
unsigned int profile;
} TestVideoParam;
std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) {
return os << "TestVideoParam { filename:" << test_arg.filename
<< " input_bit_depth:" << test_arg.input_bit_depth
<< " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth
<< " profile:" << test_arg.profile << "}";
}
// TODO(kyslov): Add more test vectors
const TestVideoParam kTestVectors[] = {
{ "park_joy_90p_8_420.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 },
};
// Speed settings tested
const int kCpuUsedVectors[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
class RTEndToEndTest
: public ::libaom_test::CodecTestWith2Params<TestVideoParam, int>,
public ::libaom_test::EncoderTest {
protected:
RTEndToEndTest()
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
cpu_used_(GET_PARAM(2)), psnr_(0.0), nframes_(0) {}
virtual ~RTEndToEndTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libaom_test::kRealTime);
cfg_.g_usage = 1; // TODO(kyslov): Move it to encode_test_driver.cc
cfg_.rc_end_usage = AOM_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
}
virtual void BeginPassHook(unsigned int) {
psnr_ = 0.0;
nframes_ = 0;
}
virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
psnr_ += pkt->data.psnr.psnr[0];
nframes_++;
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(AV1E_SET_TILE_COLUMNS, 1);
encoder->Control(AOME_SET_CPUUSED, cpu_used_);
encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT);
}
}
double GetAveragePsnr() const {
if (nframes_) return psnr_ / nframes_;
return 0.0;
}
double GetPsnrThreshold() { return kPsnrThreshold[cpu_used_]; }
void DoTest() {
cfg_.rc_target_bitrate = kBitrate;
cfg_.g_error_resilient = 0;
cfg_.g_profile = test_video_param_.profile;
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
cfg_.g_bit_depth = test_video_param_.bit_depth;
init_flags_ = AOM_CODEC_USE_PSNR;
if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH;
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0,
kFrames));
ASSERT_TRUE(video.get() != NULL);
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
const double psnr = GetAveragePsnr();
EXPECT_GT(psnr, GetPsnrThreshold()) << "cpu used = " << cpu_used_;
}
TestVideoParam test_video_param_;
int cpu_used_;
private:
double psnr_;
unsigned int nframes_;
};
class RTEndToEndTestLarge : public RTEndToEndTest {};
TEST_P(RTEndToEndTestLarge, EndtoEndPSNRTest) { DoTest(); }
TEST_P(RTEndToEndTest, EndtoEndPSNRTest) { DoTest(); }
AV1_INSTANTIATE_TEST_CASE(RTEndToEndTestLarge,
::testing::ValuesIn(kTestVectors),
::testing::ValuesIn(kCpuUsedVectors));
AV1_INSTANTIATE_TEST_CASE(RTEndToEndTest, ::testing::Values(kTestVectors[0]),
::testing::Values(kCpuUsedVectors[8]));
} // namespace

View file

@ -532,3 +532,9 @@ e94687eb0e90179b3800b6d5e11eb7e9bfb34eec *av1-1-b8-22-svc-L1T2.ivf
2bc12b16385ea14323bc79607fb8dfbd7edaf8ef *av1-1-b8-22-svc-L1T2.ivf.md5
32ef2f14ee9cb11a24a22934f4c065e926e5d236 *av1-1-b8-22-svc-L2T2.ivf
f476a10ff06d750129f8229755d51e17ff141b2a *av1-1-b8-22-svc-L2T2.ivf.md5
afca5502a489692b0a3c120370b0f43b8fc572a1 *av1-1-b8-04-cdfupdate.ivf
13b9423155a08d5e3a2fd9ae4a973bb046718cdf *av1-1-b8-04-cdfupdate.ivf.md5
f064290d7fcd3b3de19020e8aec6c43c88d3a505 *av1-1-b8-05-mv.ivf
bff316e63ded5559116bdc2fa4aa97ad7b1a1761 *av1-1-b8-05-mv.ivf.md5
b48a717c7c003b8dd23c3c2caed1ac673380fdb3 *av1-1-b8-06-mfmv.ivf
1424e3cb53e00eb56b94f4c725826274212c42b6 *av1-1-b8-06-mfmv.ivf.md5

View file

@ -64,10 +64,14 @@ list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES
"${AOM_ROOT}/test/encode_test_driver.cc"
"${AOM_ROOT}/test/encode_test_driver.h"
"${AOM_ROOT}/test/end_to_end_test.cc"
"${AOM_ROOT}/test/fwd_kf_test.cc"
"${AOM_ROOT}/test/gf_max_pyr_height_test.cc"
"${AOM_ROOT}/test/rt_end_to_end_test.cc"
"${AOM_ROOT}/test/error_resilience_test.cc"
"${AOM_ROOT}/test/frame_size_tests.cc"
"${AOM_ROOT}/test/horz_superres_test.cc"
"${AOM_ROOT}/test/i420_video_source.h"
"${AOM_ROOT}/test/level_test.cc"
"${AOM_ROOT}/test/lossless_test.cc"
"${AOM_ROOT}/test/monochrome_test.cc"
"${AOM_ROOT}/test/qm_test.cc"
@ -120,7 +124,8 @@ if(NOT BUILD_SHARED_LIBS)
"${AOM_ROOT}/test/film_grain_table_test.cc"
"${AOM_ROOT}/test/segment_binarization_sync.cc"
"${AOM_ROOT}/test/superframe_test.cc"
"${AOM_ROOT}/test/tile_independence_test.cc")
"${AOM_ROOT}/test/tile_independence_test.cc"
"${AOM_ROOT}/test/yuv_temporal_filter_test.cc")
endif()
list(APPEND AOM_UNIT_TEST_COMMON_INTRIN_NEON

View file

@ -500,6 +500,12 @@ if(CONFIG_AV1_DECODER)
"av1-1-b8-03-sizeup.mkv.md5"
"av1-1-b8-03-sizedown.mkv"
"av1-1-b8-03-sizedown.mkv.md5"
"av1-1-b8-04-cdfupdate.ivf"
"av1-1-b8-04-cdfupdate.ivf.md5"
"av1-1-b8-05-mv.ivf"
"av1-1-b8-05-mv.ivf.md5"
"av1-1-b8-06-mfmv.ivf"
"av1-1-b8-06-mfmv.ivf.md5"
"av1-1-b8-22-svc-L2T1.ivf"
"av1-1-b8-22-svc-L2T1.ivf.md5"
"av1-1-b8-22-svc-L1T2.ivf"

View file

@ -16,125 +16,243 @@ namespace libaom_test {
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
#if CONFIG_AV1_DECODER
const char *const kAV1TestVectors[] = {
"av1-1-b8-00-quantizer-00.ivf", "av1-1-b8-00-quantizer-01.ivf",
"av1-1-b8-00-quantizer-02.ivf", "av1-1-b8-00-quantizer-03.ivf",
"av1-1-b8-00-quantizer-04.ivf", "av1-1-b8-00-quantizer-05.ivf",
"av1-1-b8-00-quantizer-06.ivf", "av1-1-b8-00-quantizer-07.ivf",
"av1-1-b8-00-quantizer-08.ivf", "av1-1-b8-00-quantizer-09.ivf",
"av1-1-b8-00-quantizer-10.ivf", "av1-1-b8-00-quantizer-11.ivf",
"av1-1-b8-00-quantizer-12.ivf", "av1-1-b8-00-quantizer-13.ivf",
"av1-1-b8-00-quantizer-14.ivf", "av1-1-b8-00-quantizer-15.ivf",
"av1-1-b8-00-quantizer-16.ivf", "av1-1-b8-00-quantizer-17.ivf",
"av1-1-b8-00-quantizer-18.ivf", "av1-1-b8-00-quantizer-19.ivf",
"av1-1-b8-00-quantizer-20.ivf", "av1-1-b8-00-quantizer-21.ivf",
"av1-1-b8-00-quantizer-22.ivf", "av1-1-b8-00-quantizer-23.ivf",
"av1-1-b8-00-quantizer-24.ivf", "av1-1-b8-00-quantizer-25.ivf",
"av1-1-b8-00-quantizer-26.ivf", "av1-1-b8-00-quantizer-27.ivf",
"av1-1-b8-00-quantizer-28.ivf", "av1-1-b8-00-quantizer-29.ivf",
"av1-1-b8-00-quantizer-30.ivf", "av1-1-b8-00-quantizer-31.ivf",
"av1-1-b8-00-quantizer-32.ivf", "av1-1-b8-00-quantizer-33.ivf",
"av1-1-b8-00-quantizer-34.ivf", "av1-1-b8-00-quantizer-35.ivf",
"av1-1-b8-00-quantizer-36.ivf", "av1-1-b8-00-quantizer-37.ivf",
"av1-1-b8-00-quantizer-38.ivf", "av1-1-b8-00-quantizer-39.ivf",
"av1-1-b8-00-quantizer-40.ivf", "av1-1-b8-00-quantizer-41.ivf",
"av1-1-b8-00-quantizer-42.ivf", "av1-1-b8-00-quantizer-43.ivf",
"av1-1-b8-00-quantizer-44.ivf", "av1-1-b8-00-quantizer-45.ivf",
"av1-1-b8-00-quantizer-46.ivf", "av1-1-b8-00-quantizer-47.ivf",
"av1-1-b8-00-quantizer-48.ivf", "av1-1-b8-00-quantizer-49.ivf",
"av1-1-b8-00-quantizer-50.ivf", "av1-1-b8-00-quantizer-51.ivf",
"av1-1-b8-00-quantizer-52.ivf", "av1-1-b8-00-quantizer-53.ivf",
"av1-1-b8-00-quantizer-54.ivf", "av1-1-b8-00-quantizer-55.ivf",
"av1-1-b8-00-quantizer-56.ivf", "av1-1-b8-00-quantizer-57.ivf",
"av1-1-b8-00-quantizer-58.ivf", "av1-1-b8-00-quantizer-59.ivf",
"av1-1-b8-00-quantizer-60.ivf", "av1-1-b8-00-quantizer-61.ivf",
"av1-1-b8-00-quantizer-62.ivf", "av1-1-b8-00-quantizer-63.ivf",
"av1-1-b10-00-quantizer-00.ivf", "av1-1-b10-00-quantizer-01.ivf",
"av1-1-b10-00-quantizer-02.ivf", "av1-1-b10-00-quantizer-03.ivf",
"av1-1-b10-00-quantizer-04.ivf", "av1-1-b10-00-quantizer-05.ivf",
"av1-1-b10-00-quantizer-06.ivf", "av1-1-b10-00-quantizer-07.ivf",
"av1-1-b10-00-quantizer-08.ivf", "av1-1-b10-00-quantizer-09.ivf",
"av1-1-b10-00-quantizer-10.ivf", "av1-1-b10-00-quantizer-11.ivf",
"av1-1-b10-00-quantizer-12.ivf", "av1-1-b10-00-quantizer-13.ivf",
"av1-1-b10-00-quantizer-14.ivf", "av1-1-b10-00-quantizer-15.ivf",
"av1-1-b10-00-quantizer-16.ivf", "av1-1-b10-00-quantizer-17.ivf",
"av1-1-b10-00-quantizer-18.ivf", "av1-1-b10-00-quantizer-19.ivf",
"av1-1-b10-00-quantizer-20.ivf", "av1-1-b10-00-quantizer-21.ivf",
"av1-1-b10-00-quantizer-22.ivf", "av1-1-b10-00-quantizer-23.ivf",
"av1-1-b10-00-quantizer-24.ivf", "av1-1-b10-00-quantizer-25.ivf",
"av1-1-b10-00-quantizer-26.ivf", "av1-1-b10-00-quantizer-27.ivf",
"av1-1-b10-00-quantizer-28.ivf", "av1-1-b10-00-quantizer-29.ivf",
"av1-1-b10-00-quantizer-30.ivf", "av1-1-b10-00-quantizer-31.ivf",
"av1-1-b10-00-quantizer-32.ivf", "av1-1-b10-00-quantizer-33.ivf",
"av1-1-b10-00-quantizer-34.ivf", "av1-1-b10-00-quantizer-35.ivf",
"av1-1-b10-00-quantizer-36.ivf", "av1-1-b10-00-quantizer-37.ivf",
"av1-1-b10-00-quantizer-38.ivf", "av1-1-b10-00-quantizer-39.ivf",
"av1-1-b10-00-quantizer-40.ivf", "av1-1-b10-00-quantizer-41.ivf",
"av1-1-b10-00-quantizer-42.ivf", "av1-1-b10-00-quantizer-43.ivf",
"av1-1-b10-00-quantizer-44.ivf", "av1-1-b10-00-quantizer-45.ivf",
"av1-1-b10-00-quantizer-46.ivf", "av1-1-b10-00-quantizer-47.ivf",
"av1-1-b10-00-quantizer-48.ivf", "av1-1-b10-00-quantizer-49.ivf",
"av1-1-b10-00-quantizer-50.ivf", "av1-1-b10-00-quantizer-51.ivf",
"av1-1-b10-00-quantizer-52.ivf", "av1-1-b10-00-quantizer-53.ivf",
"av1-1-b10-00-quantizer-54.ivf", "av1-1-b10-00-quantizer-55.ivf",
"av1-1-b10-00-quantizer-56.ivf", "av1-1-b10-00-quantizer-57.ivf",
"av1-1-b10-00-quantizer-58.ivf", "av1-1-b10-00-quantizer-59.ivf",
"av1-1-b10-00-quantizer-60.ivf", "av1-1-b10-00-quantizer-61.ivf",
"av1-1-b10-00-quantizer-62.ivf", "av1-1-b10-00-quantizer-63.ivf",
"av1-1-b8-01-size-16x16.ivf", "av1-1-b8-01-size-16x18.ivf",
"av1-1-b8-01-size-16x32.ivf", "av1-1-b8-01-size-16x34.ivf",
"av1-1-b8-01-size-16x64.ivf", "av1-1-b8-01-size-16x66.ivf",
"av1-1-b8-01-size-18x16.ivf", "av1-1-b8-01-size-18x18.ivf",
"av1-1-b8-01-size-18x32.ivf", "av1-1-b8-01-size-18x34.ivf",
"av1-1-b8-01-size-18x64.ivf", "av1-1-b8-01-size-18x66.ivf",
"av1-1-b8-01-size-196x196.ivf", "av1-1-b8-01-size-196x198.ivf",
"av1-1-b8-01-size-196x200.ivf", "av1-1-b8-01-size-196x202.ivf",
"av1-1-b8-01-size-196x208.ivf", "av1-1-b8-01-size-196x210.ivf",
"av1-1-b8-01-size-196x224.ivf", "av1-1-b8-01-size-196x226.ivf",
"av1-1-b8-01-size-198x196.ivf", "av1-1-b8-01-size-198x198.ivf",
"av1-1-b8-01-size-198x200.ivf", "av1-1-b8-01-size-198x202.ivf",
"av1-1-b8-01-size-198x208.ivf", "av1-1-b8-01-size-198x210.ivf",
"av1-1-b8-01-size-198x224.ivf", "av1-1-b8-01-size-198x226.ivf",
"av1-1-b8-01-size-200x196.ivf", "av1-1-b8-01-size-200x198.ivf",
"av1-1-b8-01-size-200x200.ivf", "av1-1-b8-01-size-200x202.ivf",
"av1-1-b8-01-size-200x208.ivf", "av1-1-b8-01-size-200x210.ivf",
"av1-1-b8-01-size-200x224.ivf", "av1-1-b8-01-size-200x226.ivf",
"av1-1-b8-01-size-202x196.ivf", "av1-1-b8-01-size-202x198.ivf",
"av1-1-b8-01-size-202x200.ivf", "av1-1-b8-01-size-202x202.ivf",
"av1-1-b8-01-size-202x208.ivf", "av1-1-b8-01-size-202x210.ivf",
"av1-1-b8-01-size-202x224.ivf", "av1-1-b8-01-size-202x226.ivf",
"av1-1-b8-01-size-208x196.ivf", "av1-1-b8-01-size-208x198.ivf",
"av1-1-b8-01-size-208x200.ivf", "av1-1-b8-01-size-208x202.ivf",
"av1-1-b8-01-size-208x208.ivf", "av1-1-b8-01-size-208x210.ivf",
"av1-1-b8-01-size-208x224.ivf", "av1-1-b8-01-size-208x226.ivf",
"av1-1-b8-01-size-210x196.ivf", "av1-1-b8-01-size-210x198.ivf",
"av1-1-b8-01-size-210x200.ivf", "av1-1-b8-01-size-210x202.ivf",
"av1-1-b8-01-size-210x208.ivf", "av1-1-b8-01-size-210x210.ivf",
"av1-1-b8-01-size-210x224.ivf", "av1-1-b8-01-size-210x226.ivf",
"av1-1-b8-01-size-224x196.ivf", "av1-1-b8-01-size-224x198.ivf",
"av1-1-b8-01-size-224x200.ivf", "av1-1-b8-01-size-224x202.ivf",
"av1-1-b8-01-size-224x208.ivf", "av1-1-b8-01-size-224x210.ivf",
"av1-1-b8-01-size-224x224.ivf", "av1-1-b8-01-size-224x226.ivf",
"av1-1-b8-01-size-226x196.ivf", "av1-1-b8-01-size-226x198.ivf",
"av1-1-b8-01-size-226x200.ivf", "av1-1-b8-01-size-226x202.ivf",
"av1-1-b8-01-size-226x208.ivf", "av1-1-b8-01-size-226x210.ivf",
"av1-1-b8-01-size-226x224.ivf", "av1-1-b8-01-size-226x226.ivf",
"av1-1-b8-01-size-32x16.ivf", "av1-1-b8-01-size-32x18.ivf",
"av1-1-b8-01-size-32x32.ivf", "av1-1-b8-01-size-32x34.ivf",
"av1-1-b8-01-size-32x64.ivf", "av1-1-b8-01-size-32x66.ivf",
"av1-1-b8-01-size-34x16.ivf", "av1-1-b8-01-size-34x18.ivf",
"av1-1-b8-01-size-34x32.ivf", "av1-1-b8-01-size-34x34.ivf",
"av1-1-b8-01-size-34x64.ivf", "av1-1-b8-01-size-34x66.ivf",
"av1-1-b8-01-size-64x16.ivf", "av1-1-b8-01-size-64x18.ivf",
"av1-1-b8-01-size-64x32.ivf", "av1-1-b8-01-size-64x34.ivf",
"av1-1-b8-01-size-64x64.ivf", "av1-1-b8-01-size-64x66.ivf",
"av1-1-b8-01-size-66x16.ivf", "av1-1-b8-01-size-66x18.ivf",
"av1-1-b8-01-size-66x32.ivf", "av1-1-b8-01-size-66x34.ivf",
"av1-1-b8-01-size-66x64.ivf", "av1-1-b8-01-size-66x66.ivf",
"av1-1-b8-02-allintra.ivf", "av1-1-b8-03-sizedown.mkv",
"av1-1-b8-03-sizeup.mkv", "av1-1-b8-22-svc-L1T2.ivf",
"av1-1-b8-22-svc-L2T1.ivf", "av1-1-b8-22-svc-L2T2.ivf"
};
const char *const kAV1TestVectors[] = { "av1-1-b8-00-quantizer-00.ivf",
"av1-1-b8-00-quantizer-01.ivf",
"av1-1-b8-00-quantizer-02.ivf",
"av1-1-b8-00-quantizer-03.ivf",
"av1-1-b8-00-quantizer-04.ivf",
"av1-1-b8-00-quantizer-05.ivf",
"av1-1-b8-00-quantizer-06.ivf",
"av1-1-b8-00-quantizer-07.ivf",
"av1-1-b8-00-quantizer-08.ivf",
"av1-1-b8-00-quantizer-09.ivf",
"av1-1-b8-00-quantizer-10.ivf",
"av1-1-b8-00-quantizer-11.ivf",
"av1-1-b8-00-quantizer-12.ivf",
"av1-1-b8-00-quantizer-13.ivf",
"av1-1-b8-00-quantizer-14.ivf",
"av1-1-b8-00-quantizer-15.ivf",
"av1-1-b8-00-quantizer-16.ivf",
"av1-1-b8-00-quantizer-17.ivf",
"av1-1-b8-00-quantizer-18.ivf",
"av1-1-b8-00-quantizer-19.ivf",
"av1-1-b8-00-quantizer-20.ivf",
"av1-1-b8-00-quantizer-21.ivf",
"av1-1-b8-00-quantizer-22.ivf",
"av1-1-b8-00-quantizer-23.ivf",
"av1-1-b8-00-quantizer-24.ivf",
"av1-1-b8-00-quantizer-25.ivf",
"av1-1-b8-00-quantizer-26.ivf",
"av1-1-b8-00-quantizer-27.ivf",
"av1-1-b8-00-quantizer-28.ivf",
"av1-1-b8-00-quantizer-29.ivf",
"av1-1-b8-00-quantizer-30.ivf",
"av1-1-b8-00-quantizer-31.ivf",
"av1-1-b8-00-quantizer-32.ivf",
"av1-1-b8-00-quantizer-33.ivf",
"av1-1-b8-00-quantizer-34.ivf",
"av1-1-b8-00-quantizer-35.ivf",
"av1-1-b8-00-quantizer-36.ivf",
"av1-1-b8-00-quantizer-37.ivf",
"av1-1-b8-00-quantizer-38.ivf",
"av1-1-b8-00-quantizer-39.ivf",
"av1-1-b8-00-quantizer-40.ivf",
"av1-1-b8-00-quantizer-41.ivf",
"av1-1-b8-00-quantizer-42.ivf",
"av1-1-b8-00-quantizer-43.ivf",
"av1-1-b8-00-quantizer-44.ivf",
"av1-1-b8-00-quantizer-45.ivf",
"av1-1-b8-00-quantizer-46.ivf",
"av1-1-b8-00-quantizer-47.ivf",
"av1-1-b8-00-quantizer-48.ivf",
"av1-1-b8-00-quantizer-49.ivf",
"av1-1-b8-00-quantizer-50.ivf",
"av1-1-b8-00-quantizer-51.ivf",
"av1-1-b8-00-quantizer-52.ivf",
"av1-1-b8-00-quantizer-53.ivf",
"av1-1-b8-00-quantizer-54.ivf",
"av1-1-b8-00-quantizer-55.ivf",
"av1-1-b8-00-quantizer-56.ivf",
"av1-1-b8-00-quantizer-57.ivf",
"av1-1-b8-00-quantizer-58.ivf",
"av1-1-b8-00-quantizer-59.ivf",
"av1-1-b8-00-quantizer-60.ivf",
"av1-1-b8-00-quantizer-61.ivf",
"av1-1-b8-00-quantizer-62.ivf",
"av1-1-b8-00-quantizer-63.ivf",
"av1-1-b10-00-quantizer-00.ivf",
"av1-1-b10-00-quantizer-01.ivf",
"av1-1-b10-00-quantizer-02.ivf",
"av1-1-b10-00-quantizer-03.ivf",
"av1-1-b10-00-quantizer-04.ivf",
"av1-1-b10-00-quantizer-05.ivf",
"av1-1-b10-00-quantizer-06.ivf",
"av1-1-b10-00-quantizer-07.ivf",
"av1-1-b10-00-quantizer-08.ivf",
"av1-1-b10-00-quantizer-09.ivf",
"av1-1-b10-00-quantizer-10.ivf",
"av1-1-b10-00-quantizer-11.ivf",
"av1-1-b10-00-quantizer-12.ivf",
"av1-1-b10-00-quantizer-13.ivf",
"av1-1-b10-00-quantizer-14.ivf",
"av1-1-b10-00-quantizer-15.ivf",
"av1-1-b10-00-quantizer-16.ivf",
"av1-1-b10-00-quantizer-17.ivf",
"av1-1-b10-00-quantizer-18.ivf",
"av1-1-b10-00-quantizer-19.ivf",
"av1-1-b10-00-quantizer-20.ivf",
"av1-1-b10-00-quantizer-21.ivf",
"av1-1-b10-00-quantizer-22.ivf",
"av1-1-b10-00-quantizer-23.ivf",
"av1-1-b10-00-quantizer-24.ivf",
"av1-1-b10-00-quantizer-25.ivf",
"av1-1-b10-00-quantizer-26.ivf",
"av1-1-b10-00-quantizer-27.ivf",
"av1-1-b10-00-quantizer-28.ivf",
"av1-1-b10-00-quantizer-29.ivf",
"av1-1-b10-00-quantizer-30.ivf",
"av1-1-b10-00-quantizer-31.ivf",
"av1-1-b10-00-quantizer-32.ivf",
"av1-1-b10-00-quantizer-33.ivf",
"av1-1-b10-00-quantizer-34.ivf",
"av1-1-b10-00-quantizer-35.ivf",
"av1-1-b10-00-quantizer-36.ivf",
"av1-1-b10-00-quantizer-37.ivf",
"av1-1-b10-00-quantizer-38.ivf",
"av1-1-b10-00-quantizer-39.ivf",
"av1-1-b10-00-quantizer-40.ivf",
"av1-1-b10-00-quantizer-41.ivf",
"av1-1-b10-00-quantizer-42.ivf",
"av1-1-b10-00-quantizer-43.ivf",
"av1-1-b10-00-quantizer-44.ivf",
"av1-1-b10-00-quantizer-45.ivf",
"av1-1-b10-00-quantizer-46.ivf",
"av1-1-b10-00-quantizer-47.ivf",
"av1-1-b10-00-quantizer-48.ivf",
"av1-1-b10-00-quantizer-49.ivf",
"av1-1-b10-00-quantizer-50.ivf",
"av1-1-b10-00-quantizer-51.ivf",
"av1-1-b10-00-quantizer-52.ivf",
"av1-1-b10-00-quantizer-53.ivf",
"av1-1-b10-00-quantizer-54.ivf",
"av1-1-b10-00-quantizer-55.ivf",
"av1-1-b10-00-quantizer-56.ivf",
"av1-1-b10-00-quantizer-57.ivf",
"av1-1-b10-00-quantizer-58.ivf",
"av1-1-b10-00-quantizer-59.ivf",
"av1-1-b10-00-quantizer-60.ivf",
"av1-1-b10-00-quantizer-61.ivf",
"av1-1-b10-00-quantizer-62.ivf",
"av1-1-b10-00-quantizer-63.ivf",
"av1-1-b8-01-size-16x16.ivf",
"av1-1-b8-01-size-16x18.ivf",
"av1-1-b8-01-size-16x32.ivf",
"av1-1-b8-01-size-16x34.ivf",
"av1-1-b8-01-size-16x64.ivf",
"av1-1-b8-01-size-16x66.ivf",
"av1-1-b8-01-size-18x16.ivf",
"av1-1-b8-01-size-18x18.ivf",
"av1-1-b8-01-size-18x32.ivf",
"av1-1-b8-01-size-18x34.ivf",
"av1-1-b8-01-size-18x64.ivf",
"av1-1-b8-01-size-18x66.ivf",
"av1-1-b8-01-size-196x196.ivf",
"av1-1-b8-01-size-196x198.ivf",
"av1-1-b8-01-size-196x200.ivf",
"av1-1-b8-01-size-196x202.ivf",
"av1-1-b8-01-size-196x208.ivf",
"av1-1-b8-01-size-196x210.ivf",
"av1-1-b8-01-size-196x224.ivf",
"av1-1-b8-01-size-196x226.ivf",
"av1-1-b8-01-size-198x196.ivf",
"av1-1-b8-01-size-198x198.ivf",
"av1-1-b8-01-size-198x200.ivf",
"av1-1-b8-01-size-198x202.ivf",
"av1-1-b8-01-size-198x208.ivf",
"av1-1-b8-01-size-198x210.ivf",
"av1-1-b8-01-size-198x224.ivf",
"av1-1-b8-01-size-198x226.ivf",
"av1-1-b8-01-size-200x196.ivf",
"av1-1-b8-01-size-200x198.ivf",
"av1-1-b8-01-size-200x200.ivf",
"av1-1-b8-01-size-200x202.ivf",
"av1-1-b8-01-size-200x208.ivf",
"av1-1-b8-01-size-200x210.ivf",
"av1-1-b8-01-size-200x224.ivf",
"av1-1-b8-01-size-200x226.ivf",
"av1-1-b8-01-size-202x196.ivf",
"av1-1-b8-01-size-202x198.ivf",
"av1-1-b8-01-size-202x200.ivf",
"av1-1-b8-01-size-202x202.ivf",
"av1-1-b8-01-size-202x208.ivf",
"av1-1-b8-01-size-202x210.ivf",
"av1-1-b8-01-size-202x224.ivf",
"av1-1-b8-01-size-202x226.ivf",
"av1-1-b8-01-size-208x196.ivf",
"av1-1-b8-01-size-208x198.ivf",
"av1-1-b8-01-size-208x200.ivf",
"av1-1-b8-01-size-208x202.ivf",
"av1-1-b8-01-size-208x208.ivf",
"av1-1-b8-01-size-208x210.ivf",
"av1-1-b8-01-size-208x224.ivf",
"av1-1-b8-01-size-208x226.ivf",
"av1-1-b8-01-size-210x196.ivf",
"av1-1-b8-01-size-210x198.ivf",
"av1-1-b8-01-size-210x200.ivf",
"av1-1-b8-01-size-210x202.ivf",
"av1-1-b8-01-size-210x208.ivf",
"av1-1-b8-01-size-210x210.ivf",
"av1-1-b8-01-size-210x224.ivf",
"av1-1-b8-01-size-210x226.ivf",
"av1-1-b8-01-size-224x196.ivf",
"av1-1-b8-01-size-224x198.ivf",
"av1-1-b8-01-size-224x200.ivf",
"av1-1-b8-01-size-224x202.ivf",
"av1-1-b8-01-size-224x208.ivf",
"av1-1-b8-01-size-224x210.ivf",
"av1-1-b8-01-size-224x224.ivf",
"av1-1-b8-01-size-224x226.ivf",
"av1-1-b8-01-size-226x196.ivf",
"av1-1-b8-01-size-226x198.ivf",
"av1-1-b8-01-size-226x200.ivf",
"av1-1-b8-01-size-226x202.ivf",
"av1-1-b8-01-size-226x208.ivf",
"av1-1-b8-01-size-226x210.ivf",
"av1-1-b8-01-size-226x224.ivf",
"av1-1-b8-01-size-226x226.ivf",
"av1-1-b8-01-size-32x16.ivf",
"av1-1-b8-01-size-32x18.ivf",
"av1-1-b8-01-size-32x32.ivf",
"av1-1-b8-01-size-32x34.ivf",
"av1-1-b8-01-size-32x64.ivf",
"av1-1-b8-01-size-32x66.ivf",
"av1-1-b8-01-size-34x16.ivf",
"av1-1-b8-01-size-34x18.ivf",
"av1-1-b8-01-size-34x32.ivf",
"av1-1-b8-01-size-34x34.ivf",
"av1-1-b8-01-size-34x64.ivf",
"av1-1-b8-01-size-34x66.ivf",
"av1-1-b8-01-size-64x16.ivf",
"av1-1-b8-01-size-64x18.ivf",
"av1-1-b8-01-size-64x32.ivf",
"av1-1-b8-01-size-64x34.ivf",
"av1-1-b8-01-size-64x64.ivf",
"av1-1-b8-01-size-64x66.ivf",
"av1-1-b8-01-size-66x16.ivf",
"av1-1-b8-01-size-66x18.ivf",
"av1-1-b8-01-size-66x32.ivf",
"av1-1-b8-01-size-66x34.ivf",
"av1-1-b8-01-size-66x64.ivf",
"av1-1-b8-01-size-66x66.ivf",
"av1-1-b8-02-allintra.ivf",
"av1-1-b8-03-sizedown.mkv",
"av1-1-b8-03-sizeup.mkv",
"av1-1-b8-04-cdfupdate.ivf",
"av1-1-b8-05-mv.ivf",
"av1-1-b8-06-mfmv.ivf",
"av1-1-b8-22-svc-L1T2.ivf",
"av1-1-b8-22-svc-L2T1.ivf",
"av1-1-b8-22-svc-L2T2.ivf" };
const int kNumAV1TestVectors = NELEMENTS(kAV1TestVectors);
#endif // CONFIG_AV1_DECODER

View file

@ -703,6 +703,7 @@ class SubpelVarianceTest
protected:
void RefTest();
void ExtremeRefTest();
void SpeedTest();
ACMRandom rnd_;
uint8_t *src_;
@ -785,6 +786,41 @@ void SubpelVarianceTest<SubpelVarianceFunctionType>::ExtremeRefTest() {
}
}
template <typename SubpelVarianceFunctionType>
void SubpelVarianceTest<SubpelVarianceFunctionType>::SpeedTest() {
if (!use_high_bit_depth()) {
for (int j = 0; j < block_size(); j++) {
src_[j] = rnd_.Rand8();
}
for (int j = 0; j < block_size() + width() + height() + 1; j++) {
ref_[j] = rnd_.Rand8();
}
} else {
for (int j = 0; j < block_size(); j++) {
CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask();
}
for (int j = 0; j < block_size() + width() + height() + 1; j++) {
CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask();
}
}
unsigned int sse1;
int run_time = 1000000000 / block_size();
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_time; ++i) {
int x = rnd_(8);
int y = rnd_(8);
params_.func(ref_, width() + 1, x, y, src_, width(), &sse1);
}
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
printf("sub_pixel_variance_%dx%d_%d: %d us\n", width(), height(),
params_.bit_depth, elapsed_time);
}
template <>
void SubpelVarianceTest<SubpixAvgVarMxNFunc>::RefTest() {
for (int x = 0; x < 8; ++x) {
@ -1188,6 +1224,7 @@ TEST_P(AvxHBDVarianceTest, OneQuarter) { OneQuarterTest(); }
TEST_P(AvxHBDVarianceTest, DISABLED_Speed) { SpeedTest(); }
TEST_P(AvxHBDSubpelVarianceTest, Ref) { RefTest(); }
TEST_P(AvxHBDSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); }
TEST_P(AvxHBDSubpelVarianceTest, DISABLED_Speed) { SpeedTest(); }
TEST_P(AvxHBDSubpelAvgVarianceTest, Ref) { RefTest(); }
/* TODO(debargha): This test does not support the highbd version
@ -1677,6 +1714,9 @@ INSTANTIATE_TEST_CASE_P(AVX2, AvxHBDVarianceTest,
#endif // HAVE_AVX2
const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = {
SubpelVarianceParams(7, 7, &aom_highbd_12_sub_pixel_variance128x128_sse2, 12),
SubpelVarianceParams(7, 6, &aom_highbd_12_sub_pixel_variance128x64_sse2, 12),
SubpelVarianceParams(6, 7, &aom_highbd_12_sub_pixel_variance64x128_sse2, 12),
SubpelVarianceParams(6, 6, &aom_highbd_12_sub_pixel_variance64x64_sse2, 12),
SubpelVarianceParams(6, 5, &aom_highbd_12_sub_pixel_variance64x32_sse2, 12),
SubpelVarianceParams(5, 6, &aom_highbd_12_sub_pixel_variance32x64_sse2, 12),
@ -1688,6 +1728,9 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = {
SubpelVarianceParams(3, 4, &aom_highbd_12_sub_pixel_variance8x16_sse2, 12),
SubpelVarianceParams(3, 3, &aom_highbd_12_sub_pixel_variance8x8_sse2, 12),
SubpelVarianceParams(3, 2, &aom_highbd_12_sub_pixel_variance8x4_sse2, 12),
SubpelVarianceParams(7, 7, &aom_highbd_10_sub_pixel_variance128x128_sse2, 10),
SubpelVarianceParams(7, 6, &aom_highbd_10_sub_pixel_variance128x64_sse2, 10),
SubpelVarianceParams(6, 7, &aom_highbd_10_sub_pixel_variance64x128_sse2, 10),
SubpelVarianceParams(6, 6, &aom_highbd_10_sub_pixel_variance64x64_sse2, 10),
SubpelVarianceParams(6, 5, &aom_highbd_10_sub_pixel_variance64x32_sse2, 10),
SubpelVarianceParams(5, 6, &aom_highbd_10_sub_pixel_variance32x64_sse2, 10),
@ -1699,6 +1742,9 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = {
SubpelVarianceParams(3, 4, &aom_highbd_10_sub_pixel_variance8x16_sse2, 10),
SubpelVarianceParams(3, 3, &aom_highbd_10_sub_pixel_variance8x8_sse2, 10),
SubpelVarianceParams(3, 2, &aom_highbd_10_sub_pixel_variance8x4_sse2, 10),
SubpelVarianceParams(7, 7, &aom_highbd_8_sub_pixel_variance128x128_sse2, 8),
SubpelVarianceParams(7, 6, &aom_highbd_8_sub_pixel_variance128x64_sse2, 8),
SubpelVarianceParams(6, 7, &aom_highbd_8_sub_pixel_variance64x128_sse2, 8),
SubpelVarianceParams(6, 6, &aom_highbd_8_sub_pixel_variance64x64_sse2, 8),
SubpelVarianceParams(6, 5, &aom_highbd_8_sub_pixel_variance64x32_sse2, 8),
SubpelVarianceParams(5, 6, &aom_highbd_8_sub_pixel_variance32x64_sse2, 8),
@ -1711,7 +1757,6 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = {
SubpelVarianceParams(3, 3, &aom_highbd_8_sub_pixel_variance8x8_sse2, 8),
SubpelVarianceParams(3, 2, &aom_highbd_8_sub_pixel_variance8x4_sse2, 8)
};
INSTANTIATE_TEST_CASE_P(SSE2, AvxHBDSubpelVarianceTest,
::testing::ValuesIn(kArrayHBDSubpelVariance_sse2));

View file

@ -0,0 +1,726 @@
/*
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "config/av1_rtcd.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
#include "aom_ports/aom_timer.h"
#include "aom_ports/mem.h"
namespace {
using ::libaom_test::ACMRandom;
const int MAX_WIDTH = 32;
const int MAX_HEIGHT = 32;
typedef void (*YUVTemporalFilterFunc)(
const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre,
int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src,
int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre,
int uv_pre_stride, unsigned int block_width, unsigned int block_height,
int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32,
uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator,
uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count);
struct TemporalFilterWithBd {
TemporalFilterWithBd(YUVTemporalFilterFunc func, int bitdepth)
: temporal_filter(func), bd(bitdepth) {}
YUVTemporalFilterFunc temporal_filter;
int bd;
};
std::ostream &operator<<(std::ostream &os, const TemporalFilterWithBd &tf) {
return os << "Bitdepth: " << tf.bd;
}
int GetFilterWeight(unsigned int row, unsigned int col,
unsigned int block_height, unsigned int block_width,
const int *const blk_fw, int use_32x32) {
if (use_32x32) {
return blk_fw[0];
}
return blk_fw[2 * (row >= block_height / 2) + (col >= block_width / 2)];
}
template <typename PixelType>
int GetModIndex(int sum_dist, int index, int rounding, int strength,
int filter_weight) {
int mod = sum_dist * 3 / index;
mod += rounding;
mod >>= strength;
mod = AOMMIN(16, mod);
mod = 16 - mod;
mod *= filter_weight;
return mod;
}
// Lowbitdepth version
template <>
int GetModIndex<uint8_t>(int sum_dist, int index, int rounding, int strength,
int filter_weight) {
unsigned int index_mult[14] = {
0, 0, 0, 0, 49152, 39322, 32768, 28087, 24576, 21846, 19661, 17874, 0, 15124
};
assert(index >= 0 && index <= 13);
assert(index_mult[index] != 0);
int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16;
mod += rounding;
mod >>= strength;
mod = AOMMIN(16, mod);
mod = 16 - mod;
mod *= filter_weight;
return mod;
}
// Highbitdepth version
template <>
int GetModIndex<uint16_t>(int sum_dist, int index, int rounding, int strength,
int filter_weight) {
int64_t index_mult[14] = { 0U, 0U, 0U, 0U,
3221225472U, 2576980378U, 2147483648U, 1840700270U,
1610612736U, 1431655766U, 1288490189U, 1171354718U,
0U, 991146300U };
assert(index >= 0 && index <= 13);
assert(index_mult[index] != 0);
int mod = static_cast<int>((sum_dist * index_mult[index]) >> 32);
mod += rounding;
mod >>= strength;
mod = AOMMIN(16, mod);
mod = 16 - mod;
mod *= filter_weight;
return mod;
}
template <typename PixelType>
void SetArray(PixelType *pixel_array, int width, int height, int stride,
int val) {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
pixel_array[col] = val;
}
pixel_array += stride;
}
}
template <typename PixelType>
void SetArray(PixelType *pixel_array, int width, int height, int stride,
ACMRandom *rnd, int low_val, int high_val) {
EXPECT_LE(low_val, high_val);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
const int val =
static_cast<int>((*rnd).PseudoUniform(high_val - low_val));
pixel_array[col] = low_val + val;
}
pixel_array += stride;
}
}
template <typename ValueType>
bool CheckArrayEqual(const ValueType *arr_1, const ValueType *arr_2, int width,
int height, int stride_1, int stride_2) {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (arr_1[col] != arr_2[col]) {
return false;
}
}
arr_1 += stride_1;
arr_2 += stride_2;
}
return true;
}
template <typename ValueType>
void PrintArrayDiff(const ValueType *arr_1, const ValueType *arr_2, int width,
int height, int stride_1, int stride_2) {
const ValueType *arr_1_start = arr_1, *arr_2_start = arr_2;
printf("Array 1:\n");
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
if (arr_1[col] != arr_2[col]) {
printf("*%3d", arr_1[col]);
} else {
printf("%4d", arr_1[col]);
}
}
printf("\n");
arr_1 += stride_1;
arr_2 += stride_2;
}
arr_1 = arr_1_start;
arr_2 = arr_2_start;
printf("Array 2:\n");
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
if (arr_1[col] != arr_2[col]) {
printf("*%3d", arr_2[col]);
} else {
printf("%4d", arr_2[col]);
}
}
printf("\n");
arr_1 += stride_1;
arr_2 += stride_2;
}
arr_1 = arr_1_start;
arr_2 = arr_2_start;
printf("Difference:\n");
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
printf("%4d", arr_1[col] - arr_2[col]);
}
printf("\n");
arr_1 += stride_1;
arr_2 += stride_2;
}
}
template <typename PixelType>
void ApplyReferenceFilter(const PixelType *y_src, const PixelType *y_pre,
const PixelType *u_src, const PixelType *v_src,
const PixelType *u_pre, const PixelType *v_pre,
unsigned int block_width, unsigned int block_height,
int ss_x, int ss_y, int strength,
const int *const blk_fw, int use_32x32,
uint32_t *y_accum, uint16_t *y_count,
uint32_t *u_accum, uint16_t *u_count,
uint32_t *v_accum, uint16_t *v_count) {
const int uv_block_width = block_width >> ss_x,
uv_block_height = block_height >> ss_y;
const int y_src_stride = block_width, y_pre_stride = block_width;
const int uv_src_stride = uv_block_width, uv_pre_stride = uv_block_width;
const int y_diff_stride = block_width, uv_diff_stride = uv_block_width;
const int y_count_stride = block_width, u_count_stride = uv_block_width,
v_count_stride = uv_block_width;
const int y_accum_stride = block_width, u_accum_stride = uv_block_width,
v_accum_stride = uv_block_width;
int y_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 };
int u_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 };
int v_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 };
const int rounding = (1 << strength) >> 1;
// Get the square diffs
for (int row = 0; row < (int)block_height; row++) {
for (int col = 0; col < (int)block_width; col++) {
const int diff =
y_src[row * y_src_stride + col] - y_pre[row * y_pre_stride + col];
y_dif[row * y_diff_stride + col] = diff * diff;
}
}
for (int row = 0; row < (int)uv_block_height; row++) {
for (int col = 0; col < (int)uv_block_width; col++) {
const int u_diff =
u_src[row * uv_src_stride + col] - u_pre[row * uv_pre_stride + col];
const int v_diff =
v_src[row * uv_src_stride + col] - v_pre[row * uv_pre_stride + col];
u_dif[row * uv_diff_stride + col] = u_diff * u_diff;
v_dif[row * uv_diff_stride + col] = v_diff * v_diff;
}
}
// Apply the filter to luma
for (int row = 0; row < (int)block_height; row++) {
for (int col = 0; col < (int)block_width; col++) {
const int uv_row = row >> ss_y;
const int uv_col = col >> ss_x;
const int filter_weight = GetFilterWeight(row, col, block_height,
block_width, blk_fw, use_32x32);
// First we get the modifier for the current y pixel
const int y_pixel = y_pre[row * y_pre_stride + col];
int y_num_used = 0;
int y_mod = 0;
// Sum the neighboring 3x3 y pixels
for (int row_step = -1; row_step <= 1; row_step++) {
for (int col_step = -1; col_step <= 1; col_step++) {
const int sub_row = row + row_step;
const int sub_col = col + col_step;
if (sub_row >= 0 && sub_row < (int)block_height && sub_col >= 0 &&
sub_col < (int)block_width) {
y_mod += y_dif[sub_row * y_diff_stride + sub_col];
y_num_used++;
}
}
}
// Sum the corresponding uv pixels to the current y modifier
// Note we are rounding down instead of rounding to the nearest pixel.
y_mod += u_dif[uv_row * uv_diff_stride + uv_col];
y_mod += v_dif[uv_row * uv_diff_stride + uv_col];
y_num_used += 2;
// Set the modifier
y_mod = GetModIndex<PixelType>(y_mod, y_num_used, rounding, strength,
filter_weight);
// Accumulate the result
y_count[row * y_count_stride + col] += y_mod;
y_accum[row * y_accum_stride + col] += y_mod * y_pixel;
}
}
// Apply the filter to chroma
for (int uv_row = 0; uv_row < (int)uv_block_height; uv_row++) {
for (int uv_col = 0; uv_col < (int)uv_block_width; uv_col++) {
const int y_row = uv_row << ss_y;
const int y_col = uv_col << ss_x;
const int filter_weight = GetFilterWeight(
uv_row, uv_col, uv_block_height, uv_block_width, blk_fw, use_32x32);
const int u_pixel = u_pre[uv_row * uv_pre_stride + uv_col];
const int v_pixel = v_pre[uv_row * uv_pre_stride + uv_col];
int uv_num_used = 0;
int u_mod = 0, v_mod = 0;
// Sum the neighboring 3x3 chromal pixels to the chroma modifier
for (int row_step = -1; row_step <= 1; row_step++) {
for (int col_step = -1; col_step <= 1; col_step++) {
const int sub_row = uv_row + row_step;
const int sub_col = uv_col + col_step;
if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 &&
sub_col < uv_block_width) {
u_mod += u_dif[sub_row * uv_diff_stride + sub_col];
v_mod += v_dif[sub_row * uv_diff_stride + sub_col];
uv_num_used++;
}
}
}
// Sum all the luma pixels associated with the current luma pixel
for (int row_step = 0; row_step < 1 + ss_y; row_step++) {
for (int col_step = 0; col_step < 1 + ss_x; col_step++) {
const int sub_row = y_row + row_step;
const int sub_col = y_col + col_step;
const int y_diff = y_dif[sub_row * y_diff_stride + sub_col];
u_mod += y_diff;
v_mod += y_diff;
uv_num_used++;
}
}
// Set the modifier
u_mod = GetModIndex<PixelType>(u_mod, uv_num_used, rounding, strength,
filter_weight);
v_mod = GetModIndex<PixelType>(v_mod, uv_num_used, rounding, strength,
filter_weight);
// Accumulate the result
u_count[uv_row * u_count_stride + uv_col] += u_mod;
u_accum[uv_row * u_accum_stride + uv_col] += u_mod * u_pixel;
v_count[uv_row * v_count_stride + uv_col] += v_mod;
v_accum[uv_row * v_accum_stride + uv_col] += v_mod * v_pixel;
}
}
}
class YUVTemporalFilterTest
: public ::testing::TestWithParam<TemporalFilterWithBd> {
public:
virtual void SetUp() {
filter_func_ = GetParam().temporal_filter;
bd_ = GetParam().bd;
use_highbd_ = (bd_ != 8);
rnd_.Reset(ACMRandom::DeterministicSeed());
saturate_test_ = 0;
num_repeats_ = 10;
ASSERT_TRUE(bd_ == 8 || bd_ == 10 || bd_ == 12);
}
protected:
template <typename PixelType>
void CompareTestWithParam(int width, int height, int ss_x, int ss_y,
int filter_strength, int use_32x32,
const int *filter_weight);
template <typename PixelType>
void RunTestFilterWithParam(int width, int height, int ss_x, int ss_y,
int filter_strength, int use_32x32,
const int *filter_weight);
template <typename PixelType>
void ApplyTestFilter(const PixelType *y_src, int y_src_stride,
const PixelType *y_pre, int y_pre_stride,
const PixelType *u_src, const PixelType *v_src,
int uv_src_stride, const PixelType *u_pre,
const PixelType *v_pre, int uv_pre_stride,
unsigned int block_width, unsigned int block_height,
int ss_x, int ss_y, int strength, const int *blk_fw,
int use_32x32, uint32_t *y_accum, uint16_t *y_count,
uint32_t *u_accumu, uint16_t *u_count, uint32_t *v_accum,
uint16_t *v_count);
YUVTemporalFilterFunc filter_func_;
ACMRandom rnd_;
int saturate_test_;
int num_repeats_;
int use_highbd_;
int bd_;
};
template <>
void YUVTemporalFilterTest::ApplyTestFilter<uint8_t>(
const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre,
int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src,
int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre,
int uv_pre_stride, unsigned int block_width, unsigned int block_height,
int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32,
uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, uint16_t *u_count,
uint32_t *v_accum, uint16_t *v_count) {
ASM_REGISTER_STATE_CHECK(
filter_func_(y_src, y_src_stride, y_pre, y_pre_stride, u_src, v_src,
uv_src_stride, u_pre, v_pre, uv_pre_stride, block_width,
block_height, ss_x, ss_y, strength, blk_fw, use_32x32,
y_accum, y_count, u_accum, u_count, v_accum, v_count));
}
template <>
void YUVTemporalFilterTest::ApplyTestFilter<uint16_t>(
const uint16_t *y_src, int y_src_stride, const uint16_t *y_pre,
int y_pre_stride, const uint16_t *u_src, const uint16_t *v_src,
int uv_src_stride, const uint16_t *u_pre, const uint16_t *v_pre,
int uv_pre_stride, unsigned int block_width, unsigned int block_height,
int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32,
uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, uint16_t *u_count,
uint32_t *v_accum, uint16_t *v_count) {
ASM_REGISTER_STATE_CHECK(filter_func_(
CONVERT_TO_BYTEPTR(y_src), y_src_stride, CONVERT_TO_BYTEPTR(y_pre),
y_pre_stride, CONVERT_TO_BYTEPTR(u_src), CONVERT_TO_BYTEPTR(v_src),
uv_src_stride, CONVERT_TO_BYTEPTR(u_pre), CONVERT_TO_BYTEPTR(v_pre),
uv_pre_stride, block_width, block_height, ss_x, ss_y, strength, blk_fw,
use_32x32, y_accum, y_count, u_accum, u_count, v_accum, v_count));
}
template <typename PixelType>
void YUVTemporalFilterTest::CompareTestWithParam(int width, int height,
int ss_x, int ss_y,
int filter_strength,
int use_32x32,
const int *filter_weight) {
const int uv_width = width >> ss_x, uv_height = height >> ss_y;
const int y_stride = width, uv_stride = uv_width;
DECLARE_ALIGNED(16, PixelType, y_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, PixelType, y_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, y_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, y_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, y_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, y_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, PixelType, u_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, PixelType, u_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, u_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, u_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, u_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, u_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, PixelType, v_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, PixelType, v_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, v_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, v_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint16_t, v_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
DECLARE_ALIGNED(16, uint32_t, v_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 };
for (int repeats = 0; repeats < num_repeats_; repeats++) {
if (saturate_test_) {
const int max_val = (1 << bd_) - 1;
SetArray(y_src, width, height, y_stride, max_val);
SetArray(y_pre, width, height, y_stride, 0);
SetArray(u_src, uv_width, uv_height, uv_stride, max_val);
SetArray(u_pre, uv_width, uv_height, uv_stride, 0);
SetArray(v_src, uv_width, uv_height, uv_stride, max_val);
SetArray(v_pre, uv_width, uv_height, uv_stride, 0);
} else {
const int max_val = 7 << (bd_ - 8);
SetArray(y_src, width, height, y_stride, &rnd_, 0, max_val);
SetArray(y_pre, width, height, y_stride, &rnd_, 0, max_val);
SetArray(u_src, uv_width, uv_height, uv_stride, &rnd_, 0, max_val);
SetArray(u_pre, uv_width, uv_height, uv_stride, &rnd_, 0, max_val);
SetArray(v_src, uv_width, uv_height, uv_stride, &rnd_, 0, max_val);
SetArray(v_pre, uv_width, uv_height, uv_stride, &rnd_, 0, max_val);
}
ApplyReferenceFilter<PixelType>(
y_src, y_pre, u_src, v_src, u_pre, v_pre, width, height, ss_x, ss_y,
filter_strength, filter_weight, use_32x32, y_accum_ref, y_count_ref,
u_accum_ref, u_count_ref, v_accum_ref, v_count_ref);
ApplyTestFilter(y_src, y_stride, y_pre, y_stride, u_src, v_src, uv_stride,
u_pre, v_pre, uv_stride, width, height, ss_x, ss_y,
filter_strength, filter_weight, use_32x32, y_accum_tst,
y_count_tst, u_accum_tst, u_count_tst, v_accum_tst,
v_count_tst);
EXPECT_TRUE(CheckArrayEqual(y_accum_tst, y_accum_ref, width, height,
y_stride, y_stride));
EXPECT_TRUE(CheckArrayEqual(y_count_tst, y_count_ref, width, height,
y_stride, y_stride));
EXPECT_TRUE(CheckArrayEqual(u_accum_tst, u_accum_ref, uv_width, uv_height,
uv_stride, uv_stride));
EXPECT_TRUE(CheckArrayEqual(u_count_tst, u_count_ref, uv_width, uv_height,
uv_stride, uv_stride));
EXPECT_TRUE(CheckArrayEqual(v_accum_tst, v_accum_ref, uv_width, uv_height,
uv_stride, uv_stride));
EXPECT_TRUE(CheckArrayEqual(v_count_tst, v_count_ref, uv_width, uv_height,
uv_stride, uv_stride));
if (HasFailure()) {
if (use_32x32) {
printf("SS_X: %d, SS_Y: %d, Strength: %d, Weight: %d\n", ss_x, ss_y,
filter_strength, *filter_weight);
} else {
printf("SS_X: %d, SS_Y: %d, Strength: %d, Weights: %d,%d,%d,%d\n", ss_x,
ss_y, filter_strength, filter_weight[0], filter_weight[1],
filter_weight[2], filter_weight[3]);
}
PrintArrayDiff(y_accum_ref, y_accum_tst, width, height, y_stride,
y_stride);
PrintArrayDiff(y_count_ref, y_count_tst, width, height, y_stride,
y_stride);
PrintArrayDiff(u_accum_ref, v_accum_tst, uv_width, uv_height, uv_stride,
uv_stride);
PrintArrayDiff(u_count_ref, v_count_tst, uv_width, uv_height, uv_stride,
uv_stride);
PrintArrayDiff(u_accum_ref, v_accum_tst, uv_width, uv_height, uv_stride,
uv_stride);
PrintArrayDiff(u_count_ref, v_count_tst, uv_width, uv_height, uv_stride,
uv_stride);
return;
}
}
}
template <typename PixelType>
void YUVTemporalFilterTest::RunTestFilterWithParam(int width, int height,
int ss_x, int ss_y,
int filter_strength,
int use_32x32,
const int *filter_weight) {
PixelType y_src[MAX_WIDTH * MAX_HEIGHT] = { 0 };
PixelType y_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint16_t y_count[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint32_t y_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 };
PixelType u_src[MAX_WIDTH * MAX_HEIGHT] = { 0 };
PixelType u_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint16_t u_count[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint32_t u_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 };
PixelType v_src[MAX_WIDTH * MAX_HEIGHT] = { 0 };
PixelType v_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint16_t v_count[MAX_WIDTH * MAX_HEIGHT] = { 0 };
uint32_t v_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 };
SetArray(y_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
SetArray(y_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
SetArray(u_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
SetArray(u_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
SetArray(v_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
SetArray(v_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8));
for (int repeats = 0; repeats < num_repeats_; repeats++) {
ApplyTestFilter(y_src, MAX_WIDTH, y_pre, MAX_WIDTH, u_src, v_src, MAX_WIDTH,
u_pre, v_pre, MAX_WIDTH, width, height, ss_x, ss_y,
filter_strength, filter_weight, use_32x32, y_accum, y_count,
u_accum, u_count, v_accum, v_count);
}
}
TEST_P(YUVTemporalFilterTest, Use32x32) {
const int width = 32, height = 32;
const int use_32x32 = 1;
for (int ss_x = 0; ss_x <= 1; ss_x++) {
for (int ss_y = 0; ss_y <= 1; ss_y++) {
for (int filter_strength = 0; filter_strength <= 6;
filter_strength += 2) {
for (int filter_weight = 0; filter_weight <= 2; filter_weight++) {
if (use_highbd_) {
const int adjusted_strength = filter_strength + 2 * (bd_ - 8);
CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y,
adjusted_strength, use_32x32,
&filter_weight);
} else {
CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y,
filter_strength, use_32x32,
&filter_weight);
}
ASSERT_FALSE(HasFailure());
}
}
}
}
}
TEST_P(YUVTemporalFilterTest, Use16x16) {
const int width = 32, height = 32;
const int use_32x32 = 0;
for (int ss_x = 0; ss_x <= 1; ss_x++) {
for (int ss_y = 0; ss_y <= 1; ss_y++) {
for (int filter_idx = 0; filter_idx < 3 * 3 * 3 * 3; filter_idx++) {
// Set up the filter
int filter_weight[4];
int filter_idx_cp = filter_idx;
for (int idx = 0; idx < 4; idx++) {
filter_weight[idx] = filter_idx_cp % 3;
filter_idx_cp /= 3;
}
// Test each parameter
for (int filter_strength = 0; filter_strength <= 6;
filter_strength += 2) {
if (use_highbd_) {
const int adjusted_strength = filter_strength + 2 * (bd_ - 8);
CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y,
adjusted_strength, use_32x32,
filter_weight);
} else {
CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y,
filter_strength, use_32x32,
filter_weight);
}
ASSERT_FALSE(HasFailure());
}
}
}
}
}
TEST_P(YUVTemporalFilterTest, SaturationTest) {
const int width = 32, height = 32;
const int use_32x32 = 1;
const int filter_weight = 1;
saturate_test_ = 1;
for (int ss_x = 0; ss_x <= 1; ss_x++) {
for (int ss_y = 0; ss_y <= 1; ss_y++) {
for (int filter_strength = 0; filter_strength <= 6;
filter_strength += 2) {
if (use_highbd_) {
const int adjusted_strength = filter_strength + 2 * (bd_ - 8);
CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y,
adjusted_strength, use_32x32,
&filter_weight);
} else {
CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y,
filter_strength, use_32x32,
&filter_weight);
}
ASSERT_FALSE(HasFailure());
}
}
}
}
TEST_P(YUVTemporalFilterTest, DISABLED_Speed) {
const int width = 32, height = 32;
num_repeats_ = 1000;
for (int use_32x32 = 0; use_32x32 <= 1; use_32x32++) {
const int num_filter_weights = use_32x32 ? 3 : 3 * 3 * 3 * 3;
for (int ss_x = 0; ss_x <= 1; ss_x++) {
for (int ss_y = 0; ss_y <= 1; ss_y++) {
for (int filter_idx = 0; filter_idx < num_filter_weights;
filter_idx++) {
// Set up the filter
int filter_weight[4];
int filter_idx_cp = filter_idx;
for (int idx = 0; idx < 4; idx++) {
filter_weight[idx] = filter_idx_cp % 3;
filter_idx_cp /= 3;
}
// Test each parameter
for (int filter_strength = 0; filter_strength <= 6;
filter_strength += 2) {
aom_usec_timer timer;
aom_usec_timer_start(&timer);
if (use_highbd_) {
RunTestFilterWithParam<uint16_t>(width, height, ss_x, ss_y,
filter_strength, use_32x32,
filter_weight);
} else {
RunTestFilterWithParam<uint8_t>(width, height, ss_x, ss_y,
filter_strength, use_32x32,
filter_weight);
}
aom_usec_timer_mark(&timer);
const int elapsed_time =
static_cast<int>(aom_usec_timer_elapsed(&timer));
printf(
"Bitdepth: %d, Use 32X32: %d, SS_X: %d, SS_Y: %d, Weight Idx: "
"%d, Strength: %d, Time: %5d\n",
bd_, use_32x32, ss_x, ss_y, filter_idx, filter_strength,
elapsed_time);
}
}
}
}
}
}
INSTANTIATE_TEST_CASE_P(
C, YUVTemporalFilterTest,
::testing::Values(
TemporalFilterWithBd(&av1_apply_temporal_filter_c, 8),
TemporalFilterWithBd(&av1_highbd_apply_temporal_filter_c, 10),
TemporalFilterWithBd(&av1_highbd_apply_temporal_filter_c, 12)));
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
SSE4_1, YUVTemporalFilterTest,
::testing::Values(
TemporalFilterWithBd(&av1_apply_temporal_filter_sse4_1, 8),
TemporalFilterWithBd(&av1_highbd_apply_temporal_filter_sse4_1, 10),
TemporalFilterWithBd(&av1_highbd_apply_temporal_filter_sse4_1, 12)));
#endif // HAVE_SSE4_1
} // namespace