diff options
Diffstat (limited to 'third_party/aom/test')
59 files changed, 2889 insertions, 675 deletions
diff --git a/third_party/aom/test/acm_random.h b/third_party/aom/test/acm_random.h index 023387061..0a8317fd5 100644 --- a/third_party/aom/test/acm_random.h +++ b/third_party/aom/test/acm_random.h @@ -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_ diff --git a/third_party/aom/test/av1_config_test.cc b/third_party/aom/test/av1_config_test.cc new file mode 100644 index 000000000..e2f2c5390 --- /dev/null +++ b/third_party/aom/test/av1_config_test.cc @@ -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 diff --git a/third_party/aom/test/av1_convolve_2d_test_util.cc b/third_party/aom/test/av1_convolve_2d_test_util.cc index 1aa08044e..409fd23e1 100644 --- a/third_party/aom/test/av1_convolve_2d_test_util.cc +++ b/third_party/aom/test/av1_convolve_2d_test_util.cc @@ -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; diff --git a/third_party/aom/test/av1_convolve_2d_test_util.h b/third_party/aom/test/av1_convolve_2d_test_util.h index cd4607d68..e0eb58410 100644 --- a/third_party/aom/test/av1_convolve_2d_test_util.h +++ b/third_party/aom/test/av1_convolve_2d_test_util.h @@ -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_ diff --git a/third_party/aom/test/av1_convolve_scale_test.cc b/third_party/aom/test/av1_convolve_scale_test.cc index b99caaeeb..3b1698eeb 100644 --- a/third_party/aom/test/av1_convolve_scale_test.cc +++ b/third_party/aom/test/av1_convolve_scale_test.cc @@ -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_); diff --git a/third_party/aom/test/av1_encoder_parms_get_to_decoder.cc b/third_party/aom/test/av1_encoder_parms_get_to_decoder.cc new file mode 100644 index 000000000..e8470e5d5 --- /dev/null +++ b/third_party/aom/test/av1_encoder_parms_get_to_decoder.cc @@ -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 diff --git a/third_party/aom/test/av1_fwd_txfm2d_test.cc b/third_party/aom/test/av1_fwd_txfm2d_test.cc index 6577e33b8..75f20536b 100644 --- a/third_party/aom/test/av1_fwd_txfm2d_test.cc +++ b/third_party/aom/test/av1_fwd_txfm2d_test.cc @@ -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(¶m, 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, ¶m); + 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(¶m, 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, ¶m); + } + 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 diff --git a/third_party/aom/test/av1_highbd_iht_test.cc b/third_party/aom/test/av1_highbd_iht_test.cc index 8cadc85e7..2d6490c2a 100644 --- a/third_party/aom/test/av1_highbd_iht_test.cc +++ b/third_party/aom/test/av1_highbd_iht_test.cc @@ -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 - -const IHbdHtParam kArrayIhtParam32x32[] = { - // 32x32 - make_tuple(PARAM_LIST_32X32, DCT_DCT, 10), - make_tuple(PARAM_LIST_32X32, DCT_DCT, 12), +typedef void (*HighbdInvTxfm2dFunc)(const int32_t *input, uint8_t *output, + int stride, const TxfmParam *txfm_param); + +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; + + 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 -#endif // HAVE_AVX2 +#if HAVE_AVX2 +INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdInvTxfm2d, + ::testing::Values(av1_highbd_inv_txfm_add_avx2)); +#endif } // namespace diff --git a/third_party/aom/test/av1_round_shift_array_test.cc b/third_party/aom/test/av1_round_shift_array_test.cc index 825d1348e..181a39460 100644 --- a/third_party/aom/test/av1_round_shift_array_test.cc +++ b/third_party/aom/test/av1_round_shift_array_test.cc @@ -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; diff --git a/third_party/aom/test/av1_txfm_test.h b/third_party/aom/test/av1_txfm_test.h index 70d1a894f..a18164741 100644 --- a/third_party/aom/test/av1_txfm_test.h +++ b/third_party/aom/test/av1_txfm_test.h @@ -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_ diff --git a/third_party/aom/test/blend_a64_mask_test.cc b/third_party/aom/test/blend_a64_mask_test.cc index c9c6795ee..66ca6fc5f 100644 --- a/third_party/aom/test/blend_a64_mask_test.cc +++ b/third_party/aom/test/blend_a64_mask_test.cc @@ -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; + + 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_; + } -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 < kMaxMaskSize; ++i) mask_[i] = AOM_BLEND_A64_MAX_ALPHA; - src0_[i] = src_max_bits_mask_; - src1_[i] = src_max_bits_mask_; + RunTest(bsize, 1); } - - for (int i = 0; i < kMaxMaskSize; ++i) mask_[i] = AOM_BLEND_A64_MAX_ALPHA; - - RunTest(); } } diff --git a/third_party/aom/test/blockd_test.cc b/third_party/aom/test/blockd_test.cc new file mode 100644 index 000000000..ab624007c --- /dev/null +++ b/third_party/aom/test/blockd_test.cc @@ -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))); + } + } +} diff --git a/third_party/aom/test/boolcoder_test.cc b/third_party/aom/test/boolcoder_test.cc index 72182de10..680ec1877 100644 --- a/third_party/aom/test/boolcoder_test.cc +++ b/third_party/aom/test/boolcoder_test.cc @@ -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)); } } diff --git a/third_party/aom/test/clear_system_state.h b/third_party/aom/test/clear_system_state.h index 7aa78243b..d38ff5dd5 100644 --- a/third_party/aom/test/clear_system_state.h +++ b/third_party/aom/test/clear_system_state.h @@ -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_ diff --git a/third_party/aom/test/codec_factory.h b/third_party/aom/test/codec_factory.h index e6ae7f8c3..dd99110ee 100644 --- a/third_party/aom/test/codec_factory.h +++ b/third_party/aom/test/codec_factory.h @@ -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_ diff --git a/third_party/aom/test/coding_path_sync.cc b/third_party/aom/test/coding_path_sync.cc index 51a506004..6735236cc 100644 --- a/third_party/aom/test/coding_path_sync.cc +++ b/third_party/aom/test/coding_path_sync.cc @@ -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; diff --git a/third_party/aom/test/comp_avg_pred_test.cc b/third_party/aom/test/comp_avg_pred_test.cc index 8bd826eb4..9ad8973f0 100644 --- a/third_party/aom/test/comp_avg_pred_test.cc +++ b/third_party/aom/test/comp_avg_pred_test.cc @@ -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) { diff --git a/third_party/aom/test/comp_avg_pred_test.h b/third_party/aom/test/comp_avg_pred_test.h index ab2004c05..9661dd9f5 100644 --- a/third_party/aom/test/comp_avg_pred_test.h +++ b/third_party/aom/test/comp_avg_pred_test.h @@ -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]; - - 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); - - 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 << ")"; + 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); + + 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 << ")"; + } } } } @@ -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; - - 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); - - 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 << ")"; + 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); + + 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); + + 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_ diff --git a/third_party/aom/test/comp_mask_variance_test.cc b/third_party/aom/test/comp_mask_variance_test.cc index 0016ddd59..34be2aa6d 100644 --- a/third_party/aom/test/comp_mask_variance_test.cc +++ b/third_party/aom/test/comp_mask_variance_test.cc @@ -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)); - - // 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_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 << ")"; + 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); + + // 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 = 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); - - 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 = 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 << ")"; + 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, 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, 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 diff --git a/third_party/aom/test/decode_api_test.cc b/third_party/aom/test/decode_api_test.cc index 97cbd0655..c1beacee1 100644 --- a/third_party/aom/test/decode_api_test.cc +++ b/third_party/aom/test/decode_api_test.cc @@ -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 }; diff --git a/third_party/aom/test/decode_test_driver.h b/third_party/aom/test/decode_test_driver.h index 916efdad0..d13e13ea1 100644 --- a/third_party/aom/test/decode_test_driver.h +++ b/third_party/aom/test/decode_test_driver.h @@ -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_ diff --git a/third_party/aom/test/encode_api_test.cc b/third_party/aom/test/encode_api_test.cc index c469d0871..c26f5720f 100644 --- a/third_party/aom/test/encode_api_test.cc +++ b/third_party/aom/test/encode_api_test.cc @@ -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)); diff --git a/third_party/aom/test/encode_test_driver.cc b/third_party/aom/test/encode_test_driver.cc index 35908430d..f3d61dc36 100644 --- a/third_party/aom/test/encode_test_driver.cc +++ b/third_party/aom/test/encode_test_driver.cc @@ -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(); diff --git a/third_party/aom/test/encode_test_driver.h b/third_party/aom/test/encode_test_driver.h index 138cd6a67..4f3f855cf 100644 --- a/third_party/aom/test/encode_test_driver.h +++ b/third_party/aom/test/encode_test_driver.h @@ -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_ diff --git a/third_party/aom/test/encodetxb_test.cc b/third_party/aom/test/encodetxb_test.cc index ab6ec72c6..11cc07368 100644 --- a/third_party/aom/test/encodetxb_test.cc +++ b/third_party/aom/test/encodetxb_test.cc @@ -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)); -#endif +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 diff --git a/third_party/aom/test/ethread_test.cc b/third_party/aom/test/ethread_test.cc index dd9fc2f8d..d9ac78282 100644 --- a/third_party/aom/test/ethread_test.cc +++ b/third_party/aom/test/ethread_test.cc @@ -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 diff --git a/third_party/aom/test/external_frame_buffer_test.cc b/third_party/aom/test/external_frame_buffer_test.cc new file mode 100644 index 000000000..c2af059a4 --- /dev/null +++ b/third_party/aom/test/external_frame_buffer_test.cc @@ -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 diff --git a/third_party/aom/test/fft_test.cc b/third_party/aom/test/fft_test.cc index 5c8ec069c..e24e451a3 100644 --- a/third_party/aom/test/fft_test.cc +++ b/third_party/aom/test/fft_test.cc @@ -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 diff --git a/third_party/aom/test/function_equivalence_test.h b/third_party/aom/test/function_equivalence_test.h index 4b22c74a2..f27068902 100644 --- a/third_party/aom/test/function_equivalence_test.h +++ b/third_party/aom/test/function_equivalence_test.h @@ -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_ diff --git a/third_party/aom/test/hiprec_convolve_test_util.h b/third_party/aom/test/hiprec_convolve_test_util.h index 81471c8b9..2abe24b57 100644 --- a/third_party/aom/test/hiprec_convolve_test_util.h +++ b/third_party/aom/test/hiprec_convolve_test_util.h @@ -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_ diff --git a/third_party/aom/test/i420_video_source.h b/third_party/aom/test/i420_video_source.h index 0825296d7..233e7152b 100644 --- a/third_party/aom/test/i420_video_source.h +++ b/third_party/aom/test/i420_video_source.h @@ -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_ diff --git a/third_party/aom/test/invalid_file_test.cc b/third_party/aom/test/invalid_file_test.cc index 869f3da66..5b4f5a6c3 100644 --- a/third_party/aom/test/invalid_file_test.cc +++ b/third_party/aom/test/invalid_file_test.cc @@ -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, diff --git a/third_party/aom/test/ivf_video_source.h b/third_party/aom/test/ivf_video_source.h index 4b2713537..ff2841445 100644 --- a/third_party/aom/test/ivf_video_source.h +++ b/third_party/aom/test/ivf_video_source.h @@ -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_ diff --git a/third_party/aom/test/log2_test.cc b/third_party/aom/test/log2_test.cc new file mode 100644 index 000000000..d7840c68b --- /dev/null +++ b/third_party/aom/test/log2_test.cc @@ -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); + } + } +} diff --git a/third_party/aom/test/md5_helper.h b/third_party/aom/test/md5_helper.h index b2b14cf21..9443cb262 100644 --- a/third_party/aom/test/md5_helper.h +++ b/third_party/aom/test/md5_helper.h @@ -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_ diff --git a/third_party/aom/test/obmc_variance_test.cc b/third_party/aom/test/obmc_variance_test.cc index 04fee8285..4563b964a 100644 --- a/third_party/aom/test/obmc_variance_test.cc +++ b/third_party/aom/test/obmc_variance_test.cc @@ -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 //////////////////////////////////////////////////////////////////////////////// diff --git a/third_party/aom/test/pickrst_test.cc b/third_party/aom/test/pickrst_test.cc new file mode 100644 index 000000000..040e8e8b7 --- /dev/null +++ b/third_party/aom/test/pickrst_test.cc @@ -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, ¶ms); + } + 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, ¶ms); + } + 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, ¶ms); + + 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, ¶ms); + + 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 diff --git a/third_party/aom/test/quantize_func_test.cc b/third_party/aom/test/quantize_func_test.cc index 97e73bff0..554d0c721 100644 --- a/third_party/aom/test/quantize_func_test.cc +++ b/third_party/aom/test/quantize_func_test.cc @@ -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, - AOM_BITS_8), - make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>, - &lowbd_quan_wrapper<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, - AOM_BITS_8), - make_tuple(&lowbd_quan_wrapper<av1_quantize_fp_c>, - &lowbd_quan_wrapper<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, + 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_32x32_c>, - &lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_32X32, 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_32x32_c>, - &lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_16X64, 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_32x32_c>, - &lowbd_quan_wrapper<av1_quantize_fp_32x32_avx2>, TX_64X16, 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_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(&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_4X16, 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_16X4, 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_8X32, TYPE_FP, + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_32X8, 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(&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 diff --git a/third_party/aom/test/reconinter_test.cc b/third_party/aom/test/reconinter_test.cc index 9b849404c..a8536e517 100644 --- a/third_party/aom/test/reconinter_test.cc +++ b/third_party/aom/test/reconinter_test.cc @@ -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)); diff --git a/third_party/aom/test/register_state_check.h b/third_party/aom/test/register_state_check.h index ef1f775e5..d404621dd 100644 --- a/third_party/aom/test/register_state_check.h +++ b/third_party/aom/test/register_state_check.h @@ -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_ diff --git a/third_party/aom/test/sum_squares_test.cc b/third_party/aom/test/sum_squares_test.cc index c03ebad4a..f10998498 100644 --- a/third_party/aom/test/sum_squares_test.cc +++ b/third_party/aom/test/sum_squares_test.cc @@ -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 ////////////////////////////////////////////////////////////////////////////// diff --git a/third_party/aom/test/test-data.sha1 b/third_party/aom/test/test-data.sha1 index 723e06104..b6ee34701 100644 --- a/third_party/aom/test/test-data.sha1 +++ b/third_party/aom/test/test-data.sha1 @@ -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
\ No newline at end of file +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 diff --git a/third_party/aom/test/test.cmake b/third_party/aom/test/test.cmake index 7b584880f..b16ae14c3 100644 --- a/third_party/aom/test/test.cmake +++ b/third_party/aom/test/test.cmake @@ -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. diff --git a/third_party/aom/test/test_data_util.cmake b/third_party/aom/test/test_data_util.cmake index 9fe00a07d..45c951478 100644 --- a/third_party/aom/test/test_data_util.cmake +++ b/third_party/aom/test/test_data_util.cmake @@ -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) diff --git a/third_party/aom/test/test_vector_test.cc b/third_party/aom/test/test_vector_test.cc index 1bfeacba1..286988b17 100644 --- a/third_party/aom/test/test_vector_test.cc +++ b/third_party/aom/test/test_vector_test.cc @@ -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 diff --git a/third_party/aom/test/test_vectors.cc b/third_party/aom/test/test_vectors.cc index f478c0183..71e431e18 100644 --- a/third_party/aom/test/test_vectors.cc +++ b/third_party/aom/test/test_vectors.cc @@ -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 diff --git a/third_party/aom/test/test_vectors.h b/third_party/aom/test/test_vectors.h index 229f063a6..be37f6e37 100644 --- a/third_party/aom/test/test_vectors.h +++ b/third_party/aom/test/test_vectors.h @@ -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_ diff --git a/third_party/aom/test/transform_test_base.h b/third_party/aom/test/transform_test_base.h index 67e8faf33..8ebcf5ff7 100644 --- a/third_party/aom/test/transform_test_base.h +++ b/third_party/aom/test/transform_test_base.h @@ -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_ diff --git a/third_party/aom/test/util.h b/third_party/aom/test/util.h index db00875ef..c3f4e4442 100644 --- a/third_party/aom/test/util.h +++ b/third_party/aom/test/util.h @@ -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_ diff --git a/third_party/aom/test/variance_test.cc b/third_party/aom/test/variance_test.cc index 2f1b1fc5a..0df314b0f 100644 --- a/third_party/aom/test/variance_test.cc +++ b/third_party/aom/test/variance_test.cc @@ -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), diff --git a/third_party/aom/test/video_source.h b/third_party/aom/test/video_source.h index dc39b5a80..3c1c5e559 100644 --- a/third_party/aom/test/video_source.h +++ b/third_party/aom/test/video_source.h @@ -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_ diff --git a/third_party/aom/test/warp_filter_test.cc b/third_party/aom/test/warp_filter_test.cc index 15f8a285c..19a4e8b6a 100644 --- a/third_party/aom/test/warp_filter_test.cc +++ b/third_party/aom/test/warp_filter_test.cc @@ -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 diff --git a/third_party/aom/test/warp_filter_test_util.cc b/third_party/aom/test/warp_filter_test_util.cc index b341cd0c2..69b2ed4af 100644 --- a/third_party/aom/test/warp_filter_test_util.cc +++ b/third_party/aom/test/warp_filter_test_util.cc @@ -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; diff --git a/third_party/aom/test/warp_filter_test_util.h b/third_party/aom/test/warp_filter_test_util.h index cf72d9db6..b8998e5c8 100644 --- a/third_party/aom/test/warp_filter_test_util.h +++ b/third_party/aom/test/warp_filter_test_util.h @@ -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_ diff --git a/third_party/aom/test/webm_video_source.h b/third_party/aom/test/webm_video_source.h index 482f5dea2..bb3d11735 100644 --- a/third_party/aom/test/webm_video_source.h +++ b/third_party/aom/test/webm_video_source.h @@ -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_ diff --git a/third_party/aom/test/wiener_test.cc b/third_party/aom/test/wiener_test.cc new file mode 100644 index 000000000..dfec09119 --- /dev/null +++ b/third_party/aom/test/wiener_test.cc @@ -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 diff --git a/third_party/aom/test/y4m_test.cc b/third_party/aom/test/y4m_test.cc index b8011935d..6cc75ef5b 100644 --- a/third_party/aom/test/y4m_test.cc +++ b/third_party/aom/test/y4m_test.cc @@ -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()); diff --git a/third_party/aom/test/y4m_video_source.h b/third_party/aom/test/y4m_video_source.h index 277ded9eb..3dea901e6 100644 --- a/third_party/aom/test/y4m_video_source.h +++ b/third_party/aom/test/y4m_video_source.h @@ -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_ diff --git a/third_party/aom/test/yuv_video_source.h b/third_party/aom/test/yuv_video_source.h index 51554af6f..774ecc008 100644 --- a/third_party/aom/test/yuv_video_source.h +++ b/third_party/aom/test/yuv_video_source.h @@ -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_ |