Update libaom to commit ID 1e227d41f0616de9548a673a83a21ef990b62591

This commit is contained in:
trav90 2018-10-19 23:05:00 -05:00 committed by Roy Tam
commit 368651059a
526 changed files with 34535 additions and 15900 deletions

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_ACM_RANDOM_H_
#define TEST_ACM_RANDOM_H_
#ifndef AOM_TEST_ACM_RANDOM_H_
#define AOM_TEST_ACM_RANDOM_H_
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
@ -81,4 +81,4 @@ class ACMRandom {
} // namespace libaom_test
#endif // TEST_ACM_RANDOM_H_
#endif // AOM_TEST_ACM_RANDOM_H_

164
third_party/aom/test/av1_config_test.cc vendored Normal file
View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2018, 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 <string.h>
#include "common/av1_config.h"
#include "test/util.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
namespace {
//
// Input buffers containing exactly one Sequence Header OBU.
//
// Each buffer is named according to the OBU storage format (Annex-B vs Low
// Overhead Bitstream Format) and the type of Sequence Header OBU ("Full"
// Sequence Header OBUs vs Sequence Header OBUs with the
// reduced_still_image_flag set).
//
const uint8_t kAnnexBFullSequenceHeaderObu[] = {
0x0c, 0x08, 0x00, 0x00, 0x00, 0x04, 0x45, 0x7e, 0x3e, 0xff, 0xfc, 0xc0, 0x20
};
const uint8_t kAnnexBReducedStillImageSequenceHeaderObu[] = {
0x08, 0x08, 0x18, 0x22, 0x2b, 0xf1, 0xfe, 0xc0, 0x20
};
const uint8_t kLobfFullSequenceHeaderObu[] = {
0x0a, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x45, 0x7e, 0x3e, 0xff, 0xfc, 0xc0, 0x20
};
const uint8_t kLobfReducedStillImageSequenceHeaderObu[] = {
0x0a, 0x07, 0x18, 0x22, 0x2b, 0xf1, 0xfe, 0xc0, 0x20
};
const uint8_t kAv1cAllZero[] = { 0, 0, 0, 0 };
// The size of AV1 config when no configOBUs are present at the end of the
// configuration structure.
const size_t kAv1cNoConfigObusSize = 4;
bool VerifyAv1c(const uint8_t *const obu_buffer, size_t obu_buffer_length,
bool is_annexb) {
Av1Config av1_config;
memset(&av1_config, 0, sizeof(av1_config));
bool parse_ok = get_av1config_from_obu(obu_buffer, obu_buffer_length,
is_annexb, &av1_config) == 0;
if (parse_ok) {
EXPECT_EQ(1, av1_config.marker);
EXPECT_EQ(1, av1_config.version);
EXPECT_EQ(0, av1_config.seq_profile);
EXPECT_EQ(0, av1_config.seq_level_idx_0);
EXPECT_EQ(0, av1_config.seq_tier_0);
EXPECT_EQ(0, av1_config.high_bitdepth);
EXPECT_EQ(0, av1_config.twelve_bit);
EXPECT_EQ(0, av1_config.monochrome);
EXPECT_EQ(1, av1_config.chroma_subsampling_x);
EXPECT_EQ(1, av1_config.chroma_subsampling_y);
EXPECT_EQ(0, av1_config.chroma_sample_position);
EXPECT_EQ(0, av1_config.initial_presentation_delay_present);
EXPECT_EQ(0, av1_config.initial_presentation_delay_minus_one);
}
return parse_ok && ::testing::Test::HasFailure() == false;
}
TEST(Av1Config, ObuInvalidInputs) {
Av1Config av1_config;
memset(&av1_config, 0, sizeof(av1_config));
ASSERT_EQ(-1, get_av1config_from_obu(NULL, 0, 0, NULL));
ASSERT_EQ(-1,
get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0, NULL));
ASSERT_EQ(
-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0],
sizeof(kLobfFullSequenceHeaderObu), 0, NULL));
ASSERT_EQ(-1, get_av1config_from_obu(NULL, sizeof(kLobfFullSequenceHeaderObu),
0, NULL));
ASSERT_EQ(-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0,
&av1_config));
}
TEST(Av1Config, ReadInvalidInputs) {
Av1Config av1_config;
memset(&av1_config, 0, sizeof(av1_config));
size_t bytes_read = 0;
ASSERT_EQ(-1, read_av1config(NULL, 0, NULL, NULL));
ASSERT_EQ(-1, read_av1config(NULL, 4, NULL, NULL));
ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 0, NULL, NULL));
ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 4, &bytes_read, NULL));
ASSERT_EQ(-1, read_av1config(NULL, 4, &bytes_read, &av1_config));
}
TEST(Av1Config, WriteInvalidInputs) {
Av1Config av1_config;
memset(&av1_config, 0, sizeof(av1_config));
size_t bytes_written = 0;
uint8_t av1c_buffer[4] = { 0 };
ASSERT_EQ(-1, write_av1config(NULL, 0, NULL, NULL));
ASSERT_EQ(-1, write_av1config(&av1_config, 0, NULL, NULL));
ASSERT_EQ(-1, write_av1config(&av1_config, 0, &bytes_written, NULL));
ASSERT_EQ(-1,
write_av1config(&av1_config, 0, &bytes_written, &av1c_buffer[0]));
ASSERT_EQ(-1, write_av1config(&av1_config, 4, &bytes_written, NULL));
}
TEST(Av1Config, GetAv1ConfigFromLobfObu) {
// Test parsing of a Sequence Header OBU with the reduced_still_picture_header
// unset-- aka a full Sequence Header OBU.
ASSERT_TRUE(VerifyAv1c(kLobfFullSequenceHeaderObu,
sizeof(kLobfFullSequenceHeaderObu), false));
// Test parsing of a reduced still image Sequence Header OBU.
ASSERT_TRUE(VerifyAv1c(kLobfReducedStillImageSequenceHeaderObu,
sizeof(kLobfReducedStillImageSequenceHeaderObu),
false));
}
TEST(Av1Config, GetAv1ConfigFromAnnexBObu) {
// Test parsing of a Sequence Header OBU with the reduced_still_picture_header
// unset-- aka a full Sequence Header OBU.
ASSERT_TRUE(VerifyAv1c(kAnnexBFullSequenceHeaderObu,
sizeof(kAnnexBFullSequenceHeaderObu), true));
// Test parsing of a reduced still image Sequence Header OBU.
ASSERT_TRUE(VerifyAv1c(kAnnexBReducedStillImageSequenceHeaderObu,
sizeof(kAnnexBReducedStillImageSequenceHeaderObu),
true));
}
TEST(Av1Config, ReadWriteConfig) {
Av1Config av1_config;
memset(&av1_config, 0, sizeof(av1_config));
// Test writing out the AV1 config.
size_t bytes_written = 0;
uint8_t av1c_buffer[4] = { 0 };
ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
&av1c_buffer[0]));
ASSERT_EQ(kAv1cNoConfigObusSize, bytes_written);
for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
<< "Mismatch in output Av1Config at offset=" << i;
}
// Test reading the AV1 config.
size_t bytes_read = 0;
ASSERT_EQ(0, read_av1config(&kAv1cAllZero[0], sizeof(kAv1cAllZero),
&bytes_read, &av1_config));
ASSERT_EQ(kAv1cNoConfigObusSize, bytes_read);
ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
&av1c_buffer[0]));
for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
<< "Mismatch in output Av1Config at offset=" << i;
}
}
} // namespace

View file

@ -71,9 +71,9 @@ void AV1Convolve2DSrTest::RunCheckOutput(convolve_2d_func test_impl) {
out_h);
for (int do_average = 0; do_average < 1; ++do_average) {
ConvolveParams conv_params1 =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, 8);
ConvolveParams conv_params2 =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, 8);
const int subx_range = has_subx ? 16 : 1;
const int suby_range = has_suby ? 16 : 1;
@ -126,7 +126,7 @@ void AV1Convolve2DSrTest::RunSpeedTest(convolve_2d_func test_impl) {
const int do_average = 0;
ConvolveParams conv_params2 =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, 8);
// Make sure that sizes 2xN and Nx2 are also tested for chroma.
const int num_sizes =
@ -195,10 +195,10 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) {
av1_get_interp_filter_params_with_block_size((InterpFilter)vfilter,
out_h);
for (int do_average = 0; do_average <= 1; ++do_average) {
ConvolveParams conv_params1 = get_conv_params_no_round(
0, do_average, 0, output1, MAX_SB_SIZE, 1, 8);
ConvolveParams conv_params2 = get_conv_params_no_round(
0, do_average, 0, output2, MAX_SB_SIZE, 1, 8);
ConvolveParams conv_params1 =
get_conv_params_no_round(do_average, 0, output1, MAX_SB_SIZE, 1, 8);
ConvolveParams conv_params2 =
get_conv_params_no_round(do_average, 0, output2, MAX_SB_SIZE, 1, 8);
// Test special case where jnt_comp_avg is not used
conv_params1.use_jnt_comp_avg = 0;
@ -331,7 +331,7 @@ void AV1JntConvolve2DTest::RunSpeedTest(convolve_2d_func test_impl) {
out_h);
ConvolveParams conv_params =
get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE, 1, 8);
get_conv_params_no_round(do_average, 0, output, MAX_SB_SIZE, 1, 8);
conv_params.use_jnt_comp_avg = 0;
@ -395,7 +395,7 @@ void AV1HighbdConvolve2DSrTest::RunSpeedTest(
suby = 0;
ConvolveParams conv_params =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, bd);
// Make sure that sizes 2xN and Nx2 are also tested for chroma.
const int num_sizes =
@ -464,9 +464,9 @@ void AV1HighbdConvolve2DSrTest::RunCheckOutput(
out_h);
for (int do_average = 0; do_average < 1; ++do_average) {
ConvolveParams conv_params1 =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, bd);
ConvolveParams conv_params2 =
get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
get_conv_params_no_round(do_average, 0, NULL, 0, 0, bd);
const int subx_range = has_subx ? 16 : 1;
const int suby_range = has_suby ? 16 : 1;
@ -538,7 +538,7 @@ void AV1HighbdJntConvolve2DTest::RunSpeedTest(
out_h);
ConvolveParams conv_params =
get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE, 1, bd);
get_conv_params_no_round(do_average, 0, output, MAX_SB_SIZE, 1, bd);
// Test special case where jnt_comp_avg is not used
conv_params.use_jnt_comp_avg = 0;
@ -597,9 +597,9 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput(
out_h);
for (int do_average = 0; do_average <= 1; ++do_average) {
ConvolveParams conv_params1 = get_conv_params_no_round(
0, do_average, 0, output1, MAX_SB_SIZE, 1, bd);
do_average, 0, output1, MAX_SB_SIZE, 1, bd);
ConvolveParams conv_params2 = get_conv_params_no_round(
0, do_average, 0, output2, MAX_SB_SIZE, 1, bd);
do_average, 0, output2, MAX_SB_SIZE, 1, bd);
// Test special case where jnt_comp_avg is not used
conv_params1.use_jnt_comp_avg = 0;

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#define TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#ifndef AOM_TEST_AV1_CONVOLVE_2D_TEST_UTIL_H_
#define AOM_TEST_AV1_CONVOLVE_2D_TEST_UTIL_H_
#include "config/av1_rtcd.h"
#include "config/aom_dsp_rtcd.h"
@ -114,4 +114,4 @@ class AV1HighbdJntConvolve2DTest
} // namespace libaom_test
#endif // TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#endif // AOM_TEST_AV1_CONVOLVE_2D_TEST_UTIL_H_

View file

@ -279,7 +279,7 @@ class ConvolveScaleTestBase : public ::testing::Test {
filter_x_.set(ntaps_x_, false);
filter_y_.set(ntaps_y_, true);
convolve_params_ =
get_conv_params_no_round(0, avg_ != false, 0, NULL, 0, 1, bd);
get_conv_params_no_round(avg_ != false, 0, NULL, 0, 1, bd);
delete image_;
image_ = new TestImage<SrcPixel>(width_, height_, bd_);

View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2018, 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/util.h"
#include "test/y4m_video_source.h"
#include "aom/aom_decoder.h"
#include "av1/decoder/decoder.h"
namespace {
const int kMaxPsnr = 100;
struct ParamPassingTestVideo {
const char *name;
uint32_t width;
uint32_t height;
uint32_t bitrate;
int frames;
};
const ParamPassingTestVideo kAV1ParamPassingTestVector = {
"niklas_1280_720_30.y4m", 1280, 720, 600, 3
};
struct EncodeParameters {
int32_t lossless;
aom_color_primaries_t color_primaries;
aom_transfer_characteristics_t transfer_characteristics;
aom_matrix_coefficients_t matrix_coefficients;
aom_color_range_t color_range;
aom_chroma_sample_position_t chroma_sample_position;
int32_t render_size[2];
};
const EncodeParameters kAV1EncodeParameterSet[] = {
{ 1,
AOM_CICP_CP_BT_709,
AOM_CICP_TC_BT_709,
AOM_CICP_MC_BT_709,
AOM_CR_STUDIO_RANGE,
AOM_CSP_UNKNOWN,
{ 0, 0 } },
{ 0,
AOM_CICP_CP_BT_470_M,
AOM_CICP_TC_BT_470_M,
AOM_CICP_MC_BT_470_B_G,
AOM_CR_FULL_RANGE,
AOM_CSP_VERTICAL,
{ 0, 0 } },
{ 1,
AOM_CICP_CP_BT_601,
AOM_CICP_TC_BT_601,
AOM_CICP_MC_BT_601,
AOM_CR_STUDIO_RANGE,
AOM_CSP_COLOCATED,
{ 0, 0 } },
{ 0,
AOM_CICP_CP_BT_2020,
AOM_CICP_TC_BT_2020_10_BIT,
AOM_CICP_MC_BT_2020_NCL,
AOM_CR_FULL_RANGE,
AOM_CSP_RESERVED,
{ 640, 480 } },
};
class AVxEncoderParmsGetToDecoder
: public ::libaom_test::EncoderTest,
public ::libaom_test::CodecTestWithParam<EncodeParameters> {
protected:
AVxEncoderParmsGetToDecoder()
: EncoderTest(GET_PARAM(0)), encode_parms(GET_PARAM(1)) {}
virtual ~AVxEncoderParmsGetToDecoder() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libaom_test::kTwoPassGood);
cfg_.g_lag_in_frames = 25;
test_video_ = kAV1ParamPassingTestVector;
cfg_.rc_target_bitrate = test_video_.bitrate;
}
virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(AV1E_SET_COLOR_PRIMARIES, encode_parms.color_primaries);
encoder->Control(AV1E_SET_TRANSFER_CHARACTERISTICS,
encode_parms.transfer_characteristics);
encoder->Control(AV1E_SET_MATRIX_COEFFICIENTS,
encode_parms.matrix_coefficients);
encoder->Control(AV1E_SET_COLOR_RANGE, encode_parms.color_range);
encoder->Control(AV1E_SET_CHROMA_SAMPLE_POSITION,
encode_parms.chroma_sample_position);
encoder->Control(AV1E_SET_LOSSLESS, encode_parms.lossless);
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) {
encoder->Control(AV1E_SET_RENDER_SIZE, encode_parms.render_size);
}
}
}
virtual void DecompressedFrameHook(const aom_image_t &img,
aom_codec_pts_t pts) {
(void)pts;
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) {
EXPECT_EQ(encode_parms.render_size[0], (int)img.r_w);
EXPECT_EQ(encode_parms.render_size[1], (int)img.r_h);
}
EXPECT_EQ(encode_parms.color_primaries, img.cp);
EXPECT_EQ(encode_parms.transfer_characteristics, img.tc);
EXPECT_EQ(encode_parms.matrix_coefficients, img.mc);
EXPECT_EQ(encode_parms.color_range, img.range);
EXPECT_EQ(encode_parms.chroma_sample_position, img.csp);
}
virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
if (encode_parms.lossless) {
EXPECT_EQ(kMaxPsnr, pkt->data.psnr.psnr[0]);
}
}
virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
libaom_test::Decoder *decoder) {
EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
return AOM_CODEC_OK == res_dec;
}
ParamPassingTestVideo test_video_;
private:
EncodeParameters encode_parms;
};
TEST_P(AVxEncoderParmsGetToDecoder, BitstreamParms) {
init_flags_ = AOM_CODEC_USE_PSNR;
testing::internal::scoped_ptr<libaom_test::VideoSource> video(
new libaom_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames));
ASSERT_TRUE(video.get() != NULL);
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
}
AV1_INSTANTIATE_TEST_CASE(AVxEncoderParmsGetToDecoder,
::testing::ValuesIn(kAV1EncodeParameterSet));
} // namespace

View file

@ -20,6 +20,7 @@
#include "test/util.h"
#include "test/av1_txfm_test.h"
#include "av1/common/av1_txfm.h"
#include "av1/encoder/hybrid_fwd_txfm.h"
using libaom_test::ACMRandom;
using libaom_test::TYPE_TXFM;
@ -351,4 +352,160 @@ INSTANTIATE_TEST_CASE_P(AVX2, AV1FwdTxfm2dTest,
Combine(ValuesIn(fwd_txfm_for_avx2),
Values(av1_lowbd_fwd_txfm_avx2)));
#endif // HAVE_AVX2
typedef void (*Highbd_fwd_txfm_func)(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param);
void AV1HighbdFwdTxfm2dMatchTest(TX_SIZE tx_size,
Highbd_fwd_txfm_func target_func) {
const int bd_ar[2] = { 10, 12 };
TxfmParam param;
memset(&param, 0, sizeof(param));
const int rows = tx_size_high[tx_size];
const int cols = tx_size_wide[tx_size];
for (int i = 0; i < 2; ++i) {
const int bd = bd_ar[i];
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 cnt = 0; cnt < 500; ++cnt) {
if (cnt == 0) {
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
input[r * input_stride + c] = (1 << bd) - 1;
}
}
} else {
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;
ref_func(input, ref_output, input_stride, (TX_TYPE)tx_type, bd);
target_func(input, output, input_stride, &param);
const int check_rows = AOMMIN(32, rows);
const int check_cols = AOMMIN(32, rows * cols / check_rows);
for (int r = 0; r < check_rows; ++r) {
for (int c = 0; c < check_cols; ++c) {
ASSERT_EQ(ref_output[r * check_cols + c],
output[r * check_cols + c])
<< "[" << r << "," << c << "] cnt:" << cnt
<< " tx_size: " << tx_size << " tx_type: " << tx_type;
}
}
}
}
}
}
}
void AV1HighbdFwdTxfm2dSpeedTest(TX_SIZE tx_size,
Highbd_fwd_txfm_func target_func) {
const int bd_ar[2] = { 10, 12 };
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 = bd_ar[i];
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, Highbd_fwd_txfm_func> HighbdFwdTxfm2dParam;
class AV1HighbdFwdTxfm2dTest
: public ::testing::TestWithParam<HighbdFwdTxfm2dParam> {};
TEST_P(AV1HighbdFwdTxfm2dTest, match) {
AV1HighbdFwdTxfm2dMatchTest(GET_PARAM(0), GET_PARAM(1));
}
TEST_P(AV1HighbdFwdTxfm2dTest, DISABLED_Speed) {
AV1HighbdFwdTxfm2dSpeedTest(GET_PARAM(0), GET_PARAM(1));
}
using ::testing::Combine;
using ::testing::Values;
using ::testing::ValuesIn;
#if HAVE_SSE4_1
static TX_SIZE Highbd_fwd_txfm_for_sse4_1[] = {
TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_64X64, TX_4X8, TX_8X4,
TX_8X16, TX_16X8, TX_16X32, TX_32X16, TX_32X64, TX_64X32, TX_4X16,
TX_16X4, TX_8X32, TX_32X8, TX_16X64, TX_64X16,
};
INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdFwdTxfm2dTest,
Combine(ValuesIn(Highbd_fwd_txfm_for_sse4_1),
Values(av1_highbd_fwd_txfm)));
#endif // HAVE_SSE4_1
} // namespace

View file

@ -14,10 +14,12 @@
#include "config/av1_rtcd.h"
#include "test/acm_random.h"
#include "test/av1_txfm_test.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "av1/common/enums.h"
#include "av1/common/scan.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_ports/mem.h"
@ -142,55 +144,8 @@ using ::testing::make_tuple;
#define PARAM_LIST_4X4 \
&av1_fwd_txfm2d_4x4_c, &av1_inv_txfm2d_add_4x4_sse4_1, \
&av1_inv_txfm2d_add_4x4_c, 16
#define PARAM_LIST_8X8 \
&av1_fwd_txfm2d_8x8_c, &av1_inv_txfm2d_add_8x8_sse4_1, \
&av1_inv_txfm2d_add_8x8_c, 64
#define PARAM_LIST_16X16 \
&av1_fwd_txfm2d_16x16_c, &av1_inv_txfm2d_add_16x16_sse4_1, \
&av1_inv_txfm2d_add_16x16_c, 256
#define PARAM_LIST_64X64 \
&av1_fwd_txfm2d_64x64_c, &av1_inv_txfm2d_add_64x64_sse4_1, \
&av1_inv_txfm2d_add_64x64_c, 4096
const IHbdHtParam kArrayIhtParam[] = {
// 16x16
make_tuple(PARAM_LIST_16X16, DCT_DCT, 10),
make_tuple(PARAM_LIST_16X16, DCT_DCT, 12),
make_tuple(PARAM_LIST_16X16, ADST_DCT, 10),
make_tuple(PARAM_LIST_16X16, ADST_DCT, 12),
make_tuple(PARAM_LIST_16X16, DCT_ADST, 10),
make_tuple(PARAM_LIST_16X16, DCT_ADST, 12),
make_tuple(PARAM_LIST_16X16, ADST_ADST, 10),
make_tuple(PARAM_LIST_16X16, ADST_ADST, 12),
make_tuple(PARAM_LIST_16X16, FLIPADST_DCT, 10),
make_tuple(PARAM_LIST_16X16, FLIPADST_DCT, 12),
make_tuple(PARAM_LIST_16X16, DCT_FLIPADST, 10),
make_tuple(PARAM_LIST_16X16, DCT_FLIPADST, 12),
make_tuple(PARAM_LIST_16X16, FLIPADST_FLIPADST, 10),
make_tuple(PARAM_LIST_16X16, FLIPADST_FLIPADST, 12),
make_tuple(PARAM_LIST_16X16, ADST_FLIPADST, 10),
make_tuple(PARAM_LIST_16X16, ADST_FLIPADST, 12),
make_tuple(PARAM_LIST_16X16, FLIPADST_ADST, 10),
make_tuple(PARAM_LIST_16X16, FLIPADST_ADST, 12),
// 8x8
make_tuple(PARAM_LIST_8X8, DCT_DCT, 10),
make_tuple(PARAM_LIST_8X8, DCT_DCT, 12),
make_tuple(PARAM_LIST_8X8, ADST_DCT, 10),
make_tuple(PARAM_LIST_8X8, ADST_DCT, 12),
make_tuple(PARAM_LIST_8X8, DCT_ADST, 10),
make_tuple(PARAM_LIST_8X8, DCT_ADST, 12),
make_tuple(PARAM_LIST_8X8, ADST_ADST, 10),
make_tuple(PARAM_LIST_8X8, ADST_ADST, 12),
make_tuple(PARAM_LIST_8X8, FLIPADST_DCT, 10),
make_tuple(PARAM_LIST_8X8, FLIPADST_DCT, 12),
make_tuple(PARAM_LIST_8X8, DCT_FLIPADST, 10),
make_tuple(PARAM_LIST_8X8, DCT_FLIPADST, 12),
make_tuple(PARAM_LIST_8X8, FLIPADST_FLIPADST, 10),
make_tuple(PARAM_LIST_8X8, FLIPADST_FLIPADST, 12),
make_tuple(PARAM_LIST_8X8, ADST_FLIPADST, 10),
make_tuple(PARAM_LIST_8X8, ADST_FLIPADST, 12),
make_tuple(PARAM_LIST_8X8, FLIPADST_ADST, 10),
make_tuple(PARAM_LIST_8X8, FLIPADST_ADST, 12),
// 4x4
make_tuple(PARAM_LIST_4X4, DCT_DCT, 10),
make_tuple(PARAM_LIST_4X4, DCT_DCT, 12),
@ -210,27 +165,151 @@ const IHbdHtParam kArrayIhtParam[] = {
make_tuple(PARAM_LIST_4X4, ADST_FLIPADST, 12),
make_tuple(PARAM_LIST_4X4, FLIPADST_ADST, 10),
make_tuple(PARAM_LIST_4X4, FLIPADST_ADST, 12),
make_tuple(PARAM_LIST_64X64, DCT_DCT, 10),
make_tuple(PARAM_LIST_64X64, DCT_DCT, 12),
};
INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdInvHTNxN,
::testing::ValuesIn(kArrayIhtParam));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
#define PARAM_LIST_32X32 \
&av1_fwd_txfm2d_32x32_c, &av1_inv_txfm2d_add_32x32_avx2, \
&av1_inv_txfm2d_add_32x32_c, 1024
typedef void (*HighbdInvTxfm2dFunc)(const int32_t *input, uint8_t *output,
int stride, const TxfmParam *txfm_param);
const IHbdHtParam kArrayIhtParam32x32[] = {
// 32x32
make_tuple(PARAM_LIST_32X32, DCT_DCT, 10),
make_tuple(PARAM_LIST_32X32, DCT_DCT, 12),
typedef ::testing::tuple<const HighbdInvTxfm2dFunc> AV1HighbdInvTxfm2dParam;
class AV1HighbdInvTxfm2d
: public ::testing::TestWithParam<AV1HighbdInvTxfm2dParam> {
public:
virtual void SetUp() { target_func_ = GET_PARAM(0); }
void RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, int run_times,
int bit_depth);
private:
HighbdInvTxfm2dFunc target_func_;
};
INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdInvHTNxN,
::testing::ValuesIn(kArrayIhtParam32x32));
void AV1HighbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type_, TX_SIZE tx_size_,
int run_times, int bit_depth_) {
FwdTxfm2dFunc fwd_func_ = libaom_test::fwd_txfm_func_ls[tx_size_];
TxfmParam txfm_param;
const int BLK_WIDTH = 64;
const int BLK_SIZE = BLK_WIDTH * BLK_WIDTH;
DECLARE_ALIGNED(16, int16_t, input[BLK_SIZE]) = { 0 };
DECLARE_ALIGNED(32, int32_t, inv_input[BLK_SIZE]) = { 0 };
DECLARE_ALIGNED(32, uint16_t, output[BLK_SIZE]) = { 0 };
DECLARE_ALIGNED(32, uint16_t, ref_output[BLK_SIZE]) = { 0 };
int stride = BLK_WIDTH;
int rows = tx_size_high[tx_size_];
int cols = tx_size_wide[tx_size_];
const int rows_nonezero = AOMMIN(32, rows);
const int cols_nonezero = AOMMIN(32, cols);
const uint16_t mask = (1 << bit_depth_) - 1;
run_times /= (rows * cols);
run_times = AOMMAX(1, run_times);
const SCAN_ORDER *scan_order = get_default_scan(tx_size_, tx_type_);
const int16_t *scan = scan_order->scan;
const int16_t eobmax = rows_nonezero * cols_nonezero;
ACMRandom rnd(ACMRandom::DeterministicSeed());
int randTimes = run_times == 1 ? (eobmax) : 1;
#endif // HAVE_AVX2
txfm_param.tx_type = tx_type_;
txfm_param.tx_size = tx_size_;
txfm_param.lossless = 0;
txfm_param.bd = bit_depth_;
txfm_param.is_hbd = 1;
txfm_param.tx_set_type = EXT_TX_SET_ALL16;
for (int cnt = 0; cnt < randTimes; ++cnt) {
for (int r = 0; r < BLK_WIDTH; ++r) {
for (int c = 0; c < BLK_WIDTH; ++c) {
input[r * cols + c] = (rnd.Rand16() & mask) - (rnd.Rand16() & mask);
output[r * stride + c] = rnd.Rand16() & mask;
ref_output[r * stride + c] = output[r * stride + c];
}
}
fwd_func_(input, inv_input, stride, tx_type_, bit_depth_);
// produce eob input by setting high freq coeffs to zero
const int eob = AOMMIN(cnt + 1, eobmax);
for (int i = eob; i < eobmax; i++) {
inv_input[scan[i]] = 0;
}
txfm_param.eob = eob;
aom_usec_timer ref_timer, test_timer;
aom_usec_timer_start(&ref_timer);
for (int i = 0; i < run_times; ++i) {
av1_highbd_inv_txfm_add_c(inv_input, CONVERT_TO_BYTEPTR(ref_output),
stride, &txfm_param);
}
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 < run_times; ++i) {
target_func_(inv_input, CONVERT_TO_BYTEPTR(output), stride, &txfm_param);
}
aom_usec_timer_mark(&test_timer);
const int elapsed_time_simd =
static_cast<int>(aom_usec_timer_elapsed(&test_timer));
if (run_times > 10) {
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));
} else {
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
ASSERT_EQ(ref_output[r * stride + c], output[r * stride + c])
<< "[" << r << "," << c << "] " << cnt
<< " tx_size: " << static_cast<int>(tx_size_)
<< " tx_type: " << tx_type_ << " eob " << eob;
}
}
}
}
}
TEST_P(AV1HighbdInvTxfm2d, match) {
int bitdepth_ar[2] = { 10, 12 };
for (int k = 0; k < 2; ++k) {
int bd = bitdepth_ar[k];
for (int j = 0; j < (int)(TX_SIZES_ALL); ++j) {
for (int i = 0; i < (int)TX_TYPES; ++i) {
if (libaom_test::IsTxSizeTypeValid(static_cast<TX_SIZE>(j),
static_cast<TX_TYPE>(i))) {
RunAV1InvTxfm2dTest(static_cast<TX_TYPE>(i), static_cast<TX_SIZE>(j),
1, bd);
}
}
}
}
}
TEST_P(AV1HighbdInvTxfm2d, DISABLED_Speed) {
int bitdepth_ar[2] = { 10, 12 };
for (int k = 0; k < 2; ++k) {
int bd = bitdepth_ar[k];
for (int j = 0; j < (int)(TX_SIZES_ALL); ++j) {
for (int i = 0; i < (int)TX_TYPES; ++i) {
if (libaom_test::IsTxSizeTypeValid(static_cast<TX_SIZE>(j),
static_cast<TX_TYPE>(i))) {
RunAV1InvTxfm2dTest(static_cast<TX_TYPE>(i), static_cast<TX_SIZE>(j),
1000000, bd);
}
}
}
}
}
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdInvTxfm2d,
::testing::Values(av1_highbd_inv_txfm_add_sse4_1));
#endif
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdInvTxfm2d,
::testing::Values(av1_highbd_inv_txfm_add_avx2));
#endif
} // namespace

View file

@ -27,9 +27,11 @@ namespace AV1CompRoundShift {
typedef void (*comp_round_shift_array_func)(int32_t *arr, int size, int bit);
#if HAVE_SSE4_1 || HAVE_NEON
const int kValidBitCheck[] = {
-4, -3, -2, -1, 0, 1, 2, 3, 4,
};
#endif // HAVE_SSE4_1 || HAVE_NEON
typedef ::testing::tuple<comp_round_shift_array_func, BLOCK_SIZE, int>
CompRoundShiftParam;

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AV1_TXFM_TEST_H_
#define AV1_TXFM_TEST_H_
#ifndef AOM_TEST_AV1_TXFM_TEST_H_
#define AOM_TEST_AV1_TXFM_TEST_H_
#include <stdio.h>
#include <stdlib.h>
@ -132,4 +132,4 @@ void txfm_stage_range_check(const int8_t *stage_range, int stage_num,
const int8_t cos_bit, int low_range,
int high_range);
} // namespace libaom_test
#endif // AV1_TXFM_TEST_H_
#endif // AOM_TEST_AV1_TXFM_TEST_H_

View file

@ -43,10 +43,16 @@ class BlendA64MaskTest : public FunctionEquivalenceTest<BlendA64Func> {
virtual ~BlendA64MaskTest() {}
virtual void Execute(const SrcPixel *p_src0, const SrcPixel *p_src1) = 0;
virtual void Execute(const SrcPixel *p_src0, const SrcPixel *p_src1,
int run_times) = 0;
template <typename Pixel>
void GetSources(Pixel **src0, Pixel **src1, Pixel * /*dst*/) {
void GetSources(Pixel **src0, Pixel **src1, Pixel * /*dst*/, int run_times) {
if (run_times > 1) {
*src0 = src0_;
*src1 = src1_;
return;
}
switch (this->rng_(3)) {
case 0: // Separate sources
*src0 = src0_;
@ -68,19 +74,20 @@ class BlendA64MaskTest : public FunctionEquivalenceTest<BlendA64Func> {
}
}
void GetSources(uint16_t **src0, uint16_t **src1, uint8_t * /*dst*/) {
void GetSources(uint16_t **src0, uint16_t **src1, uint8_t * /*dst*/,
int /*run_times*/) {
*src0 = src0_;
*src1 = src1_;
}
uint8_t Rand1() { return this->rng_.Rand8() & 1; }
void RunTest() {
w_ = 4 << this->rng_(MAX_SB_SIZE_LOG2 - 1);
h_ = 4 << this->rng_(MAX_SB_SIZE_LOG2 - 1);
subx_ = Rand1();
suby_ = Rand1();
void RunOneTest(int block_size, int subx, int suby, int run_times) {
w_ = block_size_wide[block_size];
h_ = block_size_high[block_size];
run_times = run_times > 1 ? run_times / w_ : 1;
subx_ = subx;
suby_ = suby;
dst_offset_ = this->rng_(33);
dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
@ -100,19 +107,26 @@ class BlendA64MaskTest : public FunctionEquivalenceTest<BlendA64Func> {
p_src0 = src0_;
p_src1 = src1_;
GetSources(&p_src0, &p_src1, &dst_ref_[0]);
GetSources(&p_src0, &p_src1, &dst_ref_[0], run_times);
Execute(p_src0, p_src1);
Execute(p_src0, p_src1, run_times);
for (int r = 0; r < h_; ++r) {
for (int c = 0; c < w_; ++c) {
ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
dst_tst_[dst_offset_ + r * dst_stride_ + c])
<< w_ << "x" << h_ << " r: " << r << " c: " << c;
<< w_ << "x" << h_ << " subx " << subx_ << " suby " << suby_
<< " r: " << r << " c: " << c;
}
}
}
void RunTest(int block_size, int run_times) {
subx_ = Rand1();
suby_ = Rand1();
RunOneTest(block_size, subx_, suby_, run_times);
}
DstPixel dst_ref_[kBufSize];
DstPixel dst_tst_[kBufSize];
uint32_t dst_stride_;
@ -148,19 +162,37 @@ typedef libaom_test::FuncParam<F8B> TestFuncs;
class BlendA64MaskTest8B : public BlendA64MaskTest<F8B, uint8_t, uint8_t> {
protected:
void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_);
ASM_REGISTER_STATE_CHECK(params_.tst_func(
dst_tst_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_, kMaxMaskWidth,
w_, h_, subx_, suby_));
void Execute(const uint8_t *p_src0, const uint8_t *p_src1, int run_times) {
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 1) {
printf("%3dx%-3d subx %d suby %d :%7.2f/%7.2fns", w_, h_, subx_, suby_,
time1, time2);
printf("(%3.2f)\n", time1 / time2);
}
}
};
TEST_P(BlendA64MaskTest8B, RandomValues) {
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = rng_.Rand8();
dst_tst_[i] = rng_.Rand8();
@ -172,12 +204,13 @@ TEST_P(BlendA64MaskTest8B, RandomValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
RunTest();
RunTest(bsize, 1);
}
}
TEST_P(BlendA64MaskTest8B, ExtremeValues) {
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = rng_(2) + 254;
dst_tst_[i] = rng_(2) + 254;
@ -188,14 +221,39 @@ TEST_P(BlendA64MaskTest8B, ExtremeValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA - 1;
RunTest();
RunTest(bsize, 1);
}
}
TEST_P(BlendA64MaskTest8B, DISABLED_Speed) {
const int kRunTimes = 10000000;
for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) {
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = rng_.Rand8();
dst_tst_[i] = rng_.Rand8();
src0_[i] = rng_.Rand8();
src1_[i] = rng_.Rand8();
}
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
RunOneTest(bsize, 1, 1, kRunTimes);
RunOneTest(bsize, 1, 0, kRunTimes);
RunOneTest(bsize, 0, 1, kRunTimes);
RunOneTest(bsize, 0, 0, kRunTimes);
}
}
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSE4_1, BlendA64MaskTest8B,
::testing::Values(TestFuncs(
aom_blend_a64_mask_c, aom_blend_a64_mask_sse4_1)));
#endif // HAVE_AVX2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, BlendA64MaskTest8B,
::testing::Values(TestFuncs(aom_blend_a64_mask_sse4_1,
aom_blend_a64_mask_avx2)));
#endif // HAVE_SSE4_1
//////////////////////////////////////////////////////////////////////////////
@ -215,22 +273,40 @@ class BlendA64MaskTest8B_d16
// max number of bits used by the source
static const int kSrcMaxBitsMask = 0x3fff;
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
void Execute(const uint16_t *p_src0, const uint16_t *p_src1, int run_times) {
ConvolveParams conv_params;
conv_params.round_0 = ROUND0_BITS;
conv_params.round_1 = COMPOUND_ROUND1_BITS;
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, &conv_params);
ASM_REGISTER_STATE_CHECK(params_.tst_func(
dst_tst_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_, kMaxMaskWidth,
w_, h_, subx_, suby_, &conv_params));
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, &conv_params);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, &conv_params);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 1) {
printf("%3dx%-3d subx %d suby %d :%7.2f/%7.2fns", w_, h_, subx_, suby_,
time1, time2);
printf("(%3.2f)\n", time1 / time2);
}
}
};
TEST_P(BlendA64MaskTest8B_d16, RandomValues) {
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = rng_.Rand8();
dst_tst_[i] = rng_.Rand8();
@ -242,12 +318,13 @@ TEST_P(BlendA64MaskTest8B_d16, RandomValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
RunTest();
RunTest(bsize, 1);
}
}
TEST_P(BlendA64MaskTest8B_d16, ExtremeValues) {
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = 255;
dst_tst_[i] = 255;
@ -259,7 +336,7 @@ TEST_P(BlendA64MaskTest8B_d16, ExtremeValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = AOM_BLEND_A64_MAX_ALPHA - 1;
RunTest();
RunTest(bsize, 1);
}
}
@ -270,6 +347,13 @@ INSTANTIATE_TEST_CASE_P(
aom_lowbd_blend_a64_d16_mask_sse4_1)));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
AVX2, BlendA64MaskTest8B_d16,
::testing::Values(TestFuncs_d16(aom_lowbd_blend_a64_d16_mask_c,
aom_lowbd_blend_a64_d16_mask_avx2)));
#endif // HAVE_AVX2
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
NEON, BlendA64MaskTest8B_d16,
@ -290,16 +374,31 @@ typedef libaom_test::FuncParam<FHBD> TestFuncsHBD;
class BlendA64MaskTestHBD : public BlendA64MaskTest<FHBD, uint16_t, uint16_t> {
protected:
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
mask_, kMaxMaskWidth, w_, h_, subx_, suby_, bit_depth_);
ASM_REGISTER_STATE_CHECK(params_.tst_func(
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, bit_depth_));
void Execute(const uint16_t *p_src0, const uint16_t *p_src1, int run_times) {
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
mask_, kMaxMaskWidth, w_, h_, subx_, suby_, bit_depth_);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.tst_func(CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
mask_, kMaxMaskWidth, w_, h_, subx_, suby_, bit_depth_);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 1) {
printf("%3dx%-3d subx %d suby %d :%7.2f/%7.2fns", w_, h_, subx_, suby_,
time1, time2);
printf("(%3.2f)\n", time1 / time2);
}
}
int bit_depth_;
@ -307,6 +406,7 @@ class BlendA64MaskTestHBD : public BlendA64MaskTest<FHBD, uint16_t, uint16_t> {
TEST_P(BlendA64MaskTestHBD, RandomValues) {
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
switch (rng_(3)) {
case 0: bit_depth_ = 8; break;
case 1: bit_depth_ = 10; break;
@ -325,12 +425,13 @@ TEST_P(BlendA64MaskTestHBD, RandomValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
RunTest();
RunTest(bsize, 1);
}
}
TEST_P(BlendA64MaskTestHBD, ExtremeValues) {
for (int iter = 0; iter < 1000 && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
switch (rng_(3)) {
case 0: bit_depth_ = 8; break;
case 1: bit_depth_ = 10; break;
@ -350,7 +451,7 @@ TEST_P(BlendA64MaskTestHBD, ExtremeValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA - 1;
RunTest();
RunTest(bsize, 1);
}
}
@ -380,21 +481,37 @@ class BlendA64MaskTestHBD_d16
static const int kSrcMaxBitsMask = (1 << 14) - 1;
static const int kSrcMaxBitsMaskHBD = (1 << 16) - 1;
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
void Execute(const uint16_t *p_src0, const uint16_t *p_src1, int run_times) {
ConvolveParams conv_params;
conv_params.round_0 = (bit_depth_ == 12) ? ROUND0_BITS + 2 : ROUND0_BITS;
conv_params.round_1 = COMPOUND_ROUND1_BITS;
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
p_src0 + src0_offset_, src0_stride_, p_src1 + src1_offset_,
src1_stride_, mask_, kMaxMaskWidth, w_, h_, subx_, suby_,
&conv_params, bit_depth_);
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, &conv_params,
bit_depth_);
}
if (params_.tst_func) {
ASM_REGISTER_STATE_CHECK(params_.tst_func(
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
p_src0 + src0_offset_, src0_stride_, p_src1 + src1_offset_,
src1_stride_, mask_, kMaxMaskWidth, w_, h_, subx_, suby_,
&conv_params, bit_depth_));
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
params_.tst_func(CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_),
dst_stride_, p_src0 + src0_offset_, src0_stride_,
p_src1 + src1_offset_, src1_stride_, mask_,
kMaxMaskWidth, w_, h_, subx_, suby_, &conv_params,
bit_depth_);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 1) {
printf("%3dx%-3d subx %d suby %d :%7.2f/%7.2fns", w_, h_, subx_, suby_,
time1, time2);
printf("(%3.2f)\n", time1 / time2);
}
}
}
@ -405,6 +522,7 @@ class BlendA64MaskTestHBD_d16
TEST_P(BlendA64MaskTestHBD_d16, RandomValues) {
if (params_.tst_func == NULL) return;
for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
int bsize = rng_.Rand8() % BLOCK_SIZES_ALL;
switch (rng_(3)) {
case 0: bit_depth_ = 8; break;
case 1: bit_depth_ = 10; break;
@ -424,26 +542,28 @@ TEST_P(BlendA64MaskTestHBD_d16, RandomValues) {
for (int i = 0; i < kMaxMaskSize; ++i)
mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
RunTest();
RunTest(bsize, 1);
}
}
// TODO (Scott LaVarnway), fix this test
TEST_P(BlendA64MaskTestHBD_d16, DISABLED_SaturatedValues) {
for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) {
for (bit_depth_ = 8; bit_depth_ <= 12; bit_depth_ += 2) {
src_max_bits_mask_ =
(bit_depth_ == 8) ? kSrcMaxBitsMask : kSrcMaxBitsMaskHBD;
TEST_P(BlendA64MaskTestHBD_d16, SaturatedValues) {
for (bit_depth_ = 8; bit_depth_ <= 12; bit_depth_ += 2) {
src_max_bits_mask_ =
(bit_depth_ == 8) ? kSrcMaxBitsMask : kSrcMaxBitsMaskHBD;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = 0;
dst_tst_[i] = (1 << bit_depth_) - 1;
for (int i = 0; i < kBufSize; ++i) {
dst_ref_[i] = 0;
dst_tst_[i] = (1 << bit_depth_) - 1;
src0_[i] = src_max_bits_mask_;
src1_[i] = src_max_bits_mask_;
}
src0_[i] = src_max_bits_mask_;
src1_[i] = src_max_bits_mask_;
for (int i = 0; i < kMaxMaskSize; ++i) mask_[i] = AOM_BLEND_A64_MAX_ALPHA;
RunTest(bsize, 1);
}
for (int i = 0; i < kMaxMaskSize; ++i) mask_[i] = AOM_BLEND_A64_MAX_ALPHA;
RunTest();
}
}

122
third_party/aom/test/blockd_test.cc vendored Normal file
View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2018, 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 "av1/common/blockd.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
// Verify the optimized implementation of get_partition_subsize() produces the
// same results as the Partition_Subsize lookup table in the spec.
TEST(BlockdTest, GetPartitionSubsize) {
// The Partition_Subsize table in the spec (Section 9.3. Conversion tables).
/* clang-format off */
static const BLOCK_SIZE kPartitionSubsize[10][BLOCK_SIZES_ALL] = {
{
BLOCK_4X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_128X128,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_128X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X128,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_128X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_128X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X128,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X128,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X4,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X8,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}, {
BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X16,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X32,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X64,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID,
BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID
}
};
/* clang-format on */
for (int partition = 0; partition < 10; partition++) {
for (int bsize = BLOCK_4X4; bsize < BLOCK_SIZES_ALL; bsize++) {
EXPECT_EQ(kPartitionSubsize[partition][bsize],
get_partition_subsize(static_cast<BLOCK_SIZE>(bsize),
static_cast<PARTITION_TYPE>(partition)));
}
}
}

View file

@ -108,6 +108,7 @@ TEST(AV1, TestTell) {
double frac_diff_total = 0;
GTEST_ASSERT_GE(aom_reader_tell(&br), 0u);
GTEST_ASSERT_LE(aom_reader_tell(&br), 1u);
ASSERT_FALSE(aom_reader_has_overflowed(&br));
for (int i = 0; i < kSymbols; i++) {
aom_read(&br, p, NULL);
uint32_t tell = aom_reader_tell(&br);
@ -130,5 +131,43 @@ TEST(AV1, TestTell) {
// The average frac_diff error should be pretty small.
GTEST_ASSERT_LE(frac_diff_total / kSymbols, FRAC_DIFF_TOTAL_ERROR)
<< " frac_diff_total: " << frac_diff_total;
ASSERT_FALSE(aom_reader_has_overflowed(&br));
}
}
TEST(AV1, TestHasOverflowed) {
const int kBufferSize = 10000;
aom_writer bw;
uint8_t bw_buffer[kBufferSize];
const int kSymbols = 1024;
// Coders are noisier at low probabilities, so we start at p = 4.
for (int p = 4; p < 256; p++) {
aom_start_encode(&bw, bw_buffer);
for (int i = 0; i < kSymbols; i++) {
aom_write(&bw, 1, p);
}
aom_stop_encode(&bw);
aom_reader br;
aom_reader_init(&br, bw_buffer, bw.pos);
ASSERT_FALSE(aom_reader_has_overflowed(&br));
for (int i = 0; i < kSymbols; i++) {
GTEST_ASSERT_EQ(aom_read(&br, p, NULL), 1);
ASSERT_FALSE(aom_reader_has_overflowed(&br));
}
// In the worst case, the encoder uses just a tiny fraction of the last
// byte in the buffer. So to guarantee that aom_reader_has_overflowed()
// returns true, we have to consume very nearly 8 additional bits of data.
// In the worse case, one of the bits in that byte will be 1, and the rest
// will be zero. Once we are past that 1 bit, when the probability of
// reading zero symbol from aom_read() is high, each additional symbol read
// will consume very little additional data (in the case that p == 255,
// approximately -log_2(255/256) ~= 0.0056 bits). In that case it would
// take around 178 calls to consume more than 8 bits. That is only an upper
// bound. In practice we are not guaranteed to hit the worse case and can
// get away with 174 calls.
for (int i = 0; i < 174; i++) {
aom_read(&br, p, NULL);
}
ASSERT_TRUE(aom_reader_has_overflowed(&br));
}
}

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_CLEAR_SYSTEM_STATE_H_
#define TEST_CLEAR_SYSTEM_STATE_H_
#ifndef AOM_TEST_CLEAR_SYSTEM_STATE_H_
#define AOM_TEST_CLEAR_SYSTEM_STATE_H_
#include "config/aom_config.h"
@ -28,4 +28,4 @@ inline void ClearSystemState() {
}
} // namespace libaom_test
#endif // TEST_CLEAR_SYSTEM_STATE_H_
#endif // AOM_TEST_CLEAR_SYSTEM_STATE_H_

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_CODEC_FACTORY_H_
#define TEST_CODEC_FACTORY_H_
#ifndef AOM_TEST_CODEC_FACTORY_H_
#define AOM_TEST_CODEC_FACTORY_H_
#include "config/aom_config.h"
@ -89,7 +89,7 @@ class AV1Decoder : public Decoder {
protected:
virtual aom_codec_iface_t *CodecInterface() const {
#if CONFIG_AV1_DECODER
return &aom_codec_av1_dx_algo;
return aom_codec_av1_dx();
#else
return NULL;
#endif
@ -105,7 +105,7 @@ class AV1Encoder : public Encoder {
protected:
virtual aom_codec_iface_t *CodecInterface() const {
#if CONFIG_AV1_ENCODER
return &aom_codec_av1_cx_algo;
return aom_codec_av1_cx();
#else
return NULL;
#endif
@ -147,7 +147,7 @@ class AV1CodecFactory : public CodecFactory {
virtual aom_codec_err_t DefaultEncoderConfig(aom_codec_enc_cfg_t *cfg,
int usage) const {
#if CONFIG_AV1_ENCODER
return aom_codec_enc_config_default(&aom_codec_av1_cx_algo, cfg, usage);
return aom_codec_enc_config_default(aom_codec_av1_cx(), cfg, usage);
#else
(void)cfg;
(void)usage;
@ -167,4 +167,4 @@ const libaom_test::AV1CodecFactory kAV1;
__VA_ARGS__))
} // namespace libaom_test
#endif // TEST_CODEC_FACTORY_H_
#endif // AOM_TEST_CODEC_FACTORY_H_

View file

@ -27,7 +27,7 @@ namespace {
class CompressedSource {
public:
explicit CompressedSource(int seed) : rnd_(seed), frame_count_(0) {
aom_codec_iface_t *algo = &aom_codec_av1_cx_algo;
aom_codec_iface_t *algo = aom_codec_av1_cx();
aom_codec_enc_cfg_t cfg;
aom_codec_enc_config_default(algo, &cfg, 0);
@ -140,7 +140,7 @@ std::vector<int16_t> Serialize(const aom_image_t *img) {
class Decoder {
public:
explicit Decoder(int allowLowbitdepth) {
aom_codec_iface_t *algo = &aom_codec_av1_dx_algo;
aom_codec_iface_t *algo = aom_codec_av1_dx();
aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
cfg.allow_lowbitdepth = allowLowbitdepth;

View file

@ -50,9 +50,9 @@ TEST_P(AV1HighBDJNTCOMPAVGTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(1)); }
TEST_P(AV1HighBDJNTCOMPAVGTest, CheckOutput) { RunCheckOutput(GET_PARAM(1)); }
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AV1HighBDJNTCOMPAVGTest,
libaom_test::AV1JNTCOMPAVG::BuildParams(aom_highbd_jnt_comp_avg_pred_sse2));
INSTANTIATE_TEST_CASE_P(SSE2, AV1HighBDJNTCOMPAVGTest,
libaom_test::AV1JNTCOMPAVG::BuildParams(
aom_highbd_jnt_comp_avg_pred_sse2, 1));
#endif
TEST_P(AV1HighBDJNTCOMPAVGUPSAMPLEDTest, DISABLED_Speed) {

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_COMP_AVG_PRED_TEST_H_
#define TEST_COMP_AVG_PRED_TEST_H_
#ifndef AOM_TEST_COMP_AVG_PRED_TEST_H_
#define AOM_TEST_COMP_AVG_PRED_TEST_H_
#include "config/aom_dsp_rtcd.h"
@ -36,25 +36,21 @@ typedef void (*jntcompavgupsampled_func)(
MACROBLOCKD *xd, const struct AV1Common *const cm, int mi_row, int mi_col,
const MV *const mv, uint8_t *comp_pred, const uint8_t *pred, int width,
int height, int subpel_x_q3, int subpel_y_q3, const uint8_t *ref,
int ref_stride, const JNT_COMP_PARAMS *jcp_param);
typedef void (*highbdjntcompavg_func)(uint16_t *comp_pred, const uint8_t *pred8,
int width, int height,
const uint8_t *ref8, int ref_stride,
const JNT_COMP_PARAMS *jcp_param);
int ref_stride, const JNT_COMP_PARAMS *jcp_param, int subpel_search);
typedef void (*highbdjntcompavgupsampled_func)(
MACROBLOCKD *xd, const struct AV1Common *const cm, int mi_row, int mi_col,
const MV *const mv, uint16_t *comp_pred, const uint8_t *pred8, int width,
const MV *const mv, uint8_t *comp_pred8, const uint8_t *pred8, int width,
int height, int subpel_x_q3, int subpel_y_q3, const uint8_t *ref8,
int ref_stride, int bd, const JNT_COMP_PARAMS *jcp_param);
int ref_stride, int bd, const JNT_COMP_PARAMS *jcp_param,
int subpel_search);
typedef ::testing::tuple<jntcompavg_func, BLOCK_SIZE> JNTCOMPAVGParam;
typedef ::testing::tuple<jntcompavgupsampled_func, BLOCK_SIZE>
JNTCOMPAVGUPSAMPLEDParam;
typedef ::testing::tuple<int, highbdjntcompavg_func, BLOCK_SIZE>
typedef ::testing::tuple<int, jntcompavg_func, BLOCK_SIZE>
HighbdJNTCOMPAVGParam;
typedef ::testing::tuple<int, highbdjntcompavgupsampled_func, BLOCK_SIZE>
@ -73,7 +69,8 @@ typedef ::testing::tuple<int, highbdjntcompavgupsampled_func, BLOCK_SIZE>
}
::testing::internal::ParamGenerator<HighbdJNTCOMPAVGParam> BuildParams(
highbdjntcompavg_func filter) {
jntcompavg_func filter, int is_hbd) {
(void)is_hbd;
return ::testing::Combine(::testing::Range(8, 13, 2),
::testing::Values(filter),
::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL));
@ -217,33 +214,39 @@ class AV1JNTCOMPAVGUPSAMPLEDTest
JNT_COMP_PARAMS jnt_comp_params;
jnt_comp_params.use_jnt_comp_avg = 1;
int sub_x_q3, sub_y_q3;
for (sub_x_q3 = 0; sub_x_q3 < 8; ++sub_x_q3) {
for (sub_y_q3 = 0; sub_y_q3 < 8; ++sub_y_q3) {
for (int ii = 0; ii < 2; ii++) {
for (int jj = 0; jj < 4; jj++) {
jnt_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0];
jnt_comp_params.bck_offset = quant_dist_lookup_table[ii][jj][1];
int subpel_search;
for (subpel_search = 1; subpel_search <= 2; ++subpel_search) {
for (sub_x_q3 = 0; sub_x_q3 < 8; ++sub_x_q3) {
for (sub_y_q3 = 0; sub_y_q3 < 8; ++sub_y_q3) {
for (int ii = 0; ii < 2; ii++) {
for (int jj = 0; jj < 4; jj++) {
jnt_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0];
jnt_comp_params.bck_offset = quant_dist_lookup_table[ii][jj][1];
const int offset_r = 3 + rnd_.PseudoUniform(h - in_h - 7);
const int offset_c = 3 + rnd_.PseudoUniform(w - in_w - 7);
const int offset_r = 3 + rnd_.PseudoUniform(h - in_h - 7);
const int offset_c = 3 + rnd_.PseudoUniform(w - in_w - 7);
aom_jnt_comp_avg_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, output, pred8 + offset_r * w + offset_c,
in_w, in_h, sub_x_q3, sub_y_q3, ref8 + offset_r * w + offset_c,
in_w, &jnt_comp_params);
test_impl(NULL, NULL, 0, 0, NULL, output2,
pred8 + offset_r * w + offset_c, in_w, in_h, sub_x_q3,
sub_y_q3, ref8 + offset_r * w + offset_c, in_w,
&jnt_comp_params);
aom_jnt_comp_avg_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, output,
pred8 + offset_r * w + offset_c, in_w, in_h, sub_x_q3,
sub_y_q3, ref8 + offset_r * w + offset_c, in_w,
&jnt_comp_params, subpel_search);
test_impl(NULL, NULL, 0, 0, NULL, output2,
pred8 + offset_r * w + offset_c, in_w, in_h, sub_x_q3,
sub_y_q3, ref8 + offset_r * w + offset_c, in_w,
&jnt_comp_params, subpel_search);
for (int i = 0; i < in_h; ++i) {
for (int j = 0; j < in_w; ++j) {
int idx = i * in_w + j;
ASSERT_EQ(output[idx], output2[idx])
<< "Mismatch at unit tests for AV1JNTCOMPAVGUPSAMPLEDTest\n"
<< in_w << "x" << in_h << " Pixel mismatch at index " << idx
<< " = (" << i << ", " << j << "), sub pixel offset = ("
<< sub_y_q3 << ", " << sub_x_q3 << ")";
for (int i = 0; i < in_h; ++i) {
for (int j = 0; j < in_w; ++j) {
int idx = i * in_w + j;
ASSERT_EQ(output[idx], output2[idx])
<< "Mismatch at unit tests for "
"AV1JNTCOMPAVGUPSAMPLEDTest\n"
<< in_w << "x" << in_h << " Pixel mismatch at index "
<< idx << " = (" << i << ", " << j
<< "), sub pixel offset = (" << sub_y_q3 << ", "
<< sub_x_q3 << ")";
}
}
}
}
@ -280,11 +283,12 @@ class AV1JNTCOMPAVGUPSAMPLEDTest
const int num_loops = 1000000000 / (in_w + in_h);
aom_usec_timer timer;
aom_usec_timer_start(&timer);
int subpel_search = 2; // set to 1 to test 4-tap filter.
for (int i = 0; i < num_loops; ++i)
aom_jnt_comp_avg_upsampled_pred_c(NULL, NULL, 0, 0, NULL, output, pred8,
in_w, in_h, sub_x_q3, sub_y_q3, ref8,
in_w, &jnt_comp_params);
in_w, &jnt_comp_params, subpel_search);
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
@ -296,7 +300,7 @@ class AV1JNTCOMPAVGUPSAMPLEDTest
for (int i = 0; i < num_loops; ++i)
test_impl(NULL, NULL, 0, 0, NULL, output2, pred8, in_w, in_h, sub_x_q3,
sub_y_q3, ref8, in_w, &jnt_comp_params);
sub_y_q3, ref8, in_w, &jnt_comp_params, subpel_search);
aom_usec_timer_mark(&timer1);
const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
@ -316,7 +320,7 @@ class AV1HighBDJNTCOMPAVGTest
void TearDown() { libaom_test::ClearSystemState(); }
protected:
void RunCheckOutput(highbdjntcompavg_func test_impl) {
void RunCheckOutput(jntcompavg_func test_impl) {
const int w = kMaxSize, h = kMaxSize;
const int block_idx = GET_PARAM(2);
const int bd = GET_PARAM(0);
@ -344,13 +348,14 @@ class AV1HighBDJNTCOMPAVGTest
const int offset_r = 3 + rnd_.PseudoUniform(h - in_h - 7);
const int offset_c = 3 + rnd_.PseudoUniform(w - in_w - 7);
aom_highbd_jnt_comp_avg_pred_c(
output, CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w,
in_h, CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w,
CONVERT_TO_BYTEPTR(output),
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w, in_h,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w,
&jnt_comp_params);
test_impl(output2, CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c,
in_w, in_h,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w,
&jnt_comp_params);
test_impl(CONVERT_TO_BYTEPTR(output2),
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w,
in_h, CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c,
in_w, &jnt_comp_params);
for (int i = 0; i < in_h; ++i) {
for (int j = 0; j < in_w; ++j) {
@ -364,7 +369,7 @@ class AV1HighBDJNTCOMPAVGTest
}
}
}
void RunSpeedTest(highbdjntcompavg_func test_impl) {
void RunSpeedTest(jntcompavg_func test_impl) {
const int w = kMaxSize, h = kMaxSize;
const int block_idx = GET_PARAM(2);
const int bd = GET_PARAM(0);
@ -392,9 +397,9 @@ class AV1HighBDJNTCOMPAVGTest
aom_usec_timer_start(&timer);
for (int i = 0; i < num_loops; ++i)
aom_highbd_jnt_comp_avg_pred_c(output, CONVERT_TO_BYTEPTR(pred8), in_w,
in_h, CONVERT_TO_BYTEPTR(ref8), in_w,
&jnt_comp_params);
aom_highbd_jnt_comp_avg_pred_c(
CONVERT_TO_BYTEPTR(output), CONVERT_TO_BYTEPTR(pred8), in_w, in_h,
CONVERT_TO_BYTEPTR(ref8), in_w, &jnt_comp_params);
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
@ -405,8 +410,8 @@ class AV1HighBDJNTCOMPAVGTest
aom_usec_timer_start(&timer1);
for (int i = 0; i < num_loops; ++i)
test_impl(output2, CONVERT_TO_BYTEPTR(pred8), in_w, in_h,
CONVERT_TO_BYTEPTR(ref8), in_w, &jnt_comp_params);
test_impl(CONVERT_TO_BYTEPTR(output2), CONVERT_TO_BYTEPTR(pred8), in_w,
in_h, CONVERT_TO_BYTEPTR(ref8), in_w, &jnt_comp_params);
aom_usec_timer_mark(&timer1);
const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
@ -445,38 +450,41 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest
JNT_COMP_PARAMS jnt_comp_params;
jnt_comp_params.use_jnt_comp_avg = 1;
int sub_x_q3, sub_y_q3;
int subpel_search;
for (subpel_search = 1; subpel_search <= 2; ++subpel_search) {
for (sub_x_q3 = 0; sub_x_q3 < 8; ++sub_x_q3) {
for (sub_y_q3 = 0; sub_y_q3 < 8; ++sub_y_q3) {
for (int ii = 0; ii < 2; ii++) {
for (int jj = 0; jj < 4; jj++) {
jnt_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0];
jnt_comp_params.bck_offset = quant_dist_lookup_table[ii][jj][1];
for (sub_x_q3 = 0; sub_x_q3 < 8; ++sub_x_q3) {
for (sub_y_q3 = 0; sub_y_q3 < 8; ++sub_y_q3) {
for (int ii = 0; ii < 2; ii++) {
for (int jj = 0; jj < 4; jj++) {
jnt_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0];
jnt_comp_params.bck_offset = quant_dist_lookup_table[ii][jj][1];
const int offset_r = 3 + rnd_.PseudoUniform(h - in_h - 7);
const int offset_c = 3 + rnd_.PseudoUniform(w - in_w - 7);
const int offset_r = 3 + rnd_.PseudoUniform(h - in_h - 7);
const int offset_c = 3 + rnd_.PseudoUniform(w - in_w - 7);
aom_highbd_jnt_comp_avg_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(output),
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w,
in_h, sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w, bd,
&jnt_comp_params, subpel_search);
test_impl(NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(output2),
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c,
in_w, in_h, sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c,
in_w, bd, &jnt_comp_params, subpel_search);
aom_highbd_jnt_comp_avg_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, output,
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w, in_h,
sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w, bd,
&jnt_comp_params);
test_impl(NULL, NULL, 0, 0, NULL, output2,
CONVERT_TO_BYTEPTR(pred8) + offset_r * w + offset_c, in_w,
in_h, sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8) + offset_r * w + offset_c, in_w,
bd, &jnt_comp_params);
for (int i = 0; i < in_h; ++i) {
for (int j = 0; j < in_w; ++j) {
int idx = i * in_w + j;
ASSERT_EQ(output[idx], output2[idx])
<< "Mismatch at unit tests for "
"AV1HighBDJNTCOMPAVGUPSAMPLEDTest\n"
<< in_w << "x" << in_h << " Pixel mismatch at index " << idx
<< " = (" << i << ", " << j << "), sub pixel offset = ("
<< sub_y_q3 << ", " << sub_x_q3 << ")";
for (int i = 0; i < in_h; ++i) {
for (int j = 0; j < in_w; ++j) {
int idx = i * in_w + j;
ASSERT_EQ(output[idx], output2[idx])
<< "Mismatch at unit tests for "
"AV1HighBDJNTCOMPAVGUPSAMPLEDTest\n"
<< in_w << "x" << in_h << " Pixel mismatch at index "
<< idx << " = (" << i << ", " << j
<< "), sub pixel offset = (" << sub_y_q3 << ", "
<< sub_x_q3 << ")";
}
}
}
}
@ -511,12 +519,12 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest
const int num_loops = 1000000000 / (in_w + in_h);
aom_usec_timer timer;
aom_usec_timer_start(&timer);
int subpel_search = 2; // set to 1 to test 4-tap filter.
for (int i = 0; i < num_loops; ++i)
aom_highbd_jnt_comp_avg_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, output, CONVERT_TO_BYTEPTR(pred8), in_w, in_h,
sub_x_q3, sub_y_q3, CONVERT_TO_BYTEPTR(ref8), in_w, bd,
&jnt_comp_params);
NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(output),
CONVERT_TO_BYTEPTR(pred8), in_w, in_h, sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8), in_w, bd, &jnt_comp_params, subpel_search);
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
@ -527,9 +535,10 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest
aom_usec_timer_start(&timer1);
for (int i = 0; i < num_loops; ++i)
test_impl(NULL, NULL, 0, 0, NULL, output2, CONVERT_TO_BYTEPTR(pred8),
in_w, in_h, sub_x_q3, sub_y_q3, CONVERT_TO_BYTEPTR(ref8), in_w,
bd, &jnt_comp_params);
test_impl(NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(output2),
CONVERT_TO_BYTEPTR(pred8), in_w, in_h, sub_x_q3, sub_y_q3,
CONVERT_TO_BYTEPTR(ref8), in_w, bd, &jnt_comp_params,
subpel_search);
aom_usec_timer_mark(&timer1);
const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
@ -543,4 +552,4 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest
} // namespace AV1JNTCOMPAVG
} // namespace libaom_test
#endif // TEST_COMP_AVG_PRED_TEST_H_
#endif // AOM_TEST_COMP_AVG_PRED_TEST_H_

View file

@ -190,26 +190,29 @@ void AV1CompMaskUpVarianceTest::RunCheckOutput(comp_mask_pred_func test_impl,
const int w = block_size_wide[bsize];
const int h = block_size_high[bsize];
int wedge_types = (1 << get_wedge_bits_lookup(bsize));
int subpel_search;
for (subpel_search = 1; subpel_search <= 2; ++subpel_search) {
// loop through subx and suby
for (int sub = 0; sub < 8 * 8; ++sub) {
int subx = sub & 0x7;
int suby = (sub >> 3);
for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
const uint8_t *mask =
av1_get_contiguous_soft_mask(wedge_index, 1, bsize);
// loop through subx and suby
for (int sub = 0; sub < 8 * 8; ++sub) {
int subx = sub & 0x7;
int suby = (sub >> 3);
for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize);
// ref
aom_comp_mask_upsampled_pred_c(
NULL, NULL, 0, 0, NULL, comp_pred1_, pred_, w, h, subx, suby, ref_,
MAX_SB_SIZE, mask, w, inv, subpel_search);
aom_comp_mask_pred = aom_comp_mask_pred_c; // ref
aom_comp_mask_upsampled_pred(NULL, NULL, 0, 0, NULL, comp_pred1_, pred_,
w, h, subx, suby, ref_, MAX_SB_SIZE, mask, w,
inv);
aom_comp_mask_pred = test_impl; // test
aom_comp_mask_upsampled_pred(NULL, NULL, 0, 0, NULL, comp_pred2_, pred_,
w, h, subx, suby, ref_, MAX_SB_SIZE, mask, w,
inv);
ASSERT_EQ(CheckResult(w, h), true)
<< " wedge " << wedge_index << " inv " << inv << "sub (" << subx
<< "," << suby << ")";
aom_comp_mask_pred = test_impl; // test
aom_comp_mask_upsampled_pred(NULL, NULL, 0, 0, NULL, comp_pred2_, pred_,
w, h, subx, suby, ref_, MAX_SB_SIZE, mask,
w, inv, subpel_search);
ASSERT_EQ(CheckResult(w, h), true)
<< " wedge " << wedge_index << " inv " << inv << "sub (" << subx
<< "," << suby << ")";
}
}
}
}
@ -228,6 +231,7 @@ void AV1CompMaskUpVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl,
const int num_loops = 1000000000 / (w + h);
comp_mask_pred_func funcs[2] = { &aom_comp_mask_pred_c, test_impl };
double elapsed_time[2] = { 0 };
int subpel_search = 2; // set to 1 to test 4-tap filter.
for (int i = 0; i < 2; ++i) {
aom_usec_timer timer;
aom_usec_timer_start(&timer);
@ -235,7 +239,7 @@ void AV1CompMaskUpVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl,
for (int j = 0; j < num_loops; ++j) {
aom_comp_mask_upsampled_pred(NULL, NULL, 0, 0, NULL, comp_pred1_, pred_,
w, h, subx, suby, ref_, MAX_SB_SIZE, mask, w,
0);
0, subpel_search);
}
aom_usec_timer_mark(&timer);
double time = static_cast<double>(aom_usec_timer_elapsed(&timer));
@ -272,7 +276,7 @@ INSTANTIATE_TEST_CASE_P(
#endif // ifndef aom_comp_mask_pred
typedef void (*highbd_comp_mask_pred_func)(uint16_t *comp_pred,
typedef void (*highbd_comp_mask_pred_func)(uint8_t *comp_pred8,
const uint8_t *pred8, int width,
int height, const uint8_t *ref8,
int ref_stride, const uint8_t *mask,
@ -358,11 +362,11 @@ void AV1HighbdCompMaskVarianceTest::RunCheckOutput(
for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize);
aom_highbd_comp_mask_pred_c(comp_pred1_, CONVERT_TO_BYTEPTR(pred_), w, h,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w,
inv);
aom_highbd_comp_mask_pred_c(
CONVERT_TO_BYTEPTR(comp_pred1_), CONVERT_TO_BYTEPTR(pred_), w, h,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv);
test_impl(comp_pred2_, CONVERT_TO_BYTEPTR(pred_), w, h,
test_impl(CONVERT_TO_BYTEPTR(comp_pred2_), CONVERT_TO_BYTEPTR(pred_), w, h,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv);
ASSERT_EQ(CheckResult(w, h), true)
@ -398,7 +402,7 @@ void AV1HighbdCompMaskVarianceTest::RunSpeedTest(
aom_usec_timer_start(&timer);
highbd_comp_mask_pred_func func = funcs[i];
for (int j = 0; j < num_loops; ++j) {
func(comp_pred1_, CONVERT_TO_BYTEPTR(pred_), w, h,
func(CONVERT_TO_BYTEPTR(comp_pred1_), CONVERT_TO_BYTEPTR(pred_), w, h,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, 0);
}
aom_usec_timer_mark(&timer);
@ -428,6 +432,14 @@ INSTANTIATE_TEST_CASE_P(
::testing::Range(8, 13, 2)));
#endif
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AV1HighbdCompMaskVarianceTest,
::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_sse2),
::testing::ValuesIn(kValidBlockSize),
::testing::Range(8, 13, 2)));
#endif
#ifndef aom_highbd_comp_mask_pred
// can't run this test if aom_highbd_comp_mask_pred is defined to
// aom_highbd_comp_mask_pred_c
@ -458,25 +470,33 @@ void AV1HighbdCompMaskUpVarianceTest::RunCheckOutput(
ref_buffer_[i] = rnd_.Rand16() & ((1 << bd_) - 1);
}
// loop through subx and suby
for (int sub = 0; sub < 8 * 8; ++sub) {
int subx = sub & 0x7;
int suby = (sub >> 3);
for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize);
int subpel_search;
for (subpel_search = 1; subpel_search <= 2; ++subpel_search) {
// loop through subx and suby
for (int sub = 0; sub < 8 * 8; ++sub) {
int subx = sub & 0x7;
int suby = (sub >> 3);
for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
const uint8_t *mask =
av1_get_contiguous_soft_mask(wedge_index, 1, bsize);
aom_highbd_comp_mask_pred = aom_highbd_comp_mask_pred_c; // ref
aom_highbd_comp_mask_upsampled_pred(
NULL, NULL, 0, 0, NULL, comp_pred1_, CONVERT_TO_BYTEPTR(pred_), w, h,
subx, suby, CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv, bd_);
aom_highbd_comp_mask_pred = aom_highbd_comp_mask_pred_c; // ref
aom_highbd_comp_mask_upsampled_pred(
NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(comp_pred1_),
CONVERT_TO_BYTEPTR(pred_), w, h, subx, suby,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv, bd_,
subpel_search);
aom_highbd_comp_mask_pred = test_impl; // test
aom_highbd_comp_mask_upsampled_pred(
NULL, NULL, 0, 0, NULL, comp_pred2_, CONVERT_TO_BYTEPTR(pred_), w, h,
subx, suby, CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv, bd_);
ASSERT_EQ(CheckResult(w, h), true)
<< " wedge " << wedge_index << " inv " << inv << "sub (" << subx
<< "," << suby << ")";
aom_highbd_comp_mask_pred = test_impl; // test
aom_highbd_comp_mask_upsampled_pred(
NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(comp_pred2_),
CONVERT_TO_BYTEPTR(pred_), w, h, subx, suby,
CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, inv, bd_,
subpel_search);
ASSERT_EQ(CheckResult(w, h), true)
<< " wedge " << wedge_index << " inv " << inv << "sub (" << subx
<< "," << suby << ")";
}
}
}
}
@ -508,10 +528,12 @@ void AV1HighbdCompMaskUpVarianceTest::RunSpeedTest(
aom_usec_timer timer;
aom_usec_timer_start(&timer);
aom_highbd_comp_mask_pred = funcs[i];
int subpel_search = 2; // set to 1 to test 4-tap filter.
for (int j = 0; j < num_loops; ++j) {
aom_highbd_comp_mask_upsampled_pred(
NULL, NULL, 0, 0, NULL, comp_pred1_, CONVERT_TO_BYTEPTR(pred_), w, h,
subx, suby, CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, mask, w, 0, bd_);
NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(comp_pred1_),
CONVERT_TO_BYTEPTR(pred_), w, h, subx, suby, CONVERT_TO_BYTEPTR(ref_),
MAX_SB_SIZE, mask, w, 0, bd_, subpel_search);
}
aom_usec_timer_mark(&timer);
double time = static_cast<double>(aom_usec_timer_elapsed(&timer));
@ -540,5 +562,13 @@ INSTANTIATE_TEST_CASE_P(
::testing::Range(8, 13, 2)));
#endif
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AV1HighbdCompMaskUpVarianceTest,
::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_sse2),
::testing::ValuesIn(kValidBlockSize),
::testing::Range(8, 13, 2)));
#endif
#endif // ifndef aom_highbd_comp_mask_pred
} // namespace AV1CompMaskVariance

View file

@ -22,7 +22,7 @@ namespace {
TEST(DecodeAPI, InvalidParams) {
static const aom_codec_iface_t *kCodecs[] = {
#if CONFIG_AV1_DECODER
&aom_codec_av1_dx_algo,
aom_codec_av1_dx(),
#endif
};
uint8_t buf[1] = { 0 };

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_DECODE_TEST_DRIVER_H_
#define TEST_DECODE_TEST_DRIVER_H_
#ifndef AOM_TEST_DECODE_TEST_DRIVER_H_
#define AOM_TEST_DECODE_TEST_DRIVER_H_
#include <cstring>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
@ -162,4 +162,4 @@ class DecoderTest {
} // namespace libaom_test
#endif // TEST_DECODE_TEST_DRIVER_H_
#endif // AOM_TEST_DECODE_TEST_DRIVER_H_

View file

@ -22,7 +22,7 @@ namespace {
TEST(EncodeAPI, InvalidParams) {
static const aom_codec_iface_t *kCodecs[] = {
#if CONFIG_AV1_ENCODER
&aom_codec_av1_cx_algo,
aom_codec_av1_cx(),
#endif
};
uint8_t buf[1] = { 0 };
@ -54,6 +54,16 @@ TEST(EncodeAPI, InvalidParams) {
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));
EXPECT_EQ(NULL, aom_codec_get_global_headers(NULL));
aom_fixed_buf_t *glob_headers = aom_codec_get_global_headers(&enc);
EXPECT_TRUE(glob_headers->buf != NULL);
if (glob_headers) {
free(glob_headers->buf);
free(glob_headers);
}
EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, NULL, 0, 0, 0));
EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));

View file

@ -205,13 +205,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
ASSERT_FALSE(::testing::Test::HasFatalFailure());
unsigned long dec_init_flags = 0; // NOLINT
// Use fragment decoder if encoder outputs partitions.
// NOTE: fragment decoder and partition encoder are only supported by VP8.
if (init_flags_ & AOM_CODEC_USE_OUTPUT_PARTITION)
dec_init_flags |= AOM_CODEC_USE_INPUT_FRAGMENTS;
testing::internal::scoped_ptr<Decoder> decoder(
codec_->CreateDecoder(dec_cfg, dec_init_flags));
codec_->CreateDecoder(dec_cfg, 0 /* flags */));
#if CONFIG_AV1_DECODER
if (decoder->IsAV1()) {
// Set dec_cfg.tile_row = -1 and dec_cfg.tile_col = -1 so that the whole
@ -268,12 +263,6 @@ void EncoderTest::RunLoop(VideoSource *video) {
}
}
// Flush the decoder when there are no more fragments.
if ((init_flags_ & AOM_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
const aom_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
if (!HandleDecodeResult(res_dec, decoder.get())) break;
}
if (has_dxdata && has_cxdata) {
const aom_image_t *img_enc = encoder->GetPreviewFrame();
DxDataIterator dec_iter = decoder->GetDxData();

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_ENCODE_TEST_DRIVER_H_
#define TEST_ENCODE_TEST_DRIVER_H_
#ifndef AOM_TEST_ENCODE_TEST_DRIVER_H_
#define AOM_TEST_ENCODE_TEST_DRIVER_H_
#include <string>
#include <vector>
@ -246,4 +246,4 @@ class EncoderTest {
} // namespace libaom_test
#endif // TEST_ENCODE_TEST_DRIVER_H_
#endif // AOM_TEST_ENCODE_TEST_DRIVER_H_

View file

@ -181,15 +181,22 @@ INSTANTIATE_TEST_CASE_P(SSE2, EncodeTxbTest,
::testing::Values(av1_get_nz_map_contexts_sse2));
#endif
#if HAVE_SSE4_1
class EncodeTxbInitLevelTest : public ::testing::TestWithParam<int> {
typedef void (*av1_txb_init_levels_func)(const tran_low_t *const coeff,
const int width, const int height,
uint8_t *const levels);
typedef ::testing::tuple<av1_txb_init_levels_func, int> TxbInitLevelParam;
class EncodeTxbInitLevelTest
: public ::testing::TestWithParam<TxbInitLevelParam> {
public:
virtual ~EncodeTxbInitLevelTest() {}
virtual void TearDown() { libaom_test::ClearSystemState(); }
void RunTest(int tx_size, int is_speed);
void RunTest(av1_txb_init_levels_func test_func, int tx_size, int is_speed);
};
void EncodeTxbInitLevelTest::RunTest(int tx_size, int is_speed) {
void EncodeTxbInitLevelTest::RunTest(av1_txb_init_levels_func test_func,
int tx_size, int is_speed) {
const int width = get_txb_wide((TX_SIZE)tx_size);
const int height = get_txb_high((TX_SIZE)tx_size);
tran_low_t coeff[MAX_TX_SQUARE];
@ -215,7 +222,7 @@ void EncodeTxbInitLevelTest::RunTest(int tx_size, int is_speed) {
const double t1 = get_time_mark(&timer);
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
av1_txb_init_levels_sse4_1(coeff, width, height, levels1);
test_func(coeff, width, height, levels1);
}
const double t2 = get_time_mark(&timer);
if (is_speed) {
@ -232,11 +239,24 @@ void EncodeTxbInitLevelTest::RunTest(int tx_size, int is_speed) {
}
}
TEST_P(EncodeTxbInitLevelTest, match) { RunTest(GetParam(), 0); }
TEST_P(EncodeTxbInitLevelTest, DISABLED_Speed) { RunTest(GetParam(), 1); }
TEST_P(EncodeTxbInitLevelTest, match) {
RunTest(GET_PARAM(0), GET_PARAM(1), 0);
}
INSTANTIATE_TEST_CASE_P(SSE4_1, EncodeTxbInitLevelTest,
::testing::Range(0, static_cast<int>(TX_SIZES_ALL), 1));
TEST_P(EncodeTxbInitLevelTest, DISABLED_Speed) {
RunTest(GET_PARAM(0), GET_PARAM(1), 1);
}
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
SSE4_1, EncodeTxbInitLevelTest,
::testing::Combine(::testing::Values(&av1_txb_init_levels_sse4_1),
::testing::Range(0, static_cast<int>(TX_SIZES_ALL), 1)));
#endif
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
AVX2, EncodeTxbInitLevelTest,
::testing::Combine(::testing::Values(&av1_txb_init_levels_avx2),
::testing::Range(0, static_cast<int>(TX_SIZES_ALL), 1)));
#endif
} // namespace

View file

@ -50,7 +50,7 @@ class AVxEncoderThreadTest
SetMode(encoding_mode_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
cfg_.g_lag_in_frames = 3;
cfg_.g_lag_in_frames = 5;
cfg_.rc_end_usage = AOM_VBR;
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
@ -72,6 +72,7 @@ class AVxEncoderThreadTest
if (!encoder_initialized_) {
SetTileSize(encoder);
encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
encoder->Control(AV1E_SET_ROW_MT, row_mt_);
if (encoding_mode_ != ::libaom_test::kRealTime) {
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
@ -115,10 +116,11 @@ class AVxEncoderThreadTest
void DoTest() {
::libaom_test::YUVVideoSource video(
"niklas_640_480_30.yuv", AOM_IMG_FMT_I420, 640, 480, 30, 1, 15, 18);
"niklas_640_480_30.yuv", AOM_IMG_FMT_I420, 640, 480, 30, 1, 15, 21);
cfg_.rc_target_bitrate = 1000;
// Encode using single thread.
row_mt_ = 0;
cfg_.g_threads = 1;
init_flags_ = AOM_CODEC_USE_PSNR;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
@ -149,6 +151,55 @@ class AVxEncoderThreadTest
ASSERT_EQ(single_thr_size_enc, multi_thr_size_enc);
ASSERT_EQ(single_thr_md5_enc, multi_thr_md5_enc);
ASSERT_EQ(single_thr_md5_dec, multi_thr_md5_dec);
// Encode using multiple threads row-mt enabled.
row_mt_ = 1;
cfg_.g_threads = 2;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
std::vector<size_t> multi_thr2_row_mt_size_enc;
std::vector<std::string> multi_thr2_row_mt_md5_enc;
std::vector<std::string> multi_thr2_row_mt_md5_dec;
multi_thr2_row_mt_size_enc = size_enc_;
multi_thr2_row_mt_md5_enc = md5_enc_;
multi_thr2_row_mt_md5_dec = md5_dec_;
size_enc_.clear();
md5_enc_.clear();
md5_dec_.clear();
// Disable threads=3 test for now to reduce the time so that the nightly
// test would not time out.
// cfg_.g_threads = 3;
// ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// std::vector<size_t> multi_thr3_row_mt_size_enc;
// std::vector<std::string> multi_thr3_row_mt_md5_enc;
// std::vector<std::string> multi_thr3_row_mt_md5_dec;
// multi_thr3_row_mt_size_enc = size_enc_;
// multi_thr3_row_mt_md5_enc = md5_enc_;
// multi_thr3_row_mt_md5_dec = md5_dec_;
// size_enc_.clear();
// md5_enc_.clear();
// md5_dec_.clear();
// Check that the vectors are equal.
// ASSERT_EQ(multi_thr3_row_mt_size_enc, multi_thr2_row_mt_size_enc);
// ASSERT_EQ(multi_thr3_row_mt_md5_enc, multi_thr2_row_mt_md5_enc);
// ASSERT_EQ(multi_thr3_row_mt_md5_dec, multi_thr2_row_mt_md5_dec);
cfg_.g_threads = 4;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
std::vector<size_t> multi_thr4_row_mt_size_enc;
std::vector<std::string> multi_thr4_row_mt_md5_enc;
std::vector<std::string> multi_thr4_row_mt_md5_dec;
multi_thr4_row_mt_size_enc = size_enc_;
multi_thr4_row_mt_md5_enc = md5_enc_;
multi_thr4_row_mt_md5_dec = md5_dec_;
size_enc_.clear();
md5_enc_.clear();
md5_dec_.clear();
// Check that the vectors are equal.
ASSERT_EQ(multi_thr4_row_mt_size_enc, multi_thr2_row_mt_size_enc);
ASSERT_EQ(multi_thr4_row_mt_md5_enc, multi_thr2_row_mt_md5_enc);
ASSERT_EQ(multi_thr4_row_mt_md5_dec, multi_thr2_row_mt_md5_dec);
}
bool encoder_initialized_;
@ -156,6 +207,7 @@ class AVxEncoderThreadTest
int set_cpu_used_;
int tile_cols_;
int tile_rows_;
int row_mt_;
::libaom_test::Decoder *decoder_;
std::vector<size_t> size_enc_;
std::vector<std::string> md5_enc_;
@ -177,12 +229,13 @@ TEST_P(AVxEncoderThreadTestLarge, EncoderResultTest) {
}
// For AV1, only test speed 0 to 3.
// Here test cpu_used 2 and 3
AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadTest,
::testing::Values(::libaom_test::kTwoPassGood,
::libaom_test::kOnePassGood),
::testing::Range(2, 4), ::testing::Values(1, 2),
::testing::Values(::libaom_test::kTwoPassGood),
::testing::Range(2, 4), ::testing::Values(0, 2),
::testing::Values(0, 1));
// Test cpu_used 0 and 1.
AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadTestLarge,
::testing::Values(::libaom_test::kTwoPassGood,
::libaom_test::kOnePassGood),
@ -212,14 +265,9 @@ TEST_P(AVxEncoderThreadLSTestLarge, EncoderResultTest) {
DoTest();
}
AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadLSTest,
::testing::Values(::libaom_test::kTwoPassGood,
::libaom_test::kOnePassGood),
::testing::Range(2, 4), ::testing::Values(6),
::testing::Values(0, 6));
AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadLSTestLarge,
::testing::Values(::libaom_test::kTwoPassGood,
::libaom_test::kOnePassGood),
::testing::Range(0, 2), ::testing::Values(6),
::testing::Range(0, 4), ::testing::Values(0, 6),
::testing::Values(0, 6));
} // namespace

View file

@ -0,0 +1,512 @@
/*
* Copyright (c) 2014 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 <string>
#include "config/aom_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
#include "test/md5_helper.h"
#include "test/test_vectors.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
namespace {
const int kVideoNameParam = 1;
struct ExternalFrameBuffer {
uint8_t *data;
size_t size;
int in_use;
};
// Class to manipulate a list of external frame buffers.
class ExternalFrameBufferList {
public:
ExternalFrameBufferList()
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
virtual ~ExternalFrameBufferList() {
for (int i = 0; i < num_buffers_; ++i) {
delete[] ext_fb_list_[i].data;
}
delete[] ext_fb_list_;
}
// Creates the list to hold the external buffers. Returns true on success.
bool CreateBufferList(int num_buffers) {
if (num_buffers < 0) return false;
num_buffers_ = num_buffers;
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
EXPECT_TRUE(ext_fb_list_ != NULL);
memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_);
return true;
}
// Searches the frame buffer list for a free frame buffer. Makes sure
// that the frame buffer is at least |min_size| in bytes. Marks that the
// frame buffer is in use by libvpx. Finally sets |fb| to point to the
// external frame buffer. Returns < 0 on an error.
int GetFreeFrameBuffer(size_t min_size, aom_codec_frame_buffer_t *fb) {
EXPECT_TRUE(fb != NULL);
const int idx = FindFreeBufferIndex();
if (idx == num_buffers_) return -1;
if (ext_fb_list_[idx].size < min_size) {
delete[] ext_fb_list_[idx].data;
ext_fb_list_[idx].data = new uint8_t[min_size];
memset(ext_fb_list_[idx].data, 0, min_size);
ext_fb_list_[idx].size = min_size;
}
SetFrameBuffer(idx, fb);
num_used_buffers_++;
return 0;
}
// Test function that will not allocate any data for the frame buffer.
// Returns < 0 on an error.
int GetZeroFrameBuffer(size_t min_size, aom_codec_frame_buffer_t *fb) {
EXPECT_TRUE(fb != NULL);
const int idx = FindFreeBufferIndex();
if (idx == num_buffers_) return -1;
if (ext_fb_list_[idx].size < min_size) {
delete[] ext_fb_list_[idx].data;
ext_fb_list_[idx].data = NULL;
ext_fb_list_[idx].size = min_size;
}
SetFrameBuffer(idx, fb);
return 0;
}
// Marks the external frame buffer that |fb| is pointing to as free.
// Returns < 0 on an error.
int ReturnFrameBuffer(aom_codec_frame_buffer_t *fb) {
if (fb == NULL) {
EXPECT_TRUE(fb != NULL);
return -1;
}
ExternalFrameBuffer *const ext_fb =
reinterpret_cast<ExternalFrameBuffer *>(fb->priv);
if (ext_fb == NULL) {
EXPECT_TRUE(ext_fb != NULL);
return -1;
}
EXPECT_EQ(1, ext_fb->in_use);
ext_fb->in_use = 0;
num_used_buffers_--;
return 0;
}
// Checks that the ximage data is contained within the external frame buffer
// private data passed back in the ximage.
void CheckXImageFrameBuffer(const aom_image_t *img) {
if (img->fb_priv != NULL) {
const struct ExternalFrameBuffer *const ext_fb =
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
ASSERT_TRUE(img->planes[0] >= ext_fb->data &&
img->planes[0] < (ext_fb->data + ext_fb->size));
}
}
int num_used_buffers() const { return num_used_buffers_; }
private:
// Returns the index of the first free frame buffer. Returns |num_buffers_|
// if there are no free frame buffers.
int FindFreeBufferIndex() {
int i;
// Find a free frame buffer.
for (i = 0; i < num_buffers_; ++i) {
if (!ext_fb_list_[i].in_use) break;
}
return i;
}
// Sets |fb| to an external frame buffer. idx is the index into the frame
// buffer list.
void SetFrameBuffer(int idx, aom_codec_frame_buffer_t *fb) {
ASSERT_TRUE(fb != NULL);
fb->data = ext_fb_list_[idx].data;
fb->size = ext_fb_list_[idx].size;
ASSERT_EQ(0, ext_fb_list_[idx].in_use);
ext_fb_list_[idx].in_use = 1;
fb->priv = &ext_fb_list_[idx];
}
int num_buffers_;
int num_used_buffers_;
ExternalFrameBuffer *ext_fb_list_;
};
#if CONFIG_WEBM_IO
// Callback used by libvpx to request the application to return a frame
// buffer of at least |min_size| in bytes.
int get_aom_frame_buffer(void *user_priv, size_t min_size,
aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferList *const fb_list =
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
return fb_list->GetFreeFrameBuffer(min_size, fb);
}
// Callback used by libvpx to tell the application that |fb| is not needed
// anymore.
int release_aom_frame_buffer(void *user_priv, aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferList *const fb_list =
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
return fb_list->ReturnFrameBuffer(fb);
}
// Callback will not allocate data for frame buffer.
int get_aom_zero_frame_buffer(void *user_priv, size_t min_size,
aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferList *const fb_list =
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
return fb_list->GetZeroFrameBuffer(min_size, fb);
}
// Callback will allocate one less byte than |min_size|.
int get_aom_one_less_byte_frame_buffer(void *user_priv, size_t min_size,
aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferList *const fb_list =
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
return fb_list->GetFreeFrameBuffer(min_size - 1, fb);
}
// Callback will not release the external frame buffer.
int do_not_release_aom_frame_buffer(void *user_priv,
aom_codec_frame_buffer_t *fb) {
(void)user_priv;
(void)fb;
return 0;
}
#endif // CONFIG_WEBM_IO
// Class for testing passing in external frame buffers to libaom.
class ExternalFrameBufferMD5Test
: public ::libaom_test::DecoderTest,
public ::libaom_test::CodecTestWithParam<const char *> {
protected:
ExternalFrameBufferMD5Test()
: DecoderTest(GET_PARAM(::libaom_test::kCodecFactoryParam)),
md5_file_(NULL), num_buffers_(0) {}
virtual ~ExternalFrameBufferMD5Test() {
if (md5_file_ != NULL) fclose(md5_file_);
}
virtual void PreDecodeFrameHook(
const libaom_test::CompressedVideoSource &video,
libaom_test::Decoder *decoder) {
if (num_buffers_ > 0 && video.frame_number() == 0) {
// Have libvpx use frame buffers we create.
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
ASSERT_EQ(AOM_CODEC_OK,
decoder->SetFrameBufferFunctions(GetAV1FrameBuffer,
ReleaseAV1FrameBuffer, this));
}
}
void OpenMD5File(const std::string &md5_file_name_) {
md5_file_ = libaom_test::OpenTestDataFile(md5_file_name_);
ASSERT_TRUE(md5_file_ != NULL)
<< "Md5 file open failed. Filename: " << md5_file_name_;
}
virtual void DecompressedFrameHook(const aom_image_t &img,
const unsigned int frame_number) {
ASSERT_TRUE(md5_file_ != NULL);
char expected_md5[33];
char junk[128];
// Read correct md5 checksums.
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
ASSERT_NE(EOF, res) << "Read md5 data failed";
expected_md5[32] = '\0';
::libaom_test::MD5 md5_res;
md5_res.Add(&img);
const char *const actual_md5 = md5_res.Get();
// Check md5 match.
ASSERT_STREQ(expected_md5, actual_md5)
<< "Md5 checksums don't match: frame number = " << frame_number;
}
// Callback to get a free external frame buffer. Return value < 0 is an
// error.
static int GetAV1FrameBuffer(void *user_priv, size_t min_size,
aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferMD5Test *const md5Test =
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb);
}
// Callback to release an external frame buffer. Return value < 0 is an
// error.
static int ReleaseAV1FrameBuffer(void *user_priv,
aom_codec_frame_buffer_t *fb) {
ExternalFrameBufferMD5Test *const md5Test =
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
return md5Test->fb_list_.ReturnFrameBuffer(fb);
}
void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
int num_buffers() const { return num_buffers_; }
private:
FILE *md5_file_;
int num_buffers_;
ExternalFrameBufferList fb_list_;
};
#if CONFIG_WEBM_IO
const char kAV1TestFile[] = "av1-1-b8-01-size-226x226.ivf";
const char kAV1NonRefTestFile[] = "av1-1-b8-01-size-226x226.ivf";
// Class for testing passing in external frame buffers to libvpx.
class ExternalFrameBufferTest : public ::testing::Test {
protected:
ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {}
virtual void SetUp() {
video_ = new libaom_test::IVFVideoSource(kAV1TestFile);
ASSERT_TRUE(video_ != NULL);
video_->Init();
video_->Begin();
aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
decoder_ = new libaom_test::AV1Decoder(cfg, 0);
ASSERT_TRUE(decoder_ != NULL);
}
virtual void TearDown() {
delete decoder_;
decoder_ = NULL;
delete video_;
video_ = NULL;
}
// Passes the external frame buffer information to libvpx.
aom_codec_err_t SetFrameBufferFunctions(
int num_buffers, aom_get_frame_buffer_cb_fn_t cb_get,
aom_release_frame_buffer_cb_fn_t cb_release) {
if (num_buffers > 0) {
num_buffers_ = num_buffers;
EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_));
}
return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_);
}
aom_codec_err_t DecodeOneFrame() {
const aom_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
CheckDecodedFrames();
if (res == AOM_CODEC_OK) video_->Next();
return res;
}
aom_codec_err_t DecodeRemainingFrames() {
for (; video_->cxdata() != NULL; video_->Next()) {
const aom_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
if (res != AOM_CODEC_OK) return res;
CheckDecodedFrames();
}
return AOM_CODEC_OK;
}
protected:
void CheckDecodedFrames() {
libaom_test::DxDataIterator dec_iter = decoder_->GetDxData();
const aom_image_t *img = NULL;
// Get decompressed data
while ((img = dec_iter.Next()) != NULL) {
fb_list_.CheckXImageFrameBuffer(img);
}
}
libaom_test::IVFVideoSource *video_;
libaom_test::AV1Decoder *decoder_;
int num_buffers_;
ExternalFrameBufferList fb_list_;
};
class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
protected:
virtual void SetUp() {
video_ = new libaom_test::IVFVideoSource(kAV1NonRefTestFile);
ASSERT_TRUE(video_ != NULL);
video_->Init();
video_->Begin();
aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
decoder_ = new libaom_test::AV1Decoder(cfg, 0);
ASSERT_TRUE(decoder_ != NULL);
}
virtual void CheckFrameBufferRelease() {
TearDown();
ASSERT_EQ(0, fb_list_.num_used_buffers());
}
};
#endif // CONFIG_WEBM_IO
// This test runs through the set of test vectors, and decodes them.
// Libvpx will call into the application to allocate a frame buffer when
// needed. The md5 checksums are computed for each frame in the video file.
// If md5 checksums match the correct md5 data, then the test is passed.
// Otherwise, the test failed.
TEST_P(ExternalFrameBufferMD5Test, DISABLED_ExtFBMD5Match) {
const std::string filename = GET_PARAM(kVideoNameParam);
// Number of buffers equals #AOM_MAXIMUM_REF_BUFFERS +
// #AOM_MAXIMUM_WORK_BUFFERS + four jitter buffers.
const int jitter_buffers = 4;
const int num_buffers =
AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS + jitter_buffers;
set_num_buffers(num_buffers);
// Open compressed video file.
testing::internal::scoped_ptr<libaom_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libaom_test::IVFVideoSource(filename));
} else {
#if CONFIG_WEBM_IO
video.reset(new libaom_test::WebMVideoSource(filename));
#else
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
filename.c_str());
return;
#endif
}
ASSERT_TRUE(video.get() != NULL);
video->Init();
// Construct md5 file name.
const std::string md5_filename = filename + ".md5";
OpenMD5File(md5_filename);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
}
#if CONFIG_WEBM_IO
TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
// Minimum number of external frame buffers for AV1 is
// #AOM_MAXIMUM_REF_BUFFERS + #AOM_MAXIMUM_WORK_BUFFERS.
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
}
TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
// Number of buffers equals #AOM_MAXIMUM_REF_BUFFERS +
// #AOM_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
const int jitter_buffers = 8;
const int num_buffers =
AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS + jitter_buffers;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
}
TEST_F(ExternalFrameBufferTest, DISABLED_NotEnoughBuffers) {
// Minimum number of external frame buffers for AV1 is
// #AOM_MAXIMUM_REF_BUFFERS + #AOM_MAXIMUM_WORK_BUFFERS. Most files will
// only use 5 frame buffers at one time.
const int num_buffers = 2;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
// Only run this on long clips. Decoding a very short clip will return
// AOM_CODEC_OK even with only 2 buffers.
ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeRemainingFrames());
}
TEST_F(ExternalFrameBufferTest, DISABLED_NoRelease) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
do_not_release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeRemainingFrames());
}
TEST_F(ExternalFrameBufferTest, NullRealloc) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_zero_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeOneFrame());
}
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK, SetFrameBufferFunctions(
num_buffers, get_aom_one_less_byte_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeOneFrame());
}
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(
AOM_CODEC_INVALID_PARAM,
SetFrameBufferFunctions(num_buffers, NULL, release_aom_frame_buffer));
}
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_INVALID_PARAM,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer, NULL));
}
TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
ASSERT_EQ(AOM_CODEC_ERROR,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
release_aom_frame_buffer));
}
TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(AOM_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
release_aom_frame_buffer));
ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
CheckFrameBufferRelease();
}
#endif // CONFIG_WEBM_IO
AV1_INSTANTIATE_TEST_CASE(
ExternalFrameBufferMD5Test,
::testing::ValuesIn(libaom_test::kAV1TestVectors,
libaom_test::kAV1TestVectors +
libaom_test::kNumAV1TestVectors));
} // namespace

View file

@ -17,9 +17,6 @@
#include "aom_dsp/fft_common.h"
#include "aom_mem/aom_mem.h"
#if ARCH_X86 || ARCH_X86_64
#include "aom_ports/x86.h"
#endif
#include "av1/common/common.h"
#include "config/aom_dsp_rtcd.h"
#include "test/acm_random.h"
@ -80,14 +77,11 @@ std::vector<std::complex<float> > fft2d(const InputType *input, int n) {
struct FFTTestArg {
int n;
void (*fft)(const float *input, float *temp, float *output);
int flag;
FFTTestArg(int n_in, tform_fun_t fft_in, int flag_in)
: n(n_in), fft(fft_in), flag(flag_in) {}
FFTTestArg(int n_in, tform_fun_t fft_in) : n(n_in), fft(fft_in) {}
};
std::ostream &operator<<(std::ostream &os, const FFTTestArg &test_arg) {
return os << "fft_arg { n:" << test_arg.n << " fft:" << test_arg.fft
<< " flag:" << test_arg.flag << "}";
return os << "fft_arg { n:" << test_arg.n << " fft:" << test_arg.fft << " }";
}
class FFT2DTest : public ::testing::TestWithParam<FFTTestArg> {
@ -100,26 +94,18 @@ class FFT2DTest : public ::testing::TestWithParam<FFTTestArg> {
memset(input_, 0, sizeof(*input_) * n * n);
memset(temp_, 0, sizeof(*temp_) * n * n);
memset(output_, 0, sizeof(*output_) * n * n * 2);
#if ARCH_X86 || ARCH_X86_64
disabled_ = GetParam().flag != 0 && !(x86_simd_caps() & GetParam().flag);
#else
disabled_ = GetParam().flag != 0;
#endif
}
void TearDown() {
aom_free(input_);
aom_free(temp_);
aom_free(output_);
}
int disabled_;
float *input_;
float *temp_;
float *output_;
};
TEST_P(FFT2DTest, Correct) {
if (disabled_) return;
int n = GetParam().n;
for (int i = 0; i < n * n; ++i) {
input_[i] = 1;
@ -137,8 +123,6 @@ TEST_P(FFT2DTest, Correct) {
}
TEST_P(FFT2DTest, Benchmark) {
if (disabled_) return;
int n = GetParam().n;
float sum = 0;
for (int i = 0; i < 1000 * (64 - n); ++i) {
@ -149,39 +133,40 @@ TEST_P(FFT2DTest, Benchmark) {
}
}
INSTANTIATE_TEST_CASE_P(
FFT2DTestC, FFT2DTest,
::testing::Values(FFTTestArg(2, aom_fft2x2_float_c, 0),
FFTTestArg(4, aom_fft4x4_float_c, 0),
FFTTestArg(8, aom_fft8x8_float_c, 0),
FFTTestArg(16, aom_fft16x16_float_c, 0),
FFTTestArg(32, aom_fft32x32_float_c, 0)));
INSTANTIATE_TEST_CASE_P(C, FFT2DTest,
::testing::Values(FFTTestArg(2, aom_fft2x2_float_c),
FFTTestArg(4, aom_fft4x4_float_c),
FFTTestArg(8, aom_fft8x8_float_c),
FFTTestArg(16, aom_fft16x16_float_c),
FFTTestArg(32,
aom_fft32x32_float_c)));
#if ARCH_X86 || ARCH_X86_64
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
FFT2DTestSSE2, FFT2DTest,
::testing::Values(FFTTestArg(4, aom_fft4x4_float_sse2, HAS_SSE2),
FFTTestArg(8, aom_fft8x8_float_sse2, HAS_SSE2),
FFTTestArg(16, aom_fft16x16_float_sse2, HAS_SSE2),
FFTTestArg(32, aom_fft32x32_float_sse2, HAS_SSE2)));
SSE2, FFT2DTest,
::testing::Values(FFTTestArg(4, aom_fft4x4_float_sse2),
FFTTestArg(8, aom_fft8x8_float_sse2),
FFTTestArg(16, aom_fft16x16_float_sse2),
FFTTestArg(32, aom_fft32x32_float_sse2)));
#endif // HAVE_SSE2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
FFT2DTestAVX2, FFT2DTest,
::testing::Values(FFTTestArg(8, aom_fft8x8_float_avx2, HAS_AVX2),
FFTTestArg(16, aom_fft16x16_float_avx2, HAS_AVX2),
FFTTestArg(32, aom_fft32x32_float_avx2, HAS_AVX2)));
#endif
AVX2, FFT2DTest,
::testing::Values(FFTTestArg(8, aom_fft8x8_float_avx2),
FFTTestArg(16, aom_fft16x16_float_avx2),
FFTTestArg(32, aom_fft32x32_float_avx2)));
#endif // HAVE_AVX2
#endif // ARCH_X86 || ARCH_X86_64
struct IFFTTestArg {
int n;
tform_fun_t ifft;
int flag;
IFFTTestArg(int n_in, tform_fun_t ifft_in, int flag_in)
: n(n_in), ifft(ifft_in), flag(flag_in) {}
IFFTTestArg(int n_in, tform_fun_t ifft_in) : n(n_in), ifft(ifft_in) {}
};
std::ostream &operator<<(std::ostream &os, const IFFTTestArg &test_arg) {
return os << "ifft_arg { n:" << test_arg.n << " fft:" << test_arg.ifft
<< " flag:" << test_arg.flag << "}";
<< " }";
}
class IFFT2DTest : public ::testing::TestWithParam<IFFTTestArg> {
@ -194,25 +179,18 @@ class IFFT2DTest : public ::testing::TestWithParam<IFFTTestArg> {
memset(input_, 0, sizeof(*input_) * n * n * 2);
memset(temp_, 0, sizeof(*temp_) * n * n * 2);
memset(output_, 0, sizeof(*output_) * n * n);
#if ARCH_X86 || ARCH_X86_64
disabled_ = GetParam().flag != 0 && !(x86_simd_caps() & GetParam().flag);
#else
disabled_ = GetParam().flag != 0;
#endif
}
void TearDown() {
aom_free(input_);
aom_free(temp_);
aom_free(output_);
}
int disabled_;
float *input_;
float *temp_;
float *output_;
};
TEST_P(IFFT2DTest, Correctness) {
if (disabled_) return;
int n = GetParam().n;
ASSERT_GE(n, 2);
std::vector<float> expected(n * n);
@ -240,7 +218,6 @@ TEST_P(IFFT2DTest, Correctness) {
};
TEST_P(IFFT2DTest, Benchmark) {
if (disabled_) return;
int n = GetParam().n;
float sum = 0;
for (int i = 0; i < 1000 * (64 - n); ++i) {
@ -251,24 +228,29 @@ TEST_P(IFFT2DTest, Benchmark) {
}
}
INSTANTIATE_TEST_CASE_P(
IFFT2DTestC, IFFT2DTest,
::testing::Values(IFFTTestArg(2, aom_ifft2x2_float_c, 0),
IFFTTestArg(4, aom_ifft4x4_float_c, 0),
IFFTTestArg(8, aom_ifft8x8_float_c, 0),
IFFTTestArg(16, aom_ifft16x16_float_c, 0),
IFFTTestArg(32, aom_ifft32x32_float_c, 0)));
C, IFFT2DTest,
::testing::Values(IFFTTestArg(2, aom_ifft2x2_float_c),
IFFTTestArg(4, aom_ifft4x4_float_c),
IFFTTestArg(8, aom_ifft8x8_float_c),
IFFTTestArg(16, aom_ifft16x16_float_c),
IFFTTestArg(32, aom_ifft32x32_float_c)));
#if ARCH_X86 || ARCH_X86_64
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
IFFT2DTestSSE2, IFFT2DTest,
::testing::Values(IFFTTestArg(4, aom_ifft4x4_float_sse2, HAS_SSE2),
IFFTTestArg(8, aom_ifft8x8_float_sse2, HAS_SSE2),
IFFTTestArg(16, aom_ifft16x16_float_sse2, HAS_SSE2),
IFFTTestArg(32, aom_ifft32x32_float_sse2, HAS_SSE2)));
SSE2, IFFT2DTest,
::testing::Values(IFFTTestArg(4, aom_ifft4x4_float_sse2),
IFFTTestArg(8, aom_ifft8x8_float_sse2),
IFFTTestArg(16, aom_ifft16x16_float_sse2),
IFFTTestArg(32, aom_ifft32x32_float_sse2)));
#endif // HAVE_SSE2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
IFFT2DTestAVX2, IFFT2DTest,
::testing::Values(IFFTTestArg(8, aom_ifft8x8_float_avx2, HAS_AVX2),
IFFTTestArg(16, aom_ifft16x16_float_avx2, HAS_AVX2),
IFFTTestArg(32, aom_ifft32x32_float_avx2, HAS_AVX2)));
#endif
AVX2, IFFT2DTest,
::testing::Values(IFFTTestArg(8, aom_ifft8x8_float_avx2),
IFFTTestArg(16, aom_ifft16x16_float_avx2),
IFFTTestArg(32, aom_ifft32x32_float_avx2)));
#endif // HAVE_AVX2
#endif // ARCH_X86 || ARCH_X86_64
} // namespace

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_FUNCTION_EQUIVALENCE_TEST_H_
#define TEST_FUNCTION_EQUIVALENCE_TEST_H_
#ifndef AOM_TEST_FUNCTION_EQUIVALENCE_TEST_H_
#define AOM_TEST_FUNCTION_EQUIVALENCE_TEST_H_
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/acm_random.h"
@ -66,4 +66,4 @@ class FunctionEquivalenceTest : public ::testing::TestWithParam<FuncParam<T> > {
};
} // namespace libaom_test
#endif // TEST_FUNCTION_EQUIVALENCE_TEST_H_
#endif // AOM_TEST_FUNCTION_EQUIVALENCE_TEST_H_

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#define TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#ifndef AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#define AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#include "config/av1_rtcd.h"
@ -90,4 +90,4 @@ class AV1HighbdHiprecConvolveTest
} // namespace libaom_test
#endif // TEST_HIPREC_CONVOLVE_TEST_UTIL_H_
#endif // AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_I420_VIDEO_SOURCE_H_
#define TEST_I420_VIDEO_SOURCE_H_
#ifndef AOM_TEST_I420_VIDEO_SOURCE_H_
#define AOM_TEST_I420_VIDEO_SOURCE_H_
#include <cstdio>
#include <cstdlib>
#include <string>
@ -31,4 +31,4 @@ class I420VideoSource : public YUVVideoSource {
} // namespace libaom_test
#endif // TEST_I420_VIDEO_SOURCE_H_
#endif // AOM_TEST_I420_VIDEO_SOURCE_H_

View file

@ -49,29 +49,31 @@ class InvalidFileTest : public ::libaom_test::DecoderTest,
const libaom_test::CompressedVideoSource &video,
libaom_test::Decoder *decoder) {
EXPECT_TRUE(res_file_ != NULL);
int expected_res_dec;
int expected_res_dec = -1;
// Read integer result.
const int res = fscanf(res_file_, "%d", &expected_res_dec);
EXPECT_NE(res, EOF) << "Read result data failed";
// Check results match.
const DecodeParam input = GET_PARAM(1);
if (input.threads > 1) {
// The serial decode check is too strict for tile-threaded decoding as
// there is no guarantee on the decode order nor which specific error
// will take precedence. Currently a tile-level error is not forwarded so
// the frame will simply be marked corrupt.
EXPECT_TRUE(res_dec == expected_res_dec ||
res_dec == AOM_CODEC_CORRUPT_FRAME)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError()
<< "). Expected: " << expected_res_dec << " or "
<< AOM_CODEC_CORRUPT_FRAME;
} else {
EXPECT_EQ(expected_res_dec, res_dec)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError() << ")";
if (expected_res_dec != -1) {
// Check results match.
const DecodeParam input = GET_PARAM(1);
if (input.threads > 1) {
// The serial decode check is too strict for tile-threaded decoding as
// there is no guarantee on the decode order nor which specific error
// will take precedence. Currently a tile-level error is not forwarded
// so the frame will simply be marked corrupt.
EXPECT_TRUE(res_dec == expected_res_dec ||
res_dec == AOM_CODEC_CORRUPT_FRAME)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError()
<< "). Expected: " << expected_res_dec << " or "
<< AOM_CODEC_CORRUPT_FRAME;
} else {
EXPECT_EQ(expected_res_dec, res_dec)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError() << ")";
}
}
return !HasFailure();
@ -106,6 +108,12 @@ TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
const DecodeParam kAV1InvalidFileTests[] = {
{ 1, "invalid-bug-1814.ivf" },
{ 4, "invalid-oss-fuzz-9463.ivf" },
{ 1, "invalid-oss-fuzz-9482.ivf" },
{ 1, "invalid-oss-fuzz-9720.ivf" },
{ 1, "invalid-oss-fuzz-10061.ivf" },
{ 1, "invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf" },
{ 1, "invalid-oss-fuzz-10227.ivf" },
};
AV1_INSTANTIATE_TEST_CASE(InvalidFileTest,

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_IVF_VIDEO_SOURCE_H_
#define TEST_IVF_VIDEO_SOURCE_H_
#ifndef AOM_TEST_IVF_VIDEO_SOURCE_H_
#define AOM_TEST_IVF_VIDEO_SOURCE_H_
#include <cstdio>
#include <cstdlib>
@ -111,4 +111,4 @@ class IVFVideoSource : public CompressedVideoSource {
} // namespace libaom_test
#endif // TEST_IVF_VIDEO_SOURCE_H_
#endif // AOM_TEST_IVF_VIDEO_SOURCE_H_

50
third_party/aom/test/log2_test.cc vendored Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2018, 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 <math.h>
#include "aom_ports/bitops.h"
#include "av1/common/entropymode.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
TEST(Log2Test, GetMsb) {
// Test small numbers exhaustively.
for (unsigned int n = 1; n < 10000; n++) {
EXPECT_EQ(get_msb(n), static_cast<int>(floor(log2(n))));
}
// Test every power of 2 and the two adjacent numbers.
for (int exponent = 2; exponent < 32; exponent++) {
const unsigned int power_of_2 = 1U << exponent;
EXPECT_EQ(get_msb(power_of_2 - 1), exponent - 1);
EXPECT_EQ(get_msb(power_of_2), exponent);
EXPECT_EQ(get_msb(power_of_2 + 1), exponent);
}
}
TEST(Log2Test, Av1CeilLog2) {
// Test small numbers exhaustively.
EXPECT_EQ(av1_ceil_log2(0), 0);
for (int n = 1; n < 10000; n++) {
EXPECT_EQ(av1_ceil_log2(n), static_cast<int>(ceil(log2(n))));
}
// Test every power of 2 and the two adjacent numbers.
for (int exponent = 2; exponent < 31; exponent++) {
const int power_of_2 = 1 << exponent;
EXPECT_EQ(av1_ceil_log2(power_of_2 - 1), exponent);
EXPECT_EQ(av1_ceil_log2(power_of_2), exponent);
// The current implementation of av1_ceil_log2 only works up to 2^30.
if (exponent < 30) {
EXPECT_EQ(av1_ceil_log2(power_of_2 + 1), exponent + 1);
}
}
}

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_MD5_HELPER_H_
#define TEST_MD5_HELPER_H_
#ifndef AOM_TEST_MD5_HELPER_H_
#define AOM_TEST_MD5_HELPER_H_
#include "aom/aom_decoder.h"
#include "common/md5_utils.h"
@ -73,4 +73,4 @@ class MD5 {
} // namespace libaom_test
#endif // TEST_MD5_HELPER_H_
#endif // AOM_TEST_MD5_HELPER_H_

View file

@ -93,6 +93,43 @@ TEST_P(ObmcVarianceTest, ExtremeValues) {
}
}
TEST_P(ObmcVarianceTest, DISABLED_Speed) {
DECLARE_ALIGNED(32, uint8_t, pre[MAX_SB_SQUARE]);
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
const int pre_stride = this->rng_(MAX_SB_SIZE + 1);
for (int i = 0; i < MAX_SB_SQUARE; ++i) {
pre[i] = this->rng_.Rand8();
wsrc[i] = this->rng_.Rand8() * this->rng_(kMaskMax * kMaskMax + 1);
mask[i] = this->rng_(kMaskMax * kMaskMax + 1);
}
const int num_loops = 1000000;
unsigned int ref_sse, tst_sse;
aom_usec_timer ref_timer, test_timer;
aom_usec_timer_start(&ref_timer);
for (int i = 0; i < num_loops; ++i) {
params_.ref_func(pre, pre_stride, wsrc, mask, &ref_sse);
}
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) {
params_.tst_func(pre, pre_stride, wsrc, mask, &tst_sse);
}
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_SSE4_1
const ObmcVarianceTest::ParamType sse4_functions[] = {
TestFuncs(aom_obmc_variance128x128_c, aom_obmc_variance128x128_sse4_1),
@ -117,6 +154,30 @@ INSTANTIATE_TEST_CASE_P(SSE4_1, ObmcVarianceTest,
::testing::ValuesIn(sse4_functions));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
const ObmcVarianceTest::ParamType avx2_functions[] = {
TestFuncs(aom_obmc_variance128x128_c, aom_obmc_variance128x128_avx2),
TestFuncs(aom_obmc_variance128x64_c, aom_obmc_variance128x64_avx2),
TestFuncs(aom_obmc_variance64x128_c, aom_obmc_variance64x128_avx2),
TestFuncs(aom_obmc_variance64x64_c, aom_obmc_variance64x64_avx2),
TestFuncs(aom_obmc_variance64x32_c, aom_obmc_variance64x32_avx2),
TestFuncs(aom_obmc_variance32x64_c, aom_obmc_variance32x64_avx2),
TestFuncs(aom_obmc_variance32x32_c, aom_obmc_variance32x32_avx2),
TestFuncs(aom_obmc_variance32x16_c, aom_obmc_variance32x16_avx2),
TestFuncs(aom_obmc_variance16x32_c, aom_obmc_variance16x32_avx2),
TestFuncs(aom_obmc_variance16x16_c, aom_obmc_variance16x16_avx2),
TestFuncs(aom_obmc_variance16x8_c, aom_obmc_variance16x8_avx2),
TestFuncs(aom_obmc_variance8x16_c, aom_obmc_variance8x16_avx2),
TestFuncs(aom_obmc_variance8x8_c, aom_obmc_variance8x8_avx2),
TestFuncs(aom_obmc_variance8x4_c, aom_obmc_variance8x4_avx2),
TestFuncs(aom_obmc_variance4x8_c, aom_obmc_variance4x8_sse4_1),
TestFuncs(aom_obmc_variance4x4_c, aom_obmc_variance4x4_sse4_1)
};
INSTANTIATE_TEST_CASE_P(AVX2, ObmcVarianceTest,
::testing::ValuesIn(avx2_functions));
#endif // HAVE_AVX2
////////////////////////////////////////////////////////////////////////////////
// High bit-depth
////////////////////////////////////////////////////////////////////////////////

187
third_party/aom/test/pickrst_test.cc vendored Normal file
View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2018, 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/function_equivalence_test.h"
#include "test/register_state_check.h"
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "aom/aom_integer.h"
#include "av1/encoder/pickrst.h"
using libaom_test::FunctionEquivalenceTest;
#define MAX_DATA_BLOCK 384
namespace {
static const int kIterations = 100;
typedef int64_t (*lowbd_pixel_proj_error_func)(
const uint8_t *src8, int width, int height, int src_stride,
const uint8_t *dat8, int dat_stride, int32_t *flt0, int flt0_stride,
int32_t *flt1, int flt1_stride, int xq[2], const sgr_params_type *params);
typedef libaom_test::FuncParam<lowbd_pixel_proj_error_func> TestFuncs;
////////////////////////////////////////////////////////////////////////////////
// 8 bit
////////////////////////////////////////////////////////////////////////////////
typedef ::testing::tuple<const lowbd_pixel_proj_error_func>
PixelProjErrorTestParam;
class PixelProjErrorTest
: public ::testing::TestWithParam<PixelProjErrorTestParam> {
public:
virtual void SetUp() {
target_func_ = GET_PARAM(0);
src_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
sizeof(uint8_t)));
dgd_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
sizeof(uint8_t)));
flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
sizeof(int32_t)));
flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
sizeof(int32_t)));
}
virtual void TearDown() {
aom_free(src_);
aom_free(dgd_);
aom_free(flt0_);
aom_free(flt1_);
}
void runPixelProjErrorTest(int32_t run_times);
void runPixelProjErrorTest_ExtremeValues();
private:
lowbd_pixel_proj_error_func target_func_;
ACMRandom rng_;
uint8_t *src_;
uint8_t *dgd_;
int32_t *flt0_;
int32_t *flt1_;
};
void PixelProjErrorTest::runPixelProjErrorTest(int32_t run_times) {
int h_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
int v_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
const int dgd_stride = MAX_DATA_BLOCK;
const int src_stride = MAX_DATA_BLOCK;
const int flt0_stride = MAX_DATA_BLOCK;
const int flt1_stride = MAX_DATA_BLOCK;
sgr_params_type params;
int xq[2];
const int iters = run_times == 1 ? kIterations : 4;
for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
int64_t err_ref = 0, err_test = 1;
for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
dgd_[i] = rng_.Rand8();
src_[i] = rng_.Rand8();
flt0_[i] = rng_.Rand15Signed();
flt1_[i] = rng_.Rand15Signed();
}
xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
params.s[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
params.s[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
uint8_t *dgd = dgd_;
uint8_t *src = src_;
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
err_ref = av1_lowbd_pixel_proj_error_c(src, h_end, v_end, src_stride, dgd,
dgd_stride, flt0_, flt0_stride,
flt1_, flt1_stride, xq, &params);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
err_test =
target_func_(src, h_end, v_end, src_stride, dgd, dgd_stride, flt0_,
flt0_stride, flt1_, flt1_stride, xq, &params);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 10) {
printf("r0 %d r1 %d %3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", params.r[0],
params.r[1], h_end, v_end, time1, time2, time1 / time2);
}
ASSERT_EQ(err_ref, err_test);
}
}
void PixelProjErrorTest::runPixelProjErrorTest_ExtremeValues() {
const int h_start = 0;
int h_end = 192;
const int v_start = 0;
int v_end = 192;
const int dgd_stride = MAX_DATA_BLOCK;
const int src_stride = MAX_DATA_BLOCK;
const int flt0_stride = MAX_DATA_BLOCK;
const int flt1_stride = MAX_DATA_BLOCK;
sgr_params_type params;
int xq[2];
const int iters = kIterations;
for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
int64_t err_ref = 0, err_test = 1;
for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
dgd_[i] = 0;
src_[i] = 255;
flt0_[i] = rng_.Rand15Signed();
flt1_[i] = rng_.Rand15Signed();
}
xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
params.r[0] = rng_.Rand8() % MAX_RADIUS;
params.r[1] = rng_.Rand8() % MAX_RADIUS;
params.s[0] = rng_.Rand8() % MAX_RADIUS;
params.s[1] = rng_.Rand8() % MAX_RADIUS;
uint8_t *dgd = dgd_;
uint8_t *src = src_;
err_ref = av1_lowbd_pixel_proj_error_c(
src, h_end - h_start, v_end - v_start, src_stride, dgd, dgd_stride,
flt0_, flt0_stride, flt1_, flt1_stride, xq, &params);
err_test = target_func_(src, h_end - h_start, v_end - v_start, src_stride,
dgd, dgd_stride, flt0_, flt0_stride, flt1_,
flt1_stride, xq, &params);
ASSERT_EQ(err_ref, err_test);
}
}
TEST_P(PixelProjErrorTest, RandomValues) { runPixelProjErrorTest(1); }
TEST_P(PixelProjErrorTest, ExtremeValues) {
runPixelProjErrorTest_ExtremeValues();
}
TEST_P(PixelProjErrorTest, DISABLED_Speed) { runPixelProjErrorTest(200000); }
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSE4_1, PixelProjErrorTest,
::testing::Values(av1_lowbd_pixel_proj_error_sse4_1));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, PixelProjErrorTest,
::testing::Values(av1_lowbd_pixel_proj_error_avx2));
#endif // HAVE_AVX2
} // namespace

View file

@ -27,15 +27,7 @@
namespace {
using libaom_test::ACMRandom;
#define QUAN_PARAM_LIST \
const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, \
const int16_t *zbin_ptr, const int16_t *round_ptr, \
const int16_t *quant_ptr, const int16_t *quant_shift_ptr, \
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, \
const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, \
const int16_t *iscan
#define QUAN_PARAM_LIST_NO_SKIP \
#define QUAN_PARAM_LIST \
const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr, \
const int16_t *round_ptr, const int16_t *quant_ptr, \
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, \
@ -43,44 +35,34 @@ using libaom_test::ACMRandom;
const int16_t *scan, const int16_t *iscan
typedef void (*QuantizeFunc)(QUAN_PARAM_LIST);
typedef void (*QuantizeFuncHbd)(QUAN_PARAM_LIST_NO_SKIP, int log_scale);
typedef void (*QuantizeFuncNoSkip)(QUAN_PARAM_LIST_NO_SKIP);
typedef void (*QuantizeFuncHbd)(QUAN_PARAM_LIST, int log_scale);
#define HBD_QUAN_FUNC \
fn(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, quant_shift_ptr, \
qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan, log_scale)
#define LBD_QUAN_FUNC_NO_SKIP \
#define LBD_QUAN_FUNC \
fn(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, quant_shift_ptr, \
qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan)
template <QuantizeFuncHbd fn>
void highbd_quan16x16_wrapper(QUAN_PARAM_LIST) {
(void)skip_block;
const int log_scale = 0;
HBD_QUAN_FUNC;
}
template <QuantizeFuncHbd fn>
void highbd_quan32x32_wrapper(QUAN_PARAM_LIST) {
(void)skip_block;
const int log_scale = 1;
HBD_QUAN_FUNC;
}
template <QuantizeFuncHbd fn>
void highbd_quan64x64_wrapper(QUAN_PARAM_LIST) {
(void)skip_block;
const int log_scale = 2;
HBD_QUAN_FUNC;
}
template <QuantizeFuncNoSkip fn>
void lowbd_quan_wrapper(QUAN_PARAM_LIST) {
(void)skip_block;
LBD_QUAN_FUNC_NO_SKIP;
}
typedef enum { TYPE_B, TYPE_DC, TYPE_FP } QuantType;
using ::testing::tuple;
@ -125,7 +107,6 @@ class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
void QuantizeRun(bool is_loop, int q = 0, int test_num = 1) {
tran_low_t *coeff_ptr = coeff_;
const intptr_t n_coeffs = coeff_num();
const int skip_block = 0;
tran_low_t *qcoeff_ref = coeff_ptr + n_coeffs;
tran_low_t *dqcoeff_ref = qcoeff_ref + n_coeffs;
@ -158,13 +139,13 @@ class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
memset(qcoeff_ref, 0, 5 * n_coeffs * sizeof(*qcoeff_ref));
quant_ref_(coeff_ptr, n_coeffs, skip_block, zbin, round, quant,
quant_shift, qcoeff_ref, dqcoeff_ref, dequant, &eob[0],
sc->scan, sc->iscan);
quant_ref_(coeff_ptr, n_coeffs, zbin, round, quant, quant_shift,
qcoeff_ref, dqcoeff_ref, dequant, &eob[0], sc->scan,
sc->iscan);
ASM_REGISTER_STATE_CHECK(quant_(
coeff_ptr, n_coeffs, skip_block, zbin, round, quant, quant_shift,
qcoeff, dqcoeff, dequant, &eob[1], sc->scan, sc->iscan));
ASM_REGISTER_STATE_CHECK(quant_(coeff_ptr, n_coeffs, zbin, round, quant,
quant_shift, qcoeff, dqcoeff, dequant,
&eob[1], sc->scan, sc->iscan));
for (int j = 0; j < n_coeffs; ++j) {
ASSERT_EQ(qcoeff_ref[j], qcoeff[j])
@ -286,7 +267,6 @@ TEST_P(QuantizeTest, CoeffHalfDequant) {
TEST_P(QuantizeTest, DISABLED_Speed) {
tran_low_t *coeff_ptr = coeff_;
const intptr_t n_coeffs = coeff_num();
const int skip_block = 0;
tran_low_t *qcoeff_ref = coeff_ptr + n_coeffs;
tran_low_t *dqcoeff_ref = qcoeff_ref + n_coeffs;
@ -312,8 +292,8 @@ TEST_P(QuantizeTest, DISABLED_Speed) {
aom_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
quant_(coeff_ptr, n_coeffs, skip_block, zbin, round_fp, quant_fp,
quant_shift, qcoeff, dqcoeff, dequant, eob, sc->scan, sc->iscan);
quant_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, qcoeff,
dqcoeff, dequant, eob, sc->scan, sc->iscan);
}
aom_usec_timer_mark(&timer);
@ -325,33 +305,24 @@ using ::testing::make_tuple;
#if HAVE_AVX2
const QuantizeParam kQParamArrayAvx2[] = {
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_avx2>, TX_16X16, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_16X16, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_avx2>, TX_4X16, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_4X16, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_avx2>, TX_16X4, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_16X4, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_avx2>, TX_32X8, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_32X8, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_avx2>, TX_8X32, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_32x32_c>,
&lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_32X32, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_32x32_c>,
&lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_16X64, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_32x32_c>,
&lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_64X16, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_64x64_c>,
&lowbd_quan_wrapper<av1_quantize_fp_64x64_avx2>, TX_64X64, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_8X32, TYPE_FP,
AOM_BITS_8),
make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, TX_32X32,
TYPE_FP, AOM_BITS_8),
make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, TX_16X64,
TYPE_FP, AOM_BITS_8),
make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, TX_64X16,
TYPE_FP, AOM_BITS_8),
make_tuple(&av1_quantize_fp_64x64_c, &av1_quantize_fp_64x64_avx2, TX_64X64,
TYPE_FP, AOM_BITS_8),
make_tuple(&highbd_quan16x16_wrapper<av1_highbd_quantize_fp_c>,
&highbd_quan16x16_wrapper<av1_highbd_quantize_fp_avx2>, TX_16X16,
TYPE_FP, AOM_BITS_8),
@ -393,20 +364,17 @@ INSTANTIATE_TEST_CASE_P(AVX2, QuantizeTest,
#if HAVE_SSE2
const QuantizeParam kQParamArraySSE2[] = {
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_sse2>, TX_16X16, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_16X16, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_sse2>, TX_4X16, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_4X16, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_sse2>, TX_16X4, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_16X4, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_sse2>, TX_8X32, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_8X32, TYPE_FP,
AOM_BITS_8),
make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>,
&lowbd_quan_wrapper<av1_quantize_fp_sse2>, TX_32X8, TYPE_FP,
make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_32X8, TYPE_FP,
AOM_BITS_8),
make_tuple(&aom_quantize_b_c, &aom_quantize_b_sse2, TX_16X16, TYPE_B,
AOM_BITS_8),
make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, TX_16X16,
TYPE_B, AOM_BITS_8),
@ -426,4 +394,32 @@ INSTANTIATE_TEST_CASE_P(SSE2, QuantizeTest,
::testing::ValuesIn(kQParamArraySSE2));
#endif
#if HAVE_SSSE3 && ARCH_X86_64
INSTANTIATE_TEST_CASE_P(
SSSE3, QuantizeTest,
::testing::Values(make_tuple(&aom_quantize_b_c, &aom_quantize_b_ssse3,
TX_16X16, TYPE_B, AOM_BITS_8)));
// Like libvpx, the ssse3 and avx quantize tests do not pass.
// https://bugs.chromium.org/p/webm/issues/detail?id=1448
INSTANTIATE_TEST_CASE_P(
DISABLED_SSSE3_32x32, QuantizeTest,
::testing::Values(make_tuple(&aom_quantize_b_32x32_c,
&aom_quantize_b_32x32_ssse3, TX_16X16, TYPE_B,
AOM_BITS_8)));
#endif // HAVE_SSSE3 && ARCH_X86_64
#if HAVE_AVX && ARCH_X86_64
INSTANTIATE_TEST_CASE_P(
AVX, QuantizeTest,
::testing::Values(
make_tuple(&aom_quantize_b_c, &aom_quantize_b_avx, TX_16X16, TYPE_B,
AOM_BITS_8),
// Although these tests will not pass against _c, test them against each
// other so there is some minor checking.
make_tuple(&aom_quantize_b_32x32_ssse3, &aom_quantize_b_32x32_avx,
TX_32X32, TYPE_B, AOM_BITS_8)));
#endif // HAVE_AVX && ARCH_X86_64
} // namespace

View file

@ -83,7 +83,8 @@ class BuildCompDiffwtdMaskD16Test
protected:
void RunCheckOutput(buildcompdiffwtdmaskd16_func test_impl);
void RunSpeedTest(buildcompdiffwtdmaskd16_func test_impl);
void RunSpeedTest(buildcompdiffwtdmaskd16_func test_impl,
DIFFWTD_MASK_TYPE mask_type);
libaom_test::ACMRandom rnd_;
}; // class BuildCompDiffwtdMaskD16Test
@ -98,8 +99,7 @@ void BuildCompDiffwtdMaskD16Test::RunCheckOutput(
DECLARE_ALIGNED(32, uint16_t, src0[MAX_SB_SQUARE]);
DECLARE_ALIGNED(32, uint16_t, src1[MAX_SB_SQUARE]);
ConvolveParams conv_params =
get_conv_params_no_round(0, 0, 0, NULL, 0, 1, bd);
ConvolveParams conv_params = get_conv_params_no_round(0, 0, NULL, 0, 1, bd);
int in_precision =
bd + 2 * FILTER_BITS - conv_params.round_0 - conv_params.round_1 + 2;
@ -130,7 +130,7 @@ void BuildCompDiffwtdMaskD16Test::RunCheckOutput(
}
void BuildCompDiffwtdMaskD16Test::RunSpeedTest(
buildcompdiffwtdmaskd16_func test_impl) {
buildcompdiffwtdmaskd16_func test_impl, DIFFWTD_MASK_TYPE mask_type) {
const int block_idx = GET_PARAM(2);
const int bd = GET_PARAM(0);
const int width = block_size_wide[block_idx];
@ -139,8 +139,7 @@ void BuildCompDiffwtdMaskD16Test::RunSpeedTest(
DECLARE_ALIGNED(32, uint16_t, src0[MAX_SB_SQUARE]);
DECLARE_ALIGNED(32, uint16_t, src1[MAX_SB_SQUARE]);
ConvolveParams conv_params =
get_conv_params_no_round(0, 0, 0, NULL, 0, 1, bd);
ConvolveParams conv_params = get_conv_params_no_round(0, 0, NULL, 0, 1, bd);
int in_precision =
bd + 2 * FILTER_BITS - conv_params.round_0 - conv_params.round_1 + 2;
@ -150,31 +149,29 @@ void BuildCompDiffwtdMaskD16Test::RunSpeedTest(
src1[i] = rnd_.Rand16() & ((1 << in_precision) - 1);
}
const int num_loops = 1000000000 / (width + height);
const int num_loops = 10000000 / (width + height);
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < num_loops; ++i)
av1_build_compound_diffwtd_mask_d16_c(mask, DIFFWTD_38, src0, width, src1,
av1_build_compound_diffwtd_mask_d16_c(mask, mask_type, src0, width, src1,
width, height, width, &conv_params,
bd);
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
printf("av1_build_compound_diffwtd_mask_d16 c_code %3dx%-3d: %7.2f us\n",
width, height, 1000.0 * elapsed_time / num_loops);
aom_usec_timer timer1;
aom_usec_timer_start(&timer1);
for (int i = 0; i < num_loops; ++i)
test_impl(mask, DIFFWTD_38, src0, width, src1, width, height, width,
test_impl(mask, mask_type, src0, width, src1, width, height, width,
&conv_params, bd);
aom_usec_timer_mark(&timer1);
const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
printf("av1_build_compound_diffwtd_mask_d16 test_code %3dx%-3d: %7.2f us\n",
width, height, 1000.0 * elapsed_time1 / num_loops);
printf("av1_build_compound_diffwtd_mask_d16 %3dx%-3d: %7.2f \n", width,
height, elapsed_time / double(elapsed_time1));
}
#if HAVE_SSE4_1
void BuildCompDiffwtdMaskTest::RunTest(buildcompdiffwtdmaskd_func test_impl,
@ -232,7 +229,8 @@ TEST_P(BuildCompDiffwtdMaskD16Test, CheckOutput) {
}
TEST_P(BuildCompDiffwtdMaskD16Test, DISABLED_Speed) {
RunSpeedTest(GET_PARAM(1));
RunSpeedTest(GET_PARAM(1), DIFFWTD_38);
RunSpeedTest(GET_PARAM(1), DIFFWTD_38_INV);
}
#if HAVE_SSE4_1
@ -244,6 +242,14 @@ INSTANTIATE_TEST_CASE_P(
BuildParams(av1_build_compound_diffwtd_mask_d16_sse4_1));
#endif
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, BuildCompDiffwtdMaskTest,
BuildParams(av1_build_compound_diffwtd_mask_avx2));
INSTANTIATE_TEST_CASE_P(AVX2, BuildCompDiffwtdMaskD16Test,
BuildParams(av1_build_compound_diffwtd_mask_d16_avx2));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, BuildCompDiffwtdMaskD16Test,
BuildParams(av1_build_compound_diffwtd_mask_d16_neon));

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_REGISTER_STATE_CHECK_H_
#define TEST_REGISTER_STATE_CHECK_H_
#ifndef AOM_TEST_REGISTER_STATE_CHECK_H_
#define AOM_TEST_REGISTER_STATE_CHECK_H_
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
@ -145,4 +145,4 @@ class RegisterStateCheckMMX {
#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
#endif
#endif // TEST_REGISTER_STATE_CHECK_H_
#endif // AOM_TEST_REGISTER_STATE_CHECK_H_

View file

@ -52,6 +52,7 @@ class SumSquaresTest : public ::testing::TestWithParam<TestFuncs> {
aom_free(src_);
}
void RunTest(int isRandom);
void RunSpeedTest();
void GenRandomData(int width, int height, int stride) {
const int msb = 11; // Up to 12 bit input
@ -108,6 +109,38 @@ void SumSquaresTest::RunTest(int isRandom) {
}
}
void SumSquaresTest::RunSpeedTest() {
for (int block = BLOCK_4X4; block < BLOCK_SIZES_ALL; block++) {
const int width = block_size_wide[block]; // Up to 128x128
const int height = block_size_high[block]; // Up to 128x128
int stride = 4 << rnd_(7); // Up to 256 stride
while (stride < width) { // Make sure it's valid
stride = 4 << rnd_(7);
}
GenExtremeData(width, height, stride);
const int num_loops = 1000000000 / (width + height);
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < num_loops; ++i)
params_.ref_func(src_, stride, width, height);
aom_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
printf("SumSquaresTest C %3dx%-3d: %7.2f ns\n", width, height,
1000.0 * elapsed_time / num_loops);
aom_usec_timer timer1;
aom_usec_timer_start(&timer1);
for (int i = 0; i < num_loops; ++i)
params_.tst_func(src_, stride, width, height);
aom_usec_timer_mark(&timer1);
const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
printf("SumSquaresTest Test %3dx%-3d: %7.2f ns\n", width, height,
1000.0 * elapsed_time1 / num_loops);
}
}
TEST_P(SumSquaresTest, OperationCheck) {
RunTest(1); // GenRandomData
}
@ -116,6 +149,8 @@ TEST_P(SumSquaresTest, ExtremeValues) {
RunTest(0); // GenExtremeData
}
TEST_P(SumSquaresTest, DISABLED_Speed) { RunSpeedTest(); }
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
@ -125,6 +160,13 @@ INSTANTIATE_TEST_CASE_P(
#endif // HAVE_SSE2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
AVX2, SumSquaresTest,
::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c,
&aom_sum_squares_2d_i16_avx2)));
#endif // HAVE_AVX2
//////////////////////////////////////////////////////////////////////////////
// 1D version
//////////////////////////////////////////////////////////////////////////////

View file

@ -2,6 +2,18 @@ d5dfb0151c9051f8c85999255645d7a23916d3c0 *hantro_collage_w352h288.yuv
b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv
26b7f64399b84db4b4c9c915d743ec5c2619d4b9 *invalid-bug-1814.ivf
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-bug-1814.ivf.res
fa06784f23751d8c37be94160fb821e855199af4 *invalid-oss-fuzz-10061.ivf
b055f06b9a95aaa5697fa26497b592a47843a7c8 *invalid-oss-fuzz-10061.ivf.res
c9e06c4c7fb7d69fd635a1f606a5e478d60e99cf *invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf
88e18e61bd2b7457b4c71ebefbdff0029c41cc04 *invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf.res
91a5bedeb4832c1c2900736cc0f644bb63971bbc *invalid-oss-fuzz-10227.ivf
b055f06b9a95aaa5697fa26497b592a47843a7c8 *invalid-oss-fuzz-10227.ivf.res
c0960f032484579f967881cc025b71cfd7a79ee1 *invalid-oss-fuzz-9463.ivf
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-oss-fuzz-9463.ivf.res
f448caf378e250b7eea4fa2d1c3cd7ef4a3211ce *invalid-oss-fuzz-9482.ivf
b055f06b9a95aaa5697fa26497b592a47843a7c8 *invalid-oss-fuzz-9482.ivf.res
a686989de79af89136f631fd630df639c7861851 *invalid-oss-fuzz-9720.ivf
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-oss-fuzz-9720.ivf.res
a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
@ -486,4 +498,10 @@ bf241a449a28773b93e6e529a06dfc28109577e4 *av1-1-b10-00-quantizer-62.ivf
8b6eb3fff2e0db7eac775b08c745250ca591e2d9 *av1-1-b10-00-quantizer-63.ivf
63ea689d025593e5d91760785b8e446d04d4671e *av1-1-b10-00-quantizer-63.ivf.md5
a9f7ea6312a533cc6426a6145edd190d45813c37 *av1-1-b8-02-allintra.ivf
8fd8f789cfee1069d20f3e2c241f5cad7292239e *av1-1-b8-02-allintra.ivf.md5
8fd8f789cfee1069d20f3e2c241f5cad7292239e *av1-1-b8-02-allintra.ivf.md5
e69e41fee40b408b6eebcc79f266a95f2ee24f9e *av1-1-b8-03-sizedown.mkv
8c528fb3ccda959a29721566e132f730935ca32b *av1-1-b8-03-sizedown.mkv.md5
1889da5ee1708007e47bb887470ac477e1d7ba01 *av1-1-b8-03-sizeup.mkv
8de81b170635d456602dc8923a8b39c534d01fa8 *av1-1-b8-03-sizeup.mkv.md5
d3ed7de0aa8c155fe35e0f5f4203240710d31383 *park_joy_90p_8_420_monochrome.y4m
5b3f0907407b809aa66b62cb080feda8c92454ca *park_joy_90p_8_420_vertical_csp.y4m

View file

@ -20,17 +20,20 @@ include("${AOM_ROOT}/test/test_data_util.cmake")
set(AOM_UNIT_TEST_DATA_LIST_FILE "${AOM_ROOT}/test/test-data.sha1")
list(APPEND AOM_UNIT_TEST_WRAPPER_SOURCES "${AOM_CONFIG_DIR}/usage_exit.c"
list(APPEND AOM_UNIT_TEST_WRAPPER_SOURCES "${AOM_GEN_SRC_DIR}/usage_exit.c"
"${AOM_ROOT}/test/test_libaom.cc")
list(APPEND AOM_UNIT_TEST_COMMON_SOURCES
"${AOM_ROOT}/test/acm_random.h"
"${AOM_ROOT}/test/aom_integer_test.cc"
"${AOM_ROOT}/test/av1_config_test.cc"
"${AOM_ROOT}/test/blockd_test.cc"
"${AOM_ROOT}/test/clear_system_state.h"
"${AOM_ROOT}/test/codec_factory.h"
"${AOM_ROOT}/test/decode_test_driver.cc"
"${AOM_ROOT}/test/decode_test_driver.h"
"${AOM_ROOT}/test/function_equivalence_test.h"
"${AOM_ROOT}/test/log2_test.cc"
"${AOM_ROOT}/test/md5_helper.h"
"${AOM_ROOT}/test/register_state_check.h"
"${AOM_ROOT}/test/test_vectors.cc"
@ -45,6 +48,7 @@ if(CONFIG_INTERNAL_STATS)
endif()
list(APPEND AOM_UNIT_TEST_DECODER_SOURCES "${AOM_ROOT}/test/decode_api_test.cc"
"${AOM_ROOT}/test/external_frame_buffer_test.cc"
"${AOM_ROOT}/test/invalid_file_test.cc"
"${AOM_ROOT}/test/test_vector_test.cc"
"${AOM_ROOT}/test/ivf_video_source.h")
@ -53,8 +57,6 @@ list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES
"${AOM_ROOT}/test/active_map_test.cc"
"${AOM_ROOT}/test/altref_test.cc"
"${AOM_ROOT}/test/aq_segment_test.cc"
"${AOM_ROOT}/test/av1_txfm_test.cc"
"${AOM_ROOT}/test/av1_txfm_test.h"
"${AOM_ROOT}/test/borders_test.cc"
"${AOM_ROOT}/test/cpu_speed_test.cc"
"${AOM_ROOT}/test/datarate_test.cc"
@ -78,7 +80,7 @@ list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES
list(APPEND AOM_DECODE_PERF_TEST_SOURCES "${AOM_ROOT}/test/decode_perf_test.cc")
list(APPEND AOM_ENCODE_PERF_TEST_SOURCES "${AOM_ROOT}/test/encode_perf_test.cc")
list(APPEND AOM_UNIT_TEST_WEBM_SOURCES "${AOM_ROOT}/test/webm_video_source.h")
list(APPEND AOM_TEST_INTRA_PRED_SPEED_SOURCES "${AOM_CONFIG_DIR}/usage_exit.c"
list(APPEND AOM_TEST_INTRA_PRED_SPEED_SOURCES "${AOM_GEN_SRC_DIR}/usage_exit.c"
"${AOM_ROOT}/test/test_intra_pred_speed.cc")
if(NOT BUILD_SHARED_LIBS)
@ -105,6 +107,7 @@ if(NOT BUILD_SHARED_LIBS)
if(CONFIG_AV1_DECODER AND CONFIG_AV1_ENCODER)
list(APPEND AOM_UNIT_TEST_COMMON_SOURCES
"${AOM_ROOT}/test/av1_encoder_parms_get_to_decoder.cc"
"${AOM_ROOT}/test/av1_ext_tile_test.cc"
"${AOM_ROOT}/test/binary_codes_test.cc"
"${AOM_ROOT}/test/boolcoder_test.cc"
@ -168,6 +171,8 @@ if(NOT BUILD_SHARED_LIBS)
"${AOM_ROOT}/test/av1_inv_txfm1d_test.cc"
"${AOM_ROOT}/test/av1_inv_txfm2d_test.cc"
"${AOM_ROOT}/test/av1_round_shift_array_test.cc"
"${AOM_ROOT}/test/av1_txfm_test.cc"
"${AOM_ROOT}/test/av1_txfm_test.h"
"${AOM_ROOT}/test/av1_wedge_utils_test.cc"
"${AOM_ROOT}/test/blend_a64_mask_1d_test.cc"
"${AOM_ROOT}/test/blend_a64_mask_test.cc"
@ -184,11 +189,16 @@ if(NOT BUILD_SHARED_LIBS)
"${AOM_ROOT}/test/noise_model_test.cc"
"${AOM_ROOT}/test/obmc_sad_test.cc"
"${AOM_ROOT}/test/obmc_variance_test.cc"
"${AOM_ROOT}/test/pickrst_test.cc"
"${AOM_ROOT}/test/sad_test.cc"
"${AOM_ROOT}/test/subtract_test.cc"
"${AOM_ROOT}/test/reconinter_test.cc"
"${AOM_ROOT}/test/sum_squares_test.cc"
"${AOM_ROOT}/test/variance_test.cc")
"${AOM_ROOT}/test/variance_test.cc"
"${AOM_ROOT}/test/wiener_test.cc"
"${AOM_ROOT}/test/warp_filter_test.cc"
"${AOM_ROOT}/test/warp_filter_test_util.cc"
"${AOM_ROOT}/test/warp_filter_test_util.h")
list(APPEND AOM_UNIT_TEST_ENCODER_INTRIN_SSE4_1
"${AOM_ROOT}/test/av1_highbd_iht_test.cc"
@ -201,10 +211,8 @@ if(NOT BUILD_SHARED_LIBS)
list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES
"${AOM_ROOT}/test/av1_convolve_scale_test.cc"
"${AOM_ROOT}/test/av1_horz_only_frame_superres_test.cc"
"${AOM_ROOT}/test/intra_edge_test.cc"
"${AOM_ROOT}/test/warp_filter_test.cc"
"${AOM_ROOT}/test/warp_filter_test_util.cc"
"${AOM_ROOT}/test/warp_filter_test_util.h")
"${AOM_ROOT}/test/intra_edge_test.cc")
endif()
if(HAVE_SSE4_2)
@ -224,6 +232,9 @@ if(ENABLE_TESTS)
if(MSVC) # Force static run time to avoid collisions with googletest.
include("${AOM_ROOT}/build/cmake/msvc_runtime.cmake")
if(BUILD_SHARED_LIBS)
set(AOM_DISABLE_GTEST_CMAKE 1)
endif()
endif()
if(BUILD_SHARED_LIBS AND APPLE) # Silence an RPATH warning.

View file

@ -14,6 +14,18 @@ list(APPEND AOM_TEST_DATA_FILE_NAMES
"hantro_odd.yuv"
"invalid-bug-1814.ivf"
"invalid-bug-1814.ivf.res"
"invalid-oss-fuzz-10061.ivf"
"invalid-oss-fuzz-10061.ivf.res"
"invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf"
"invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf.res"
"invalid-oss-fuzz-10227.ivf"
"invalid-oss-fuzz-10227.ivf.res"
"invalid-oss-fuzz-9463.ivf"
"invalid-oss-fuzz-9463.ivf.res"
"invalid-oss-fuzz-9482.ivf"
"invalid-oss-fuzz-9482.ivf.res"
"invalid-oss-fuzz-9720.ivf"
"invalid-oss-fuzz-9720.ivf.res"
"park_joy_90p_10_420.y4m"
"park_joy_90p_10_422.y4m"
"park_joy_90p_10_444.y4m"
@ -22,6 +34,8 @@ list(APPEND AOM_TEST_DATA_FILE_NAMES
"park_joy_90p_12_444.y4m"
"park_joy_90p_8_420_a10-1.y4m"
"park_joy_90p_8_420.y4m"
"park_joy_90p_8_420_monochrome.y4m"
"park_joy_90p_8_420_vertical_csp.y4m"
"park_joy_90p_8_422.y4m"
"park_joy_90p_8_444.y4m"
"desktop_credits.y4m"
@ -494,7 +508,11 @@ if(CONFIG_AV1_DECODER)
"av1-1-b8-01-size-66x66.ivf"
"av1-1-b8-01-size-66x66.ivf.md5"
"av1-1-b8-02-allintra.ivf"
"av1-1-b8-02-allintra.ivf.md5")
"av1-1-b8-02-allintra.ivf.md5"
"av1-1-b8-03-sizeup.mkv"
"av1-1-b8-03-sizeup.mkv.md5"
"av1-1-b8-03-sizedown.mkv"
"av1-1-b8-03-sizedown.mkv.md5")
endif()
if(ENABLE_ENCODE_PERF_TESTS AND CONFIG_AV1_ENCODER)

View file

@ -119,7 +119,8 @@ TEST_P(TestVectorTest, MD5Match) {
testing::internal::scoped_ptr<libaom_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libaom_test::IVFVideoSource(filename));
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
} else if (filename.substr(filename.length() - 4, 4) == "webm" ||
filename.substr(filename.length() - 3, 3) == "mkv") {
#if CONFIG_WEBM_IO
video.reset(new libaom_test::WebMVideoSource(filename));
#else

View file

@ -131,7 +131,8 @@ const char *const kAV1TestVectors[] = {
"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-02-allintra.ivf", "av1-1-b8-03-sizedown.mkv",
"av1-1-b8-03-sizeup.mkv"
};
const int kNumAV1TestVectors = NELEMENTS(kAV1TestVectors);
#endif // CONFIG_AV1_DECODER

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_TEST_VECTORS_H_
#define TEST_TEST_VECTORS_H_
#ifndef AOM_TEST_TEST_VECTORS_H_
#define AOM_TEST_TEST_VECTORS_H_
#include "config/aom_config.h"
@ -23,4 +23,4 @@ extern const char *const kAV1TestVectors[];
} // namespace libaom_test
#endif // TEST_TEST_VECTORS_H_
#endif // AOM_TEST_TEST_VECTORS_H_

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_TRANSFORM_TEST_BASE_H_
#define TEST_TRANSFORM_TEST_BASE_H_
#ifndef AOM_TEST_TRANSFORM_TEST_BASE_H_
#define AOM_TEST_TRANSFORM_TEST_BASE_H_
#include "config/aom_config.h"
@ -339,4 +339,4 @@ class TransformTestBase {
} // namespace libaom_test
#endif // TEST_TRANSFORM_TEST_BASE_H_
#endif // AOM_TEST_TRANSFORM_TEST_BASE_H_

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_UTIL_H_
#define TEST_UTIL_H_
#ifndef AOM_TEST_UTIL_H_
#define AOM_TEST_UTIL_H_
#include <stdio.h>
#include <math.h>
@ -50,4 +50,4 @@ static INLINE double get_time_mark(aom_usec_timer *t) {
return static_cast<double>(aom_usec_timer_elapsed(t));
}
#endif // TEST_UTIL_H_
#endif // AOM_TEST_UTIL_H_

View file

@ -470,6 +470,7 @@ class MainTestClass
int byte_shift() const { return params_.bit_depth - 8; }
int block_size() const { return params_.block_size; }
int width() const { return params_.width; }
int height() const { return params_.height; }
uint32_t mask() const { return params_.mask; }
};
@ -583,18 +584,19 @@ void MainTestClass<VarianceFunctionType>::SpeedTest() {
CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask();
}
}
unsigned int sse1, sse2, var1, var2;
unsigned int sse;
const int stride = width();
int run_time = 1000000000 / block_size();
ASM_REGISTER_STATE_CHECK(var1 =
params_.func(src_, stride, ref_, stride, &sse1));
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_time; ++i) {
ASM_REGISTER_STATE_CHECK(
var2 = params_.func(src_, stride, ref_, stride, &sse2));
params_.func(src_, stride, ref_, stride, &sse);
}
EXPECT_EQ(var1, var2);
EXPECT_EQ(sse1, sse2);
aom_usec_timer_mark(&timer);
const double elapsed_time =
static_cast<double>(aom_usec_timer_elapsed(&timer));
printf("Variance %dx%d : %7.2fns\n", width(), height(), elapsed_time);
}
////////////////////////////////////////////////////////////////////////////////
@ -1183,6 +1185,7 @@ TEST_P(AvxHBDVarianceTest, Zero) { ZeroTest(); }
TEST_P(AvxHBDVarianceTest, Ref) { RefTest(); }
TEST_P(AvxHBDVarianceTest, RefStride) { RefStrideTest(); }
TEST_P(AvxHBDVarianceTest, OneQuarter) { OneQuarterTest(); }
TEST_P(AvxHBDVarianceTest, DISABLED_Speed) { SpeedTest(); }
TEST_P(AvxHBDSubpelVarianceTest, Ref) { RefTest(); }
TEST_P(AvxHBDSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); }
TEST_P(AvxHBDSubpelAvgVarianceTest, Ref) { RefTest(); }
@ -1607,39 +1610,71 @@ INSTANTIATE_TEST_CASE_P(
MseParams(3, 3, &aom_highbd_8_mse8x8_sse2)));
*/
INSTANTIATE_TEST_CASE_P(
SSE2, AvxHBDVarianceTest,
::testing::Values(
VarianceParams(6, 6, &aom_highbd_12_variance64x64_sse2, 12),
VarianceParams(6, 5, &aom_highbd_12_variance64x32_sse2, 12),
VarianceParams(5, 6, &aom_highbd_12_variance32x64_sse2, 12),
VarianceParams(5, 5, &aom_highbd_12_variance32x32_sse2, 12),
VarianceParams(5, 4, &aom_highbd_12_variance32x16_sse2, 12),
VarianceParams(4, 5, &aom_highbd_12_variance16x32_sse2, 12),
VarianceParams(4, 4, &aom_highbd_12_variance16x16_sse2, 12),
VarianceParams(4, 3, &aom_highbd_12_variance16x8_sse2, 12),
VarianceParams(3, 4, &aom_highbd_12_variance8x16_sse2, 12),
VarianceParams(3, 3, &aom_highbd_12_variance8x8_sse2, 12),
VarianceParams(6, 6, &aom_highbd_10_variance64x64_sse2, 10),
VarianceParams(6, 5, &aom_highbd_10_variance64x32_sse2, 10),
VarianceParams(5, 6, &aom_highbd_10_variance32x64_sse2, 10),
VarianceParams(5, 5, &aom_highbd_10_variance32x32_sse2, 10),
VarianceParams(5, 4, &aom_highbd_10_variance32x16_sse2, 10),
VarianceParams(4, 5, &aom_highbd_10_variance16x32_sse2, 10),
VarianceParams(4, 4, &aom_highbd_10_variance16x16_sse2, 10),
VarianceParams(4, 3, &aom_highbd_10_variance16x8_sse2, 10),
VarianceParams(3, 4, &aom_highbd_10_variance8x16_sse2, 10),
VarianceParams(3, 3, &aom_highbd_10_variance8x8_sse2, 10),
VarianceParams(6, 6, &aom_highbd_8_variance64x64_sse2, 8),
VarianceParams(6, 5, &aom_highbd_8_variance64x32_sse2, 8),
VarianceParams(5, 6, &aom_highbd_8_variance32x64_sse2, 8),
VarianceParams(5, 5, &aom_highbd_8_variance32x32_sse2, 8),
VarianceParams(5, 4, &aom_highbd_8_variance32x16_sse2, 8),
VarianceParams(4, 5, &aom_highbd_8_variance16x32_sse2, 8),
VarianceParams(4, 4, &aom_highbd_8_variance16x16_sse2, 8),
VarianceParams(4, 3, &aom_highbd_8_variance16x8_sse2, 8),
VarianceParams(3, 4, &aom_highbd_8_variance8x16_sse2, 8),
VarianceParams(3, 3, &aom_highbd_8_variance8x8_sse2, 8)));
const VarianceParams kArrayHBDVariance_sse2[] = {
VarianceParams(7, 7, &aom_highbd_12_variance128x128_sse2, 12),
VarianceParams(7, 6, &aom_highbd_12_variance128x64_sse2, 12),
VarianceParams(6, 7, &aom_highbd_12_variance64x128_sse2, 12),
VarianceParams(6, 6, &aom_highbd_12_variance64x64_sse2, 12),
VarianceParams(6, 5, &aom_highbd_12_variance64x32_sse2, 12),
VarianceParams(5, 6, &aom_highbd_12_variance32x64_sse2, 12),
VarianceParams(5, 5, &aom_highbd_12_variance32x32_sse2, 12),
VarianceParams(5, 4, &aom_highbd_12_variance32x16_sse2, 12),
VarianceParams(4, 5, &aom_highbd_12_variance16x32_sse2, 12),
VarianceParams(4, 4, &aom_highbd_12_variance16x16_sse2, 12),
VarianceParams(4, 3, &aom_highbd_12_variance16x8_sse2, 12),
VarianceParams(3, 4, &aom_highbd_12_variance8x16_sse2, 12),
VarianceParams(3, 3, &aom_highbd_12_variance8x8_sse2, 12),
VarianceParams(7, 7, &aom_highbd_10_variance128x128_sse2, 10),
VarianceParams(7, 6, &aom_highbd_10_variance128x64_sse2, 10),
VarianceParams(6, 7, &aom_highbd_10_variance64x128_sse2, 10),
VarianceParams(6, 6, &aom_highbd_10_variance64x64_sse2, 10),
VarianceParams(6, 5, &aom_highbd_10_variance64x32_sse2, 10),
VarianceParams(5, 6, &aom_highbd_10_variance32x64_sse2, 10),
VarianceParams(5, 5, &aom_highbd_10_variance32x32_sse2, 10),
VarianceParams(5, 4, &aom_highbd_10_variance32x16_sse2, 10),
VarianceParams(4, 5, &aom_highbd_10_variance16x32_sse2, 10),
VarianceParams(4, 4, &aom_highbd_10_variance16x16_sse2, 10),
VarianceParams(4, 3, &aom_highbd_10_variance16x8_sse2, 10),
VarianceParams(3, 4, &aom_highbd_10_variance8x16_sse2, 10),
VarianceParams(3, 3, &aom_highbd_10_variance8x8_sse2, 10),
VarianceParams(7, 7, &aom_highbd_8_variance128x128_sse2, 8),
VarianceParams(7, 6, &aom_highbd_8_variance128x64_sse2, 8),
VarianceParams(6, 7, &aom_highbd_8_variance64x128_sse2, 8),
VarianceParams(6, 6, &aom_highbd_8_variance64x64_sse2, 8),
VarianceParams(6, 5, &aom_highbd_8_variance64x32_sse2, 8),
VarianceParams(5, 6, &aom_highbd_8_variance32x64_sse2, 8),
VarianceParams(5, 5, &aom_highbd_8_variance32x32_sse2, 8),
VarianceParams(5, 4, &aom_highbd_8_variance32x16_sse2, 8),
VarianceParams(4, 5, &aom_highbd_8_variance16x32_sse2, 8),
VarianceParams(4, 4, &aom_highbd_8_variance16x16_sse2, 8),
VarianceParams(4, 3, &aom_highbd_8_variance16x8_sse2, 8),
VarianceParams(3, 4, &aom_highbd_8_variance8x16_sse2, 8),
VarianceParams(3, 3, &aom_highbd_8_variance8x8_sse2, 8)
};
INSTANTIATE_TEST_CASE_P(SSE2, AvxHBDVarianceTest,
::testing::ValuesIn(kArrayHBDVariance_sse2));
#if HAVE_AVX2
const VarianceParams kArrayHBDVariance_avx2[] = {
VarianceParams(7, 7, &aom_highbd_10_variance128x128_avx2, 10),
VarianceParams(7, 6, &aom_highbd_10_variance128x64_avx2, 10),
VarianceParams(6, 7, &aom_highbd_10_variance64x128_avx2, 10),
VarianceParams(6, 6, &aom_highbd_10_variance64x64_avx2, 10),
VarianceParams(6, 5, &aom_highbd_10_variance64x32_avx2, 10),
VarianceParams(5, 6, &aom_highbd_10_variance32x64_avx2, 10),
VarianceParams(5, 5, &aom_highbd_10_variance32x32_avx2, 10),
VarianceParams(5, 4, &aom_highbd_10_variance32x16_avx2, 10),
VarianceParams(4, 5, &aom_highbd_10_variance16x32_avx2, 10),
VarianceParams(4, 4, &aom_highbd_10_variance16x16_avx2, 10),
VarianceParams(4, 3, &aom_highbd_10_variance16x8_avx2, 10),
VarianceParams(3, 4, &aom_highbd_10_variance8x16_avx2, 10),
VarianceParams(3, 3, &aom_highbd_10_variance8x8_avx2, 10)
};
INSTANTIATE_TEST_CASE_P(AVX2, AvxHBDVarianceTest,
::testing::ValuesIn(kArrayHBDVariance_avx2));
#endif // HAVE_AVX2
const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = {
SubpelVarianceParams(6, 6, &aom_highbd_12_sub_pixel_variance64x64_sse2, 12),

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_VIDEO_SOURCE_H_
#define TEST_VIDEO_SOURCE_H_
#ifndef AOM_TEST_VIDEO_SOURCE_H_
#define AOM_TEST_VIDEO_SOURCE_H_
#if defined(_WIN32)
#undef NOMINMAX
@ -256,4 +256,4 @@ class CompressedVideoSource {
} // namespace libaom_test
#endif // TEST_VIDEO_SOURCE_H_
#endif // AOM_TEST_VIDEO_SOURCE_H_

View file

@ -17,20 +17,40 @@ using libaom_test::AV1HighbdWarpFilter::AV1HighbdWarpFilterTest;
using libaom_test::AV1WarpFilter::AV1WarpFilterTest;
namespace {
#if HAVE_SSE4_1
TEST_P(AV1WarpFilterTest, CheckOutput) { RunCheckOutput(GET_PARAM(3)); }
TEST_P(AV1WarpFilterTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(3)); }
TEST_P(AV1WarpFilterTest, CheckOutput) {
RunCheckOutput(::testing::get<3>(GET_PARAM(0)));
}
TEST_P(AV1WarpFilterTest, DISABLED_Speed) {
RunSpeedTest(::testing::get<3>(GET_PARAM(0)));
}
INSTANTIATE_TEST_CASE_P(
C, AV1WarpFilterTest,
libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_c));
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
SSE4_1, AV1WarpFilterTest,
libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_sse4_1));
TEST_P(AV1HighbdWarpFilterTest, CheckOutput) { RunCheckOutput(GET_PARAM(4)); }
TEST_P(AV1HighbdWarpFilterTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(4)); }
TEST_P(AV1HighbdWarpFilterTest, CheckOutput) {
RunCheckOutput(::testing::get<4>(GET_PARAM(0)));
}
TEST_P(AV1HighbdWarpFilterTest, DISABLED_Speed) {
RunSpeedTest(::testing::get<4>(GET_PARAM(0)));
}
INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdWarpFilterTest,
libaom_test::AV1HighbdWarpFilter::BuildParams(
av1_highbd_warp_affine_sse4_1));
#endif // HAVE_SSE4_1
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
NEON, AV1WarpFilterTest,
libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_neon));
#endif // HAVE_NEON
} // namespace

View file

@ -28,22 +28,35 @@ int32_t random_warped_param(libaom_test::ACMRandom *rnd, int bits) {
void generate_warped_model(libaom_test::ACMRandom *rnd, int32_t *mat,
int16_t *alpha, int16_t *beta, int16_t *gamma,
int16_t *delta) {
int16_t *delta, const int is_alpha_zero,
const int is_beta_zero, const int is_gamma_zero,
const int is_delta_zero) {
while (1) {
int rnd8 = rnd->Rand8() & 3;
mat[0] = random_warped_param(rnd, WARPEDMODEL_PREC_BITS + 6);
mat[1] = random_warped_param(rnd, WARPEDMODEL_PREC_BITS + 6);
mat[2] = (random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3)) +
(1 << WARPEDMODEL_PREC_BITS);
mat[3] = random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3);
// 50/50 chance of generating ROTZOOM vs. AFFINE models
if (rnd->Rand8() & 1) {
if (rnd8 <= 1) {
// AFFINE
mat[4] = random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3);
mat[5] = (random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3)) +
(1 << WARPEDMODEL_PREC_BITS);
} else {
} else if (rnd8 == 2) {
mat[4] = -mat[3];
mat[5] = mat[2];
} else {
mat[4] = random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3);
mat[5] = (random_warped_param(rnd, WARPEDMODEL_PREC_BITS - 3)) +
(1 << WARPEDMODEL_PREC_BITS);
if (is_alpha_zero == 1) mat[2] = 1 << WARPEDMODEL_PREC_BITS;
if (is_beta_zero == 1) mat[3] = 0;
if (is_gamma_zero == 1) mat[4] = 0;
if (is_delta_zero == 1)
mat[5] = (((int64_t)mat[3] * mat[4] + (mat[2] / 2)) / mat[2]) +
(1 << WARPEDMODEL_PREC_BITS);
}
// Calculate the derived parameters and check that they are suitable
@ -78,14 +91,16 @@ void generate_warped_model(libaom_test::ACMRandom *rnd, int32_t *mat,
}
namespace AV1WarpFilter {
::testing::internal::ParamGenerator<WarpTestParam> BuildParams(
::testing::internal::ParamGenerator<WarpTestParams> BuildParams(
warp_affine_func filter) {
const WarpTestParam params[] = {
WarpTestParam params[] = {
make_tuple(4, 4, 50000, filter), make_tuple(8, 8, 50000, filter),
make_tuple(64, 64, 1000, filter), make_tuple(4, 16, 20000, filter),
make_tuple(32, 8, 10000, filter),
};
return ::testing::ValuesIn(params);
return ::testing::Combine(::testing::ValuesIn(params),
::testing::Values(0, 1), ::testing::Values(0, 1),
::testing::Values(0, 1), ::testing::Values(0, 1));
}
AV1WarpFilterTest::~AV1WarpFilterTest() {}
@ -97,7 +112,13 @@ void AV1WarpFilterTest::RunSpeedTest(warp_affine_func test_impl) {
const int w = 128, h = 128;
const int border = 16;
const int stride = w + 2 * border;
const int out_w = GET_PARAM(0), out_h = GET_PARAM(1);
WarpTestParam params = GET_PARAM(0);
const int out_w = ::testing::get<0>(params),
out_h = ::testing::get<1>(params);
const int is_alpha_zero = GET_PARAM(1);
const int is_beta_zero = GET_PARAM(2);
const int is_gamma_zero = GET_PARAM(3);
const int is_delta_zero = GET_PARAM(4);
int sub_x, sub_y;
const int bd = 8;
@ -110,10 +131,11 @@ void AV1WarpFilterTest::RunSpeedTest(warp_affine_func test_impl) {
uint8_t *output = new uint8_t[output_n];
int32_t mat[8];
int16_t alpha, beta, gamma, delta;
ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
ConvolveParams conv_params = get_conv_params(0, 0, bd);
CONV_BUF_TYPE *dsta = new CONV_BUF_TYPE[output_n];
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta);
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta,
is_alpha_zero, is_beta_zero, is_gamma_zero,
is_delta_zero);
for (int r = 0; r < h; ++r)
for (int c = 0; c < w; ++c) input[r * stride + c] = rnd_.Rand8();
@ -126,7 +148,7 @@ void AV1WarpFilterTest::RunSpeedTest(warp_affine_func test_impl) {
sub_y = 0;
int do_average = 0;
conv_params = get_conv_params_no_round(0, do_average, 0, dsta, out_w, 1, bd);
conv_params = get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd);
conv_params.use_jnt_comp_avg = 0;
const int num_loops = 1000000000 / (out_w + out_h);
@ -150,8 +172,14 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) {
const int w = 128, h = 128;
const int border = 16;
const int stride = w + 2 * border;
const int out_w = GET_PARAM(0), out_h = GET_PARAM(1);
const int num_iters = GET_PARAM(2);
WarpTestParam params = GET_PARAM(0);
const int is_alpha_zero = GET_PARAM(1);
const int is_beta_zero = GET_PARAM(2);
const int is_gamma_zero = GET_PARAM(3);
const int is_delta_zero = GET_PARAM(4);
const int out_w = ::testing::get<0>(params),
out_h = ::testing::get<1>(params);
const int num_iters = ::testing::get<2>(params);
int i, j, sub_x, sub_y;
const int bd = 8;
@ -164,7 +192,7 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) {
uint8_t *output2 = new uint8_t[output_n];
int32_t mat[8];
int16_t alpha, beta, gamma, delta;
ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
ConvolveParams conv_params = get_conv_params(0, 0, bd);
CONV_BUF_TYPE *dsta = new CONV_BUF_TYPE[output_n];
CONV_BUF_TYPE *dstb = new CONV_BUF_TYPE[output_n];
for (int i = 0; i < output_n; ++i) output[i] = output2[i] = rnd_.Rand8();
@ -180,15 +208,18 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) {
const int use_no_round = rnd_.Rand8() & 1;
for (sub_x = 0; sub_x < 2; ++sub_x)
for (sub_y = 0; sub_y < 2; ++sub_y) {
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta);
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta,
is_alpha_zero, is_beta_zero, is_gamma_zero,
is_delta_zero);
for (int ii = 0; ii < 2; ++ii) {
for (int jj = 0; jj < 5; ++jj) {
for (int do_average = 0; do_average <= 1; ++do_average) {
if (use_no_round) {
conv_params = get_conv_params_no_round(0, do_average, 0, dsta,
out_w, 1, bd);
conv_params =
get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd);
} else {
conv_params = get_conv_params(0, 0, 0, bd);
conv_params = get_conv_params(0, 0, bd);
}
if (jj >= 4) {
conv_params.use_jnt_comp_avg = 0;
@ -201,8 +232,8 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) {
out_h, out_w, sub_x, sub_y, &conv_params, alpha,
beta, gamma, delta);
if (use_no_round) {
conv_params = get_conv_params_no_round(0, do_average, 0, dstb,
out_w, 1, bd);
conv_params =
get_conv_params_no_round(do_average, 0, dstb, out_w, 1, bd);
}
if (jj >= 4) {
conv_params.use_jnt_comp_avg = 0;
@ -246,7 +277,7 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) {
} // namespace AV1WarpFilter
namespace AV1HighbdWarpFilter {
::testing::internal::ParamGenerator<HighbdWarpTestParam> BuildParams(
::testing::internal::ParamGenerator<HighbdWarpTestParams> BuildParams(
highbd_warp_affine_func filter) {
const HighbdWarpTestParam params[] = {
make_tuple(4, 4, 100, 8, filter), make_tuple(8, 8, 100, 8, filter),
@ -258,7 +289,9 @@ namespace AV1HighbdWarpFilter {
make_tuple(64, 64, 100, 12, filter), make_tuple(4, 16, 100, 12, filter),
make_tuple(32, 8, 100, 12, filter),
};
return ::testing::ValuesIn(params);
return ::testing::Combine(::testing::ValuesIn(params),
::testing::Values(0, 1), ::testing::Values(0, 1),
::testing::Values(0, 1), ::testing::Values(0, 1));
}
AV1HighbdWarpFilterTest::~AV1HighbdWarpFilterTest() {}
@ -272,8 +305,13 @@ void AV1HighbdWarpFilterTest::RunSpeedTest(highbd_warp_affine_func test_impl) {
const int w = 128, h = 128;
const int border = 16;
const int stride = w + 2 * border;
const int out_w = GET_PARAM(0), out_h = GET_PARAM(1);
const int bd = GET_PARAM(3);
HighbdWarpTestParam param = GET_PARAM(0);
const int is_alpha_zero = GET_PARAM(1);
const int is_beta_zero = GET_PARAM(2);
const int is_gamma_zero = GET_PARAM(3);
const int is_delta_zero = GET_PARAM(4);
const int out_w = ::testing::get<0>(param), out_h = ::testing::get<1>(param);
const int bd = ::testing::get<3>(param);
const int mask = (1 << bd) - 1;
int sub_x, sub_y;
@ -285,10 +323,12 @@ void AV1HighbdWarpFilterTest::RunSpeedTest(highbd_warp_affine_func test_impl) {
uint16_t *output = new uint16_t[output_n];
int32_t mat[8];
int16_t alpha, beta, gamma, delta;
ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
ConvolveParams conv_params = get_conv_params(0, 0, bd);
CONV_BUF_TYPE *dsta = new CONV_BUF_TYPE[output_n];
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta);
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta,
is_alpha_zero, is_beta_zero, is_gamma_zero,
is_delta_zero);
// Generate an input block and extend its borders horizontally
for (int r = 0; r < h; ++r)
for (int c = 0; c < w; ++c) input[r * stride + c] = rnd_.Rand16() & mask;
@ -303,7 +343,7 @@ void AV1HighbdWarpFilterTest::RunSpeedTest(highbd_warp_affine_func test_impl) {
sub_y = 0;
int do_average = 0;
conv_params.use_jnt_comp_avg = 0;
conv_params = get_conv_params_no_round(0, do_average, 0, dsta, out_w, 1, bd);
conv_params = get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd);
const int num_loops = 1000000000 / (out_w + out_h);
aom_usec_timer timer;
@ -328,9 +368,14 @@ void AV1HighbdWarpFilterTest::RunCheckOutput(
const int w = 128, h = 128;
const int border = 16;
const int stride = w + 2 * border;
const int out_w = GET_PARAM(0), out_h = GET_PARAM(1);
const int num_iters = GET_PARAM(2);
const int bd = GET_PARAM(3);
HighbdWarpTestParam param = GET_PARAM(0);
const int is_alpha_zero = GET_PARAM(1);
const int is_beta_zero = GET_PARAM(2);
const int is_gamma_zero = GET_PARAM(3);
const int is_delta_zero = GET_PARAM(4);
const int out_w = ::testing::get<0>(param), out_h = ::testing::get<1>(param);
const int bd = ::testing::get<3>(param);
const int num_iters = ::testing::get<2>(param);
const int mask = (1 << bd) - 1;
int i, j, sub_x, sub_y;
@ -343,7 +388,7 @@ void AV1HighbdWarpFilterTest::RunCheckOutput(
uint16_t *output2 = new uint16_t[output_n];
int32_t mat[8];
int16_t alpha, beta, gamma, delta;
ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
ConvolveParams conv_params = get_conv_params(0, 0, bd);
CONV_BUF_TYPE *dsta = new CONV_BUF_TYPE[output_n];
CONV_BUF_TYPE *dstb = new CONV_BUF_TYPE[output_n];
for (int i = 0; i < output_n; ++i) output[i] = output2[i] = rnd_.Rand16();
@ -361,15 +406,17 @@ void AV1HighbdWarpFilterTest::RunCheckOutput(
const int use_no_round = rnd_.Rand8() & 1;
for (sub_x = 0; sub_x < 2; ++sub_x)
for (sub_y = 0; sub_y < 2; ++sub_y) {
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta);
generate_warped_model(&rnd_, mat, &alpha, &beta, &gamma, &delta,
is_alpha_zero, is_beta_zero, is_gamma_zero,
is_delta_zero);
for (int ii = 0; ii < 2; ++ii) {
for (int jj = 0; jj < 5; ++jj) {
for (int do_average = 0; do_average <= 1; ++do_average) {
if (use_no_round) {
conv_params = get_conv_params_no_round(0, do_average, 0, dsta,
out_w, 1, bd);
conv_params =
get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd);
} else {
conv_params = get_conv_params(0, 0, 0, bd);
conv_params = get_conv_params(0, 0, bd);
}
if (jj >= 4) {
conv_params.use_jnt_comp_avg = 0;
@ -385,8 +432,8 @@ void AV1HighbdWarpFilterTest::RunCheckOutput(
if (use_no_round) {
// TODO(angiebird): Change this to test_impl once we have SIMD
// implementation
conv_params = get_conv_params_no_round(0, do_average, 0, dstb,
out_w, 1, bd);
conv_params =
get_conv_params_no_round(do_average, 0, dstb, out_w, 1, bd);
}
if (jj >= 4) {
conv_params.use_jnt_comp_avg = 0;

View file

@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef TEST_WARP_FILTER_TEST_UTIL_H_
#define TEST_WARP_FILTER_TEST_UTIL_H_
#ifndef AOM_TEST_WARP_FILTER_TEST_UTIL_H_
#define AOM_TEST_WARP_FILTER_TEST_UTIL_H_
#include "config/av1_rtcd.h"
#include "config/aom_dsp_rtcd.h"
@ -28,7 +28,8 @@ namespace libaom_test {
void generate_warped_model(libaom_test::ACMRandom *rnd, int32_t *mat,
int16_t *alpha, int16_t *beta, int16_t *gamma,
int16_t *delta);
int16_t *delta, int is_alpha_zero, int is_beta_zero,
int is_gamma_zero, int is_delta_zero);
namespace AV1WarpFilter {
@ -41,11 +42,12 @@ typedef void (*warp_affine_func)(const int32_t *mat, const uint8_t *ref,
int16_t beta, int16_t gamma, int16_t delta);
typedef ::testing::tuple<int, int, int, warp_affine_func> WarpTestParam;
typedef ::testing::tuple<WarpTestParam, int, int, int, int> WarpTestParams;
::testing::internal::ParamGenerator<WarpTestParam> BuildParams(
::testing::internal::ParamGenerator<WarpTestParams> BuildParams(
warp_affine_func filter);
class AV1WarpFilterTest : public ::testing::TestWithParam<WarpTestParam> {
class AV1WarpFilterTest : public ::testing::TestWithParam<WarpTestParams> {
public:
virtual ~AV1WarpFilterTest();
virtual void SetUp();
@ -73,12 +75,14 @@ typedef void (*highbd_warp_affine_func)(const int32_t *mat, const uint16_t *ref,
typedef ::testing::tuple<int, int, int, int, highbd_warp_affine_func>
HighbdWarpTestParam;
typedef ::testing::tuple<HighbdWarpTestParam, int, int, int, int>
HighbdWarpTestParams;
::testing::internal::ParamGenerator<HighbdWarpTestParam> BuildParams(
::testing::internal::ParamGenerator<HighbdWarpTestParams> BuildParams(
highbd_warp_affine_func filter);
class AV1HighbdWarpFilterTest
: public ::testing::TestWithParam<HighbdWarpTestParam> {
: public ::testing::TestWithParam<HighbdWarpTestParams> {
public:
virtual ~AV1HighbdWarpFilterTest();
virtual void SetUp();
@ -96,4 +100,4 @@ class AV1HighbdWarpFilterTest
} // namespace libaom_test
#endif // TEST_WARP_FILTER_TEST_UTIL_H_
#endif // AOM_TEST_WARP_FILTER_TEST_UTIL_H_

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_WEBM_VIDEO_SOURCE_H_
#define TEST_WEBM_VIDEO_SOURCE_H_
#ifndef AOM_TEST_WEBM_VIDEO_SOURCE_H_
#define AOM_TEST_WEBM_VIDEO_SOURCE_H_
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
@ -93,4 +93,4 @@ class WebMVideoSource : public CompressedVideoSource {
} // namespace libaom_test
#endif // TEST_WEBM_VIDEO_SOURCE_H_
#endif // AOM_TEST_WEBM_VIDEO_SOURCE_H_

280
third_party/aom/test/wiener_test.cc vendored Normal file
View file

@ -0,0 +1,280 @@
/*
* Copyright (c) 2018, 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 <vector>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/function_equivalence_test.h"
#include "test/register_state_check.h"
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "aom/aom_integer.h"
#include "av1/encoder/pickrst.h"
#define MAX_WIENER_BLOCK 384
#define MAX_DATA_BLOCK (MAX_WIENER_BLOCK + WIENER_WIN)
using libaom_test::FunctionEquivalenceTest;
namespace {
static void compute_stats_win_opt_c(int wiener_win, const uint8_t *dgd,
const uint8_t *src, int h_start, int h_end,
int v_start, int v_end, int dgd_stride,
int src_stride, double *M, double *H) {
ASSERT_TRUE(wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA);
int i, j, k, l, m, n;
const int pixel_count = (h_end - h_start) * (v_end - v_start);
const int wiener_win2 = wiener_win * wiener_win;
const int wiener_halfwin = (wiener_win >> 1);
const double avg =
find_average(dgd, h_start, h_end, v_start, v_end, dgd_stride);
std::vector<std::vector<int64_t> > M_int(wiener_win,
std::vector<int64_t>(wiener_win, 0));
std::vector<std::vector<int64_t> > H_int(
wiener_win * wiener_win, std::vector<int64_t>(wiener_win * 8, 0));
std::vector<std::vector<int32_t> > sumY(wiener_win,
std::vector<int32_t>(wiener_win, 0));
int32_t sumX = 0;
const uint8_t *dgd_win = dgd - wiener_halfwin * dgd_stride - wiener_halfwin;
for (i = v_start; i < v_end; i++) {
for (j = h_start; j < h_end; j += 2) {
const uint8_t X1 = src[i * src_stride + j];
const uint8_t X2 = src[i * src_stride + j + 1];
sumX += X1 + X2;
const uint8_t *dgd_ij = dgd_win + i * dgd_stride + j;
for (k = 0; k < wiener_win; k++) {
for (l = 0; l < wiener_win; l++) {
const uint8_t *dgd_ijkl = dgd_ij + k * dgd_stride + l;
int64_t *H_int_temp = &H_int[(l * wiener_win + k)][0];
const uint8_t D1 = dgd_ijkl[0];
const uint8_t D2 = dgd_ijkl[1];
sumY[k][l] += D1 + D2;
M_int[l][k] += D1 * X1 + D2 * X2;
for (m = 0; m < wiener_win; m++) {
for (n = 0; n < wiener_win; n++) {
H_int_temp[m * 8 + n] += D1 * dgd_ij[n + dgd_stride * m] +
D2 * dgd_ij[n + dgd_stride * m + 1];
}
}
}
}
}
}
const double avg_square_sum = avg * avg * pixel_count;
for (k = 0; k < wiener_win; k++) {
for (l = 0; l < wiener_win; l++) {
M[l * wiener_win + k] =
M_int[l][k] + avg_square_sum - avg * (sumX + sumY[k][l]);
for (m = 0; m < wiener_win; m++) {
for (n = 0; n < wiener_win; n++) {
H[(l * wiener_win + k) * wiener_win2 + m * wiener_win + n] =
H_int[(l * wiener_win + k)][n * 8 + m] + avg_square_sum -
avg * (sumY[k][l] + sumY[n][m]);
}
}
}
}
}
void compute_stats_opt_c(int wiener_win, const uint8_t *dgd, const uint8_t *src,
int h_start, int h_end, int v_start, int v_end,
int dgd_stride, int src_stride, double *M, double *H) {
if (wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA) {
compute_stats_win_opt_c(wiener_win, dgd, src, h_start, h_end, v_start,
v_end, dgd_stride, src_stride, M, H);
} else {
av1_compute_stats_c(wiener_win, dgd, src, h_start, h_end, v_start, v_end,
dgd_stride, src_stride, M, H);
}
}
static const int kIterations = 100;
static const double min_error = (double)(0.01);
typedef void (*compute_stats_Func)(int wiener_win, const uint8_t *dgd,
const uint8_t *src, int h_start, int h_end,
int v_start, int v_end, int dgd_stride,
int src_stride, double *M, double *H);
typedef libaom_test::FuncParam<compute_stats_Func> TestFuncs;
////////////////////////////////////////////////////////////////////////////////
// 8 bit
////////////////////////////////////////////////////////////////////////////////
typedef ::testing::tuple<const compute_stats_Func> WienerTestParam;
class WienerTest : public ::testing::TestWithParam<WienerTestParam> {
public:
virtual void SetUp() { target_func_ = GET_PARAM(0); }
void runWienerTest(const int32_t wiener_win, int32_t run_times);
void runWienerTest_ExtremeValues(const int32_t wiener_win);
private:
compute_stats_Func target_func_;
ACMRandom rng_;
};
void WienerTest::runWienerTest(const int32_t wiener_win, int32_t run_times) {
const int32_t wiener_halfwin = wiener_win >> 1;
const int32_t wiener_win2 = wiener_win * wiener_win;
DECLARE_ALIGNED(32, uint8_t, dgd_buf[MAX_DATA_BLOCK * MAX_DATA_BLOCK]);
DECLARE_ALIGNED(32, uint8_t, src_buf[MAX_DATA_BLOCK * MAX_DATA_BLOCK]);
DECLARE_ALIGNED(32, double, M_ref[WIENER_WIN2]);
DECLARE_ALIGNED(32, double, H_ref[WIENER_WIN2 * WIENER_WIN2]);
DECLARE_ALIGNED(32, double, M_test[WIENER_WIN2]);
DECLARE_ALIGNED(32, double, H_test[WIENER_WIN2 * WIENER_WIN2]);
const int h_start = ((rng_.Rand16() % (MAX_WIENER_BLOCK / 2)) & (~7));
int h_end =
run_times != 1 ? 256 : ((rng_.Rand16() % MAX_WIENER_BLOCK) & (~7)) + 8;
const int v_start = ((rng_.Rand16() % (MAX_WIENER_BLOCK / 2)) & (~7));
int v_end =
run_times != 1 ? 256 : ((rng_.Rand16() % MAX_WIENER_BLOCK) & (~7)) + 8;
const int dgd_stride = h_end;
const int src_stride = MAX_DATA_BLOCK;
const int iters = run_times == 1 ? kIterations : 2;
for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
dgd_buf[i] = rng_.Rand8();
src_buf[i] = rng_.Rand8();
}
uint8_t *dgd = dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin;
uint8_t *src = src_buf;
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
av1_compute_stats_c(wiener_win, dgd, src, h_start, h_end, v_start, v_end,
dgd_stride, src_stride, M_ref, H_ref);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
target_func_(wiener_win, dgd, src, h_start, h_end, v_start, v_end,
dgd_stride, src_stride, M_test, H_test);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
if (run_times > 10) {
printf("win %d %3dx%-3d:%7.2f/%7.2fns", wiener_win, h_end, v_end, time1,
time2);
printf("(%3.2f)\n", time1 / time2);
}
int failed = 0;
for (int i = 0; i < wiener_win2; ++i) {
if (fabs(M_ref[i] - M_test[i]) > min_error) {
failed = 1;
printf("win %d M iter %d [%4d] ref %6.0f test %6.0f \n", wiener_win,
iter, i, M_ref[i], M_test[i]);
break;
}
}
// ASSERT_EQ(failed, 0);
for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
if (fabs(H_ref[i] - H_test[i]) > min_error) {
failed = 1;
printf("win %d H iter %d [%4d] ref %6.0f test %6.0f \n", wiener_win,
iter, i, H_ref[i], H_test[i]);
break;
}
}
ASSERT_EQ(failed, 0);
}
}
void WienerTest::runWienerTest_ExtremeValues(const int32_t wiener_win) {
const int32_t wiener_halfwin = wiener_win >> 1;
const int32_t wiener_win2 = wiener_win * wiener_win;
DECLARE_ALIGNED(32, uint8_t, dgd_buf[MAX_DATA_BLOCK * MAX_DATA_BLOCK]);
DECLARE_ALIGNED(32, uint8_t, src_buf[MAX_DATA_BLOCK * MAX_DATA_BLOCK]);
DECLARE_ALIGNED(32, double, M_ref[WIENER_WIN2]);
DECLARE_ALIGNED(32, double, H_ref[WIENER_WIN2 * WIENER_WIN2]);
DECLARE_ALIGNED(32, double, M_test[WIENER_WIN2]);
DECLARE_ALIGNED(32, double, H_test[WIENER_WIN2 * WIENER_WIN2]);
const int h_start = 16;
const int h_end = MAX_WIENER_BLOCK;
const int v_start = 16;
const int v_end = MAX_WIENER_BLOCK;
const int dgd_stride = h_end;
const int src_stride = MAX_DATA_BLOCK;
const int iters = 1;
for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
dgd_buf[i] = 255;
src_buf[i] = 255;
}
uint8_t *dgd = dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin;
uint8_t *src = src_buf;
av1_compute_stats_c(wiener_win, dgd, src, h_start, h_end, v_start, v_end,
dgd_stride, src_stride, M_ref, H_ref);
target_func_(wiener_win, dgd, src, h_start, h_end, v_start, v_end,
dgd_stride, src_stride, M_test, H_test);
int failed = 0;
for (int i = 0; i < wiener_win2; ++i) {
if (fabs(M_ref[i] - M_test[i]) > min_error) {
failed = 1;
printf("win %d M iter %d [%4d] ref %6.0f test %6.0f \n", wiener_win,
iter, i, M_ref[i], M_test[i]);
break;
}
}
// ASSERT_EQ(failed, 0);
for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
if (fabs(H_ref[i] - H_test[i]) > min_error) {
failed = 1;
printf("win %d H iter %d [%4d] ref %6.0f test %6.0f \n", wiener_win,
iter, i, H_ref[i], H_test[i]);
break;
}
}
ASSERT_EQ(failed, 0);
}
}
TEST_P(WienerTest, RandomValues) {
runWienerTest(WIENER_WIN, 1);
runWienerTest(WIENER_WIN_CHROMA, 1);
}
TEST_P(WienerTest, ExtremeValues) {
runWienerTest_ExtremeValues(WIENER_WIN);
runWienerTest_ExtremeValues(WIENER_WIN_CHROMA);
}
TEST_P(WienerTest, DISABLED_Speed) {
runWienerTest(WIENER_WIN, 200);
runWienerTest(WIENER_WIN_CHROMA, 200);
}
INSTANTIATE_TEST_CASE_P(C, WienerTest, ::testing::Values(compute_stats_opt_c));
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSE4_1, WienerTest,
::testing::Values(av1_compute_stats_sse4_1));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, WienerTest,
::testing::Values(av1_compute_stats_avx2));
#endif // HAVE_AVX2
} // namespace

View file

@ -37,6 +37,10 @@ struct Y4mTestParam {
const Y4mTestParam kY4mTestVectors[] = {
{ "park_joy_90p_8_420.y4m", 8, AOM_IMG_FMT_I420,
"e5406275b9fc6bb3436c31d4a05c1cab" },
{ "park_joy_90p_8_420_monochrome.y4m", 8, AOM_IMG_FMT_I420,
"95ef5bf6218580588be24a5271bb6a7f" },
{ "park_joy_90p_8_420_vertical_csp.y4m", 8, AOM_IMG_FMT_I420,
"f53a40fec15254ac312527339d9c686b" },
{ "park_joy_90p_8_422.y4m", 8, AOM_IMG_FMT_I422,
"284a47a47133b12884ec3a14e959a0b6" },
{ "park_joy_90p_8_444.y4m", 8, AOM_IMG_FMT_I444,
@ -55,24 +59,7 @@ const Y4mTestParam kY4mTestVectors[] = {
"5a6481a550821dab6d0192f5c63845e9" },
};
static void write_image_file(const aom_image_t *img, FILE *file) {
int plane, y;
for (plane = 0; plane < 3; ++plane) {
const unsigned char *buf = img->planes[plane];
const int stride = img->stride[plane];
const int bytes_per_sample = (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
const int h =
(plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift
: img->d_h);
const int w =
(plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift
: img->d_w);
for (y = 0; y < h; ++y) {
fwrite(buf, bytes_per_sample, w, file);
buf += stride;
}
}
}
static const int PLANES_YUV[] = { AOM_PLANE_Y, AOM_PLANE_U, AOM_PLANE_V };
class Y4mVideoSourceTest : public ::testing::TestWithParam<Y4mTestParam>,
public ::libaom_test::Y4mVideoSource {
@ -162,12 +149,13 @@ class Y4mVideoWriteTest : public Y4mVideoSourceTest {
tmpfile_ = new libaom_test::TempOutFile;
ASSERT_TRUE(tmpfile_->file() != NULL);
y4m_write_file_header(buf, sizeof(buf), kWidth, kHeight, &framerate,
y4m_.aom_fmt, y4m_.bit_depth);
img()->monochrome, img()->csp, y4m_.aom_fmt,
y4m_.bit_depth);
fputs(buf, tmpfile_->file());
for (unsigned int i = start_; i < limit_; i++) {
y4m_write_frame_header(buf, sizeof(buf));
fputs(buf, tmpfile_->file());
write_image_file(img(), tmpfile_->file());
y4m_write_image_file(img(), PLANES_YUV, tmpfile_->file());
Next();
}
ReplaceInputFile(tmpfile_->file());

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_Y4M_VIDEO_SOURCE_H_
#define TEST_Y4M_VIDEO_SOURCE_H_
#ifndef AOM_TEST_Y4M_VIDEO_SOURCE_H_
#define AOM_TEST_Y4M_VIDEO_SOURCE_H_
#include <algorithm>
#include <string>
@ -120,4 +120,4 @@ class Y4mVideoSource : public VideoSource {
} // namespace libaom_test
#endif // TEST_Y4M_VIDEO_SOURCE_H_
#endif // AOM_TEST_Y4M_VIDEO_SOURCE_H_

View file

@ -8,8 +8,8 @@
* 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.
*/
#ifndef TEST_YUV_VIDEO_SOURCE_H_
#define TEST_YUV_VIDEO_SOURCE_H_
#ifndef AOM_TEST_YUV_VIDEO_SOURCE_H_
#define AOM_TEST_YUV_VIDEO_SOURCE_H_
#include <cstdio>
#include <cstdlib>
@ -120,4 +120,4 @@ class YUVVideoSource : public VideoSource {
} // namespace libaom_test
#endif // TEST_YUV_VIDEO_SOURCE_H_
#endif // AOM_TEST_YUV_VIDEO_SOURCE_H_