diff options
author | Moonchild <moonchild@palemoon.org> | 2021-03-03 18:48:48 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2021-03-04 00:03:46 +0000 |
commit | 44d2b4a86e3d862eb1b68db3d9a29b9dbf3da746 (patch) | |
tree | 9d9cc4d21c93ae3e1a88ab5c160c3be5f6af0ca9 /media/libaom/src/test | |
parent | 353943d1a48086a39ff5f4365b22f8f058d5f66e (diff) | |
download | aura-central-44d2b4a86e3d862eb1b68db3d9a29b9dbf3da746.tar.gz |
Issue mcp-graveyard/UXP%1737 - Import libaom 2.0.2 source
Diffstat (limited to 'media/libaom/src/test')
130 files changed, 13512 insertions, 2596 deletions
diff --git a/media/libaom/src/test/acm_random.h b/media/libaom/src/test/acm_random.h index 0a8317fd5..8b1d51aef 100644 --- a/media/libaom/src/test/acm_random.h +++ b/media/libaom/src/test/acm_random.h @@ -26,6 +26,7 @@ class ACMRandom { void Reset(int seed) { random_.Reseed(seed); } + // Generates a random 31-bit unsigned integer from [0, 2^31). uint32_t Rand31(void) { return random_.Generate(testing::internal::Random::kMaxRange); } @@ -66,7 +67,7 @@ class ACMRandom { // Returns a random value near 0 or near 255, to better exercise // saturation behavior. const uint8_t r = Rand8(); - return r < 128 ? r << 4 : r >> 4; + return static_cast<uint8_t>((r < 128) ? r << 4 : r >> 4); } int PseudoUniform(int range) { return random_.Generate(range); } diff --git a/media/libaom/src/test/active_map_test.cc b/media/libaom/src/test/active_map_test.cc index a2b0546ed..0f8a7329e 100644 --- a/media/libaom/src/test/active_map_test.cc +++ b/media/libaom/src/test/active_map_test.cc @@ -37,7 +37,7 @@ class ActiveMapTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, cpu_used_); } else if (video->frame() == 3) { aom_active_map_t map = aom_active_map_t(); diff --git a/media/libaom/src/test/altref_test.cc b/media/libaom/src/test/altref_test.cc index dabb1475a..43df39fb6 100644 --- a/media/libaom/src/test/altref_test.cc +++ b/media/libaom/src/test/altref_test.cc @@ -50,7 +50,8 @@ class AltRefForcedKeyTestLarge virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { if (frame_num_ == forced_kf_frame_num_) { - ASSERT_TRUE(!!(pkt->data.frame.flags & AOM_FRAME_IS_KEY)) + ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, + static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_KEY)) << "Frame #" << frame_num_ << " isn't a keyframe!"; } ++frame_num_; diff --git a/media/libaom/src/test/aom_integer_test.cc b/media/libaom/src/test/aom_integer_test.cc index fe88a54e9..d5dfad946 100644 --- a/media/libaom/src/test/aom_integer_test.cc +++ b/media/libaom/src/test/aom_integer_test.cc @@ -20,9 +20,9 @@ const uint32_t kSizeTestNumValues = 6; const uint32_t kSizeTestExpectedSizes[kSizeTestNumValues] = { 1, 1, 2, 3, 4, 5 }; -const uint64_t kSizeTestInputs[kSizeTestNumValues] = { - 0, 0x7f, 0x3fff, 0x1fffff, 0xffffff, 0x10000000 -}; +const uint64_t kSizeTestInputs[kSizeTestNumValues] = { 0, 0x7f, + 0x3fff, 0x1fffff, + 0xffffff, 0x10000000 }; const uint8_t kOutOfRangeLeb128Value[5] = { 0x80, 0x80, 0x80, 0x80, 0x10 }; // UINT32_MAX + 1 diff --git a/media/libaom/src/test/aq_segment_test.cc b/media/libaom/src/test/aq_segment_test.cc index bbb5027d4..83bfdb670 100644 --- a/media/libaom/src/test/aq_segment_test.cc +++ b/media/libaom/src/test/aq_segment_test.cc @@ -20,7 +20,8 @@ namespace { class AqSegmentTest - : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>, + : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int, + int>, public ::libaom_test::EncoderTest { protected: AqSegmentTest() : EncoderTest(GET_PARAM(0)) {} @@ -35,7 +36,7 @@ class AqSegmentTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); encoder->Control(AV1E_SET_AQ_MODE, aq_mode_); encoder->Control(AV1E_SET_DELTAQ_MODE, deltaq_mode_); @@ -65,25 +66,13 @@ class AqSegmentTest int deltaq_mode_; }; -// Validate that this AQ segmentation mode (AQ=1, variance_ap) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ1) { DoTest(1); } - -// Validate that this AQ segmentation mode (AQ=2, complexity_aq) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ2) { DoTest(2); } - -// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ3) { DoTest(3); } +// Validate that this AQ segmentation mode (1-variance_aq, 2-complexity_aq, +// 3-cyclic_refresh_aq) encodes and decodes without a mismatch. +TEST_P(AqSegmentTest, TestNoMisMatch) { DoTest(GET_PARAM(3)); } class AqSegmentTestLarge : public AqSegmentTest {}; -TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ1) { DoTest(1); } - -TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ2) { DoTest(2); } - -TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ3) { DoTest(3); } +TEST_P(AqSegmentTestLarge, TestNoMisMatch) { DoTest(GET_PARAM(3)); } // Validate that this delta q mode // encodes and decodes without a mismatch. @@ -100,9 +89,9 @@ TEST_P(AqSegmentTest, TestNoMisMatchExtDeltaQ) { AV1_INSTANTIATE_TEST_CASE(AqSegmentTest, ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood), - ::testing::Range(5, 9)); + ::testing::Range(5, 9), ::testing::Range(0, 4)); AV1_INSTANTIATE_TEST_CASE(AqSegmentTestLarge, ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood), - ::testing::Range(3, 5)); + ::testing::Range(3, 5), ::testing::Range(0, 4)); } // namespace diff --git a/media/libaom/src/test/arf_freq_test.cc b/media/libaom/src/test/arf_freq_test.cc index 083f4022f..0780cd712 100644 --- a/media/libaom/src/test/arf_freq_test.cc +++ b/media/libaom/src/test/arf_freq_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -185,7 +187,7 @@ TEST_P(ArfFreqTestLarge, MinArfFreqTest) { init_flags_ = AOM_CODEC_USE_PSNR; if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; - testing::internal::scoped_ptr<libaom_test::VideoSource> video; + std::unique_ptr<libaom_test::VideoSource> video; if (is_extension_y4m(test_video_param_.filename)) { video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, kFrames)); @@ -212,7 +214,7 @@ TEST_P(ArfFreqTestLarge, MinArfFreqTest) { // BWDREF_FRAME is also a non-show frame, and the minimum run between two // consecutive BWDREF_FRAME's may vary between 1 and any arbitrary positive // number as long as it does not exceed the gf_group interval. -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( DISABLED_AV1, ArfFreqTestLarge, ::testing::Combine( ::testing::Values( diff --git a/media/libaom/src/test/onyxc_int_test.cc b/media/libaom/src/test/av1_common_int_test.cc index 388959518..dde2542e3 100644 --- a/media/libaom/src/test/onyxc_int_test.cc +++ b/media/libaom/src/test/av1_common_int_test.cc @@ -11,9 +11,9 @@ #include "third_party/googletest/src/googletest/include/gtest/gtest.h" -#include "av1/common/onyxc_int.h" +#include "av1/common/av1_common_int.h" -TEST(OnyxcInt, TestGetTxSize) { +TEST(AV1CommonInt, TestGetTxSize) { for (int t = TX_4X4; t < TX_SIZES_ALL; t++) { TX_SIZE t2 = get_tx_size(tx_size_wide[t], tx_size_high[t]); GTEST_ASSERT_EQ(tx_size_wide[t], tx_size_wide[t2]); diff --git a/media/libaom/src/test/av1_config_test.cc b/media/libaom/src/test/av1_config_test.cc index e2f2c5390..fca980f06 100644 --- a/media/libaom/src/test/av1_config_test.cc +++ b/media/libaom/src/test/av1_config_test.cc @@ -24,20 +24,20 @@ namespace { // 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 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 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 kLobfReducedStillImageSequenceHeaderObu[] = { 0x0a, 0x07, 0x18, + 0x22, 0x2b, 0xf1, + 0xfe, 0xc0, 0x20 }; const uint8_t kAv1cAllZero[] = { 0, 0, 0, 0 }; diff --git a/media/libaom/src/test/av1_convolve_2d_test.cc b/media/libaom/src/test/av1_convolve_2d_test.cc index 03286260e..50a58f06d 100644 --- a/media/libaom/src/test/av1_convolve_2d_test.cc +++ b/media/libaom/src/test/av1_convolve_2d_test.cc @@ -9,193 +9,203 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/av1_convolve_2d_test_util.h" -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; using libaom_test::AV1Convolve2D::AV1Convolve2DSrTest; using libaom_test::AV1Convolve2D::AV1JntConvolve2DTest; +#if CONFIG_AV1_HIGHBITDEPTH using libaom_test::AV1HighbdConvolve2D::AV1HighbdConvolve2DSrTest; using libaom_test::AV1HighbdConvolve2D::AV1HighbdJntConvolve2DTest; +#endif +using std::make_tuple; +using std::tuple; + namespace { TEST_P(AV1Convolve2DSrTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } TEST_P(AV1Convolve2DSrTest, CheckOutput) { RunCheckOutput(GET_PARAM(0)); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C_COPY, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_copy_sr_c, 0, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C_X, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_sr_c, 1, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C_Y, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_sr_c, 0, 1)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sr_c, 1, 1)); #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2_COPY, AV1Convolve2DSrTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_convolve_2d_copy_sr_sse2, 0, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P(SSE2_COPY, AV1Convolve2DSrTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_convolve_2d_copy_sr_sse2, 0, 0)); +INSTANTIATE_TEST_SUITE_P( SSE2_X, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_sr_sse2, 1, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2_Y, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_sr_sse2, 0, 1)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sr_sse2, 1, 1)); #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2_COPY, AV1Convolve2DSrTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_convolve_2d_copy_sr_avx2, 0, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P(AVX2_COPY, AV1Convolve2DSrTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_convolve_2d_copy_sr_avx2, 0, 0)); +INSTANTIATE_TEST_SUITE_P( AVX2_X, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_sr_avx2, 1, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2_Y, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_sr_avx2, 0, 1)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sr_avx2, 1, 1)); #endif // HAVE_AVX2 #endif // HAVE_SSE2 #if HAVE_NEON -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON_X, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_sr_neon, 1, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON_Y, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_sr_neon, 0, 1)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AV1Convolve2DSrTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sr_neon, 1, 1)); -INSTANTIATE_TEST_CASE_P(NEON_COPY, AV1Convolve2DSrTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_convolve_2d_copy_sr_neon, 0, 0)); +INSTANTIATE_TEST_SUITE_P(NEON_COPY, AV1Convolve2DSrTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_convolve_2d_copy_sr_neon, 0, 0)); #endif // HAVE_NEON TEST_P(AV1JntConvolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(0)); } TEST_P(AV1JntConvolve2DTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } -INSTANTIATE_TEST_CASE_P( - C_COPY, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_2d_copy_c, 0, 0)); +INSTANTIATE_TEST_SUITE_P(C_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_copy_c, 0, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C_X, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_x_c, 1, 0)); + libaom_test::AV1Convolve2D::BuildParams(av1_dist_wtd_convolve_x_c, 1, 0)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C_Y, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_y_c, 0, 1)); + libaom_test::AV1Convolve2D::BuildParams(av1_dist_wtd_convolve_y_c, 0, 1)); #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2_COPY, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_jnt_convolve_2d_copy_sse2, 0, 0)); -#if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( - SSE2_X, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_x_sse2, 1, 0)); +INSTANTIATE_TEST_SUITE_P(SSE2_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_copy_sse2, 0, 0)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_sse2, 1, 1)); -INSTANTIATE_TEST_CASE_P( - SSE2_Y, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_y_sse2, 0, 1)); +INSTANTIATE_TEST_SUITE_P(SSE2_X, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_x_sse2, 1, 0)); -INSTANTIATE_TEST_CASE_P( - SSSE3, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_2d_ssse3, 1, 1)); +INSTANTIATE_TEST_SUITE_P(SSE2_Y, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_y_sse2, 0, 1)); + +#if HAVE_SSSE3 +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_ssse3, 1, 1)); #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2_COPY, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_jnt_convolve_2d_copy_avx2, 0, 0)); -INSTANTIATE_TEST_CASE_P( - AVX2_X, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_x_avx2, 1, 0)); - -INSTANTIATE_TEST_CASE_P( - AVX2_Y, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_y_avx2, 0, 1)); - -INSTANTIATE_TEST_CASE_P( - AVX2, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_2d_avx2, 1, 1)); +INSTANTIATE_TEST_SUITE_P(AVX2_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_copy_avx2, 0, 0)); +INSTANTIATE_TEST_SUITE_P(AVX2_X, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_x_avx2, 1, 0)); + +INSTANTIATE_TEST_SUITE_P(AVX2_Y, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_y_avx2, 0, 1)); + +INSTANTIATE_TEST_SUITE_P(AVX2, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_avx2, 1, 1)); #endif // HAVE_AVX2 -#endif // HAVE_SSE4_1 +#endif // HAVE_SSSE3 #endif // HAVE_SSE2 #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON_COPY, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams( - av1_jnt_convolve_2d_copy_neon, 0, 0)); - -INSTANTIATE_TEST_CASE_P( - NEON, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_2d_neon, 1, 1)); -INSTANTIATE_TEST_CASE_P( - NEON_X, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_x_neon, 1, 0)); - -INSTANTIATE_TEST_CASE_P( - NEON_Y, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_y_neon, 0, 1)); +INSTANTIATE_TEST_SUITE_P(NEON_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_copy_neon, 0, 0)); + +INSTANTIATE_TEST_SUITE_P(NEON, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_2d_neon, 1, 1)); +INSTANTIATE_TEST_SUITE_P(NEON_X, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_x_neon, 1, 0)); + +INSTANTIATE_TEST_SUITE_P(NEON_Y, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_dist_wtd_convolve_y_neon, 0, 1)); #endif // HAVE_NEON +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(AV1HighbdConvolve2DSrTest, CheckOutput) { RunCheckOutput(GET_PARAM(1)); } TEST_P(AV1HighbdConvolve2DSrTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(1)); } -INSTANTIATE_TEST_CASE_P(C_X, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_x_sr_c, 1, 0)); +INSTANTIATE_TEST_SUITE_P(C_X, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_x_sr_c, 1, 0)); -INSTANTIATE_TEST_CASE_P(C_Y, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_y_sr_c, 0, 1)); +INSTANTIATE_TEST_SUITE_P(C_Y, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_y_sr_c, 0, 1)); -INSTANTIATE_TEST_CASE_P(C_COPY, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_2d_copy_sr_c, 0, 0)); +INSTANTIATE_TEST_SUITE_P(C_COPY, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_2d_copy_sr_c, 0, 0)); #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2_COPY, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_2d_copy_sr_sse2, 0, 0)); +INSTANTIATE_TEST_SUITE_P(SSE2_COPY, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_2d_copy_sr_sse2, 0, 0)); #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P(SSSE3, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_2d_sr_ssse3, 1, 1)); -INSTANTIATE_TEST_CASE_P(SSSE3_X, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_x_sr_ssse3, 1, 0)); -INSTANTIATE_TEST_CASE_P(SSSE3_Y, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_y_sr_ssse3, 0, 1)); +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_2d_sr_ssse3, 1, 1)); +INSTANTIATE_TEST_SUITE_P(SSSE3_X, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_x_sr_ssse3, 1, 0)); +INSTANTIATE_TEST_SUITE_P(SSSE3_Y, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_y_sr_ssse3, 0, 1)); #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_2d_sr_avx2, 1, 1)); -INSTANTIATE_TEST_CASE_P(AVX2_X, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_x_sr_avx2, 1, 0)); -INSTANTIATE_TEST_CASE_P(AVX2_Y, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_y_sr_avx2, 0, 1)); -INSTANTIATE_TEST_CASE_P(AVX2_COPY, AV1HighbdConvolve2DSrTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_convolve_2d_copy_sr_avx2, 0, 0)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_2d_sr_avx2, 1, 1)); +INSTANTIATE_TEST_SUITE_P(AVX2_X, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_x_sr_avx2, 1, 0)); +INSTANTIATE_TEST_SUITE_P(AVX2_Y, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_y_sr_avx2, 0, 1)); +INSTANTIATE_TEST_SUITE_P(AVX2_COPY, AV1HighbdConvolve2DSrTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_convolve_2d_copy_sr_avx2, 0, 0)); #endif // HAVE_AVX2 #endif // HAVE_SSSE3 #endif // HAVE_SSE2 @@ -207,43 +217,45 @@ TEST_P(AV1HighbdJntConvolve2DTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(1)); } -INSTANTIATE_TEST_CASE_P(C_X, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_x_c, 1, 0)); +INSTANTIATE_TEST_SUITE_P(C_X, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_x_c, 1, 0)); -INSTANTIATE_TEST_CASE_P(C_Y, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_y_c, 0, 1)); +INSTANTIATE_TEST_SUITE_P(C_Y, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_y_c, 0, 1)); -INSTANTIATE_TEST_CASE_P(C_COPY, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_2d_copy_c, 0, 0)); +INSTANTIATE_TEST_SUITE_P(C_COPY, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_2d_copy_c, 0, 0)); #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1_COPY, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_2d_copy_sse4_1, 0, 0)); -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_2d_sse4_1, 1, 1)); -INSTANTIATE_TEST_CASE_P(SSE4_1_X, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_x_sse4_1, 1, 0)); -INSTANTIATE_TEST_CASE_P(SSE4_1_Y, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_y_sse4_1, 0, 1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1_COPY, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_2d_copy_sse4_1, 0, + 0)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_2d_sse4_1, 1, 1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1_X, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_x_sse4_1, 1, 0)); +INSTANTIATE_TEST_SUITE_P(SSE4_1_Y, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_y_sse4_1, 0, 1)); #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2_COPY, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_2d_copy_avx2, 0, 0)); -INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_2d_avx2, 1, 1)); -INSTANTIATE_TEST_CASE_P(AVX2_X, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_x_avx2, 1, 0)); -INSTANTIATE_TEST_CASE_P(AVX2_Y, AV1HighbdJntConvolve2DTest, - libaom_test::AV1HighbdConvolve2D::BuildParams( - av1_highbd_jnt_convolve_y_avx2, 0, 1)); +INSTANTIATE_TEST_SUITE_P(AVX2_COPY, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_2d_copy_avx2, 0, 0)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_2d_avx2, 1, 1)); +INSTANTIATE_TEST_SUITE_P(AVX2_X, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_x_avx2, 1, 0)); +INSTANTIATE_TEST_SUITE_P(AVX2_Y, AV1HighbdJntConvolve2DTest, + libaom_test::AV1HighbdConvolve2D::BuildParams( + av1_highbd_dist_wtd_convolve_y_avx2, 0, 1)); #endif // HAVE_AVX2 #endif // HAVE_SSE4_1 +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/av1_convolve_2d_test_util.cc b/media/libaom/src/test/av1_convolve_2d_test_util.cc index 409fd23e1..6f103d3f6 100644 --- a/media/libaom/src/test/av1_convolve_2d_test_util.cc +++ b/media/libaom/src/test/av1_convolve_2d_test_util.cc @@ -15,8 +15,8 @@ #include "av1/common/common_data.h" #include "av1/common/convolve.h" -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; namespace libaom_test { @@ -51,7 +51,7 @@ void AV1Convolve2DSrTest::RunCheckOutput(convolve_2d_func test_impl) { for (int i = 0; i < h; ++i) for (int j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8(); for (int i = 0; i < MAX_SB_SQUARE; ++i) - output[i] = output2[i] = rnd_.Rand31(); + output[i] = output2[i] = static_cast<uint8_t>(rnd_.Rand31()); // Make sure that sizes 2xN and Nx2 are also tested for chroma. const int num_sizes = @@ -200,9 +200,9 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { 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; - conv_params2.use_jnt_comp_avg = 0; + // Test special case where dist_wtd_comp_avg is not used + conv_params1.use_dist_wtd_comp_avg = 0; + conv_params2.use_dist_wtd_comp_avg = 0; const int subx_range = has_subx ? 16 : 1; const int suby_range = has_suby ? 16 : 1; @@ -211,9 +211,10 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { // Choose random locations within the source block const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, output8_1, - MAX_SB_SIZE, out_w, out_h, filter_params_x, - filter_params_y, subx, suby, &conv_params1); + av1_dist_wtd_convolve_2d_c(input + offset_r * w + offset_c, w, + output8_1, MAX_SB_SIZE, out_w, out_h, + filter_params_x, filter_params_y, subx, + suby, &conv_params1); test_impl(input + offset_r * w + offset_c, w, output8_2, MAX_SB_SIZE, out_w, out_h, filter_params_x, filter_params_y, subx, suby, &conv_params2); @@ -222,7 +223,7 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { for (int j = 0; j < out_w; ++j) { int idx = i * MAX_SB_SIZE + j; ASSERT_EQ(output1[idx], output2[idx]) - << "Mismatch at unit tests for av1_jnt_convolve_2d\n" + << "Mismatch at unit tests for av1_dist_wtd_convolve_2d\n" << out_w << "x" << out_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << "), sub pixel offset = (" << suby << ", " << subx << ")"; @@ -247,8 +248,8 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { // Test different combination of fwd and bck offset weights for (int k = 0; k < 2; ++k) { for (int l = 0; l < 4; ++l) { - conv_params1.use_jnt_comp_avg = 1; - conv_params2.use_jnt_comp_avg = 1; + conv_params1.use_dist_wtd_comp_avg = 1; + conv_params2.use_dist_wtd_comp_avg = 1; conv_params1.fwd_offset = quant_dist_lookup_table[k][l][0]; conv_params1.bck_offset = quant_dist_lookup_table[k][l][1]; conv_params2.fwd_offset = quant_dist_lookup_table[k][l][0]; @@ -259,10 +260,10 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { // Choose random locations within the source block const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, - output8_1, MAX_SB_SIZE, out_w, out_h, - filter_params_x, filter_params_y, subx, - suby, &conv_params1); + av1_dist_wtd_convolve_2d_c(input + offset_r * w + offset_c, w, + output8_1, MAX_SB_SIZE, out_w, out_h, + filter_params_x, filter_params_y, + subx, suby, &conv_params1); test_impl(input + offset_r * w + offset_c, w, output8_2, MAX_SB_SIZE, out_w, out_h, filter_params_x, filter_params_y, subx, suby, &conv_params2); @@ -272,7 +273,7 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { int idx = i * MAX_SB_SIZE + j; ASSERT_EQ(output1[idx], output2[idx]) << "Mismatch at unit tests for " - "av1_jnt_convolve_2d\n" + "av1_dist_wtd_convolve_2d\n" << out_w << "x" << out_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << "), sub pixel offset = (" << suby << ", " << subx @@ -333,7 +334,7 @@ void AV1JntConvolve2DTest::RunSpeedTest(convolve_2d_func test_impl) { ConvolveParams conv_params = get_conv_params_no_round(do_average, 0, output, MAX_SB_SIZE, 1, 8); - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; // Choose random locations within the source block const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); @@ -354,6 +355,7 @@ void AV1JntConvolve2DTest::RunSpeedTest(convolve_2d_func test_impl) { } } // namespace AV1Convolve2D +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdConvolve2D { ::testing::internal::ParamGenerator<HighbdConvolve2DParam> BuildParams( highbd_convolve_2d_func filter, int has_subx, int has_suby) { @@ -444,7 +446,7 @@ void AV1HighbdConvolve2DSrTest::RunCheckOutput( for (int j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1); for (int i = 0; i < MAX_SB_SQUARE; ++i) - output[i] = output2[i] = rnd_.Rand31(); + output[i] = output2[i] = static_cast<int16_t>(rnd_.Rand31()); // Make sure that sizes 2xN and Nx2 are also tested for chroma. const int num_sizes = @@ -540,8 +542,8 @@ void AV1HighbdJntConvolve2DTest::RunSpeedTest( ConvolveParams conv_params = 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; + // Test special case where dist_wtd_comp_avg is not used + conv_params.use_dist_wtd_comp_avg = 0; subx = 0; suby = 0; @@ -601,9 +603,9 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput( ConvolveParams conv_params2 = get_conv_params_no_round( 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; - conv_params2.use_jnt_comp_avg = 0; + // Test special case where dist_wtd_comp_avg is not used + conv_params1.use_dist_wtd_comp_avg = 0; + conv_params2.use_dist_wtd_comp_avg = 0; const int subx_range = has_subx ? 16 : 1; const int suby_range = has_suby ? 16 : 1; @@ -612,10 +614,10 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput( // Choose random locations within the source block const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_highbd_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, - output16_1, MAX_SB_SIZE, out_w, out_h, - filter_params_x, filter_params_y, subx, - suby, &conv_params1, bd); + av1_highbd_dist_wtd_convolve_2d_c( + input + offset_r * w + offset_c, w, output16_1, MAX_SB_SIZE, + out_w, out_h, filter_params_x, filter_params_y, subx, suby, + &conv_params1, bd); test_impl(input + offset_r * w + offset_c, w, output16_2, MAX_SB_SIZE, out_w, out_h, filter_params_x, filter_params_y, subx, suby, &conv_params2, bd); @@ -648,8 +650,8 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput( // Test different combination of fwd and bck offset weights for (int k = 0; k < 2; ++k) { for (int l = 0; l < 4; ++l) { - conv_params1.use_jnt_comp_avg = 1; - conv_params2.use_jnt_comp_avg = 1; + conv_params1.use_dist_wtd_comp_avg = 1; + conv_params2.use_dist_wtd_comp_avg = 1; conv_params1.fwd_offset = quant_dist_lookup_table[k][l][0]; conv_params1.bck_offset = quant_dist_lookup_table[k][l][1]; conv_params2.fwd_offset = quant_dist_lookup_table[k][l][0]; @@ -662,7 +664,7 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput( // Choose random locations within the source block const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_highbd_jnt_convolve_2d_c( + av1_highbd_dist_wtd_convolve_2d_c( input + offset_r * w + offset_c, w, output16_1, MAX_SB_SIZE, out_w, out_h, filter_params_x, filter_params_y, subx, suby, &conv_params1, bd); @@ -702,4 +704,5 @@ void AV1HighbdJntConvolve2DTest::RunCheckOutput( } } } // namespace AV1HighbdConvolve2D +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test diff --git a/media/libaom/src/test/av1_convolve_2d_test_util.h b/media/libaom/src/test/av1_convolve_2d_test_util.h index e0eb58410..3c19cfed3 100644 --- a/media/libaom/src/test/av1_convolve_2d_test_util.h +++ b/media/libaom/src/test/av1_convolve_2d_test_util.h @@ -12,6 +12,8 @@ #ifndef AOM_TEST_AV1_CONVOLVE_2D_TEST_UTIL_H_ #define AOM_TEST_AV1_CONVOLVE_2D_TEST_UTIL_H_ +#include <tuple> + #include "config/av1_rtcd.h" #include "config/aom_dsp_rtcd.h" @@ -30,11 +32,10 @@ typedef void (*convolve_2d_func)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, - const int subpel_x_q4, const int subpel_y_q4, + const int subpel_x_qn, const int subpel_y_qn, ConvolveParams *conv_params); -typedef ::testing::tuple<convolve_2d_func, int, int, BLOCK_SIZE> - Convolve2DParam; +typedef std::tuple<convolve_2d_func, int, int, BLOCK_SIZE> Convolve2DParam; ::testing::internal::ParamGenerator<Convolve2DParam> BuildParams( convolve_2d_func filter, int subx_exist, int suby_exist); @@ -68,14 +69,15 @@ class AV1JntConvolve2DTest : public ::testing::TestWithParam<Convolve2DParam> { }; } // namespace AV1Convolve2D +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdConvolve2D { typedef void (*highbd_convolve_2d_func)( const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, - const InterpFilterParams *filter_params_y, const int subpel_x_q4, - const int subpel_y_q4, ConvolveParams *conv_params, int bd); + const InterpFilterParams *filter_params_y, const int subpel_x_qn, + const int subpel_y_qn, ConvolveParams *conv_params, int bd); -typedef ::testing::tuple<int, highbd_convolve_2d_func, int, int, BLOCK_SIZE> +typedef std::tuple<int, highbd_convolve_2d_func, int, int, BLOCK_SIZE> HighbdConvolve2DParam; ::testing::internal::ParamGenerator<HighbdConvolve2DParam> BuildParams( @@ -111,6 +113,7 @@ class AV1HighbdJntConvolve2DTest libaom_test::ACMRandom rnd_; }; } // namespace AV1HighbdConvolve2D +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test diff --git a/media/libaom/src/test/av1_convolve_scale_test.cc b/media/libaom/src/test/av1_convolve_scale_test.cc index 3b1698eeb..ffd0bab33 100644 --- a/media/libaom/src/test/av1_convolve_scale_test.cc +++ b/media/libaom/src/test/av1_convolve_scale_test.cc @@ -9,6 +9,7 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> #include <vector> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -32,9 +33,9 @@ const int kHPad = 32; const int kXStepQn = 16; const int kYStepQn = 20; -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; +using std::make_tuple; +using std::tuple; enum NTaps { EIGHT_TAP, TEN_TAP, TWELVE_TAP }; int NTapsToInt(NTaps ntaps) { return 8 + static_cast<int>(ntaps) * 2; } @@ -269,8 +270,8 @@ class ConvolveScaleTestBase : public ::testing::Test { protected: void SetParams(const BaseParams ¶ms, int bd) { - width_ = ::testing::get<0>(params.dims); - height_ = ::testing::get<1>(params.dims); + width_ = std::get<0>(params.dims); + height_ = std::get<1>(params.dims); ntaps_x_ = params.ntaps_x; ntaps_y_ = params.ntaps_y; bd_ = bd; @@ -286,13 +287,13 @@ class ConvolveScaleTestBase : public ::testing::Test { } void SetConvParamOffset(int i, int j, int is_compound, int do_average, - int use_jnt_comp_avg) { + int use_dist_wtd_comp_avg) { if (i == -1 && j == -1) { - convolve_params_.use_jnt_comp_avg = use_jnt_comp_avg; + convolve_params_.use_dist_wtd_comp_avg = use_dist_wtd_comp_avg; convolve_params_.is_compound = is_compound; convolve_params_.do_average = do_average; } else { - convolve_params_.use_jnt_comp_avg = use_jnt_comp_avg; + convolve_params_.use_dist_wtd_comp_avg = use_dist_wtd_comp_avg; convolve_params_.fwd_offset = quant_dist_lookup_table[i][j][0]; convolve_params_.bck_offset = quant_dist_lookup_table[i][j][1]; convolve_params_.is_compound = is_compound; @@ -312,12 +313,12 @@ class ConvolveScaleTestBase : public ::testing::Test { is_compound = 1; for (int do_average = 0; do_average < 2; do_average++) { - for (int use_jnt_comp_avg = 0; use_jnt_comp_avg < 2; - use_jnt_comp_avg++) { + for (int use_dist_wtd_comp_avg = 0; use_dist_wtd_comp_avg < 2; + use_dist_wtd_comp_avg++) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 4; ++k) { SetConvParamOffset(j, k, is_compound, do_average, - use_jnt_comp_avg); + use_dist_wtd_comp_avg); Prep(&rnd); RunOne(true); RunOne(false); @@ -454,13 +455,14 @@ const NTaps kNTaps[] = { EIGHT_TAP }; TEST_P(LowBDConvolveScaleTest, Check) { Run(); } TEST_P(LowBDConvolveScaleTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, LowBDConvolveScaleTest, ::testing::Combine(::testing::Values(av1_convolve_2d_scale_sse4_1), ::testing::ValuesIn(kBlockDim), ::testing::ValuesIn(kNTaps), ::testing::ValuesIn(kNTaps), ::testing::Bool())); +#if CONFIG_AV1_HIGHBITDEPTH typedef void (*HighbdConvolveFunc)(const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, @@ -520,10 +522,11 @@ const int kBDs[] = { 8, 10, 12 }; TEST_P(HighBDConvolveScaleTest, Check) { Run(); } TEST_P(HighBDConvolveScaleTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, HighBDConvolveScaleTest, ::testing::Combine(::testing::Values(av1_highbd_convolve_2d_scale_sse4_1), ::testing::ValuesIn(kBlockDim), ::testing::ValuesIn(kNTaps), ::testing::ValuesIn(kNTaps), ::testing::Bool(), ::testing::ValuesIn(kBDs))); +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/av1_encoder_parms_get_to_decoder.cc b/media/libaom/src/test/av1_encoder_parms_get_to_decoder.cc index e8470e5d5..76b82f58f 100644 --- a/media/libaom/src/test/av1_encoder_parms_get_to_decoder.cc +++ b/media/libaom/src/test/av1_encoder_parms_get_to_decoder.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -95,7 +97,7 @@ class AVxEncoderParmsGetToDecoder virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_COLOR_PRIMARIES, encode_parms.color_primaries); encoder->Control(AV1E_SET_TRANSFER_CHARACTERISTICS, encode_parms.transfer_characteristics); @@ -146,7 +148,7 @@ class AVxEncoderParmsGetToDecoder TEST_P(AVxEncoderParmsGetToDecoder, BitstreamParms) { init_flags_ = AOM_CODEC_USE_PSNR; - testing::internal::scoped_ptr<libaom_test::VideoSource> video( + std::unique_ptr<libaom_test::VideoSource> video( new libaom_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames)); ASSERT_TRUE(video.get() != NULL); diff --git a/media/libaom/src/test/av1_fwd_txfm1d_test.cc b/media/libaom/src/test/av1_fwd_txfm1d_test.cc index 49a666879..abc46ed5a 100644 --- a/media/libaom/src/test/av1_fwd_txfm1d_test.cc +++ b/media/libaom/src/test/av1_fwd_txfm1d_test.cc @@ -13,12 +13,12 @@ #include "test/av1_txfm_test.h" using libaom_test::ACMRandom; +using libaom_test::input_base; +using libaom_test::reference_hybrid_1d; using libaom_test::TYPE_ADST; using libaom_test::TYPE_DCT; using libaom_test::TYPE_IDTX; using libaom_test::TYPE_TXFM; -using libaom_test::input_base; -using libaom_test::reference_hybrid_1d; namespace { const int txfm_type_num = 3; @@ -30,11 +30,11 @@ const int txfm_size_num = 5; const int txfm_size_ls[] = { 4, 8, 16, 32, 64 }; const TxfmFunc fwd_txfm_func_ls[][txfm_type_num] = { - { av1_fdct4_new, av1_fadst4_new, av1_fidentity4_c }, - { av1_fdct8_new, av1_fadst8_new, av1_fidentity8_c }, - { av1_fdct16_new, av1_fadst16_new, av1_fidentity16_c }, - { av1_fdct32_new, NULL, av1_fidentity32_c }, - { av1_fdct64_new, NULL, NULL }, + { av1_fdct4, av1_fadst4, av1_fidentity4_c }, + { av1_fdct8, av1_fadst8, av1_fidentity8_c }, + { av1_fdct16, av1_fadst16, av1_fidentity16_c }, + { av1_fdct32, NULL, av1_fidentity32_c }, + { av1_fdct64, NULL, NULL }, }; // the maximum stage number of fwd/inv 1d dct/adst txfm is 12 @@ -56,7 +56,7 @@ TEST(av1_fwd_txfm1d, av1_cospi_arr_data) { for (int i = 0; i < 7; i++) { for (int j = 0; j < 64; j++) { EXPECT_EQ(av1_cospi_arr_data[i][j], - (int32_t)round(cos(M_PI * j / 128) * (1 << (cos_bit_min + i)))); + (int32_t)round(cos(PI * j / 128) * (1 << (cos_bit_min + i)))); } } } diff --git a/media/libaom/src/test/av1_fwd_txfm2d_test.cc b/media/libaom/src/test/av1_fwd_txfm2d_test.cc index 75f20536b..dd6066576 100644 --- a/media/libaom/src/test/av1_fwd_txfm2d_test.cc +++ b/media/libaom/src/test/av1_fwd_txfm2d_test.cc @@ -12,6 +12,7 @@ #include <math.h> #include <stdio.h> #include <stdlib.h> +#include <tuple> #include <vector> #include "config/av1_rtcd.h" @@ -23,16 +24,16 @@ #include "av1/encoder/hybrid_fwd_txfm.h" using libaom_test::ACMRandom; -using libaom_test::TYPE_TXFM; using libaom_test::bd; using libaom_test::compute_avg_abs_error; using libaom_test::input_base; +using libaom_test::TYPE_TXFM; using std::vector; namespace { // tx_type_, tx_size_, max_error_, max_avg_error_ -typedef ::testing::tuple<TX_TYPE, TX_SIZE, double, double> AV1FwdTxfm2dParam; +typedef std::tuple<TX_TYPE, TX_SIZE, double, double> AV1FwdTxfm2dParam; class AV1FwdTxfm2d : public ::testing::TestWithParam<AV1FwdTxfm2dParam> { public: @@ -196,8 +197,8 @@ vector<AV1FwdTxfm2dParam> GetTxfm2dParamList() { return param_list; } -INSTANTIATE_TEST_CASE_P(C, AV1FwdTxfm2d, - ::testing::ValuesIn(GetTxfm2dParamList())); +INSTANTIATE_TEST_SUITE_P(C, AV1FwdTxfm2d, + ::testing::ValuesIn(GetTxfm2dParamList())); TEST_P(AV1FwdTxfm2d, RunFwdAccuracyCheck) { RunFwdAccuracyCheck(); } @@ -288,14 +289,78 @@ void AV1FwdTxfm2dMatchTest(TX_SIZE tx_size, lowbd_fwd_txfm_func target_func) { } } -typedef ::testing::tuple<TX_SIZE, lowbd_fwd_txfm_func> LbdFwdTxfm2dParam; +void AV1FwdTxfm2dSpeedTest(TX_SIZE tx_size, lowbd_fwd_txfm_func target_func) { + 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 = 8; + for (int tx_type = 0; tx_type < TX_TYPES; ++tx_type) { + if (libaom_test::IsTxSizeTypeValid( + tx_size, static_cast<TX_TYPE>(tx_type)) == false) { + continue; + } + + FwdTxfm2dFunc ref_func = libaom_test::fwd_txfm_func_ls[tx_size]; + if (ref_func != NULL) { + DECLARE_ALIGNED(32, int16_t, input[64 * 64]) = { 0 }; + DECLARE_ALIGNED(32, int32_t, output[64 * 64]); + DECLARE_ALIGNED(32, int32_t, ref_output[64 * 64]); + int input_stride = 64; + ACMRandom rnd(ACMRandom::DeterministicSeed()); + + for (int r = 0; r < rows; ++r) { + for (int c = 0; c < cols; ++c) { + input[r * input_stride + c] = rnd.Rand16() % (1 << bd); + } + } + + param.tx_type = (TX_TYPE)tx_type; + param.tx_size = (TX_SIZE)tx_size; + param.tx_set_type = EXT_TX_SET_ALL16; + param.bd = bd; + + aom_usec_timer ref_timer, test_timer; + + aom_usec_timer_start(&ref_timer); + for (int i = 0; i < num_loops; ++i) { + ref_func(input, ref_output, input_stride, (TX_TYPE)tx_type, bd); + } + aom_usec_timer_mark(&ref_timer); + const int elapsed_time_c = + static_cast<int>(aom_usec_timer_elapsed(&ref_timer)); + + aom_usec_timer_start(&test_timer); + for (int i = 0; i < num_loops; ++i) { + target_func(input, output, input_stride, ¶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 std::tuple<TX_SIZE, lowbd_fwd_txfm_func> LbdFwdTxfm2dParam; class AV1FwdTxfm2dTest : public ::testing::TestWithParam<LbdFwdTxfm2dParam> {}; TEST_P(AV1FwdTxfm2dTest, match) { AV1FwdTxfm2dMatchTest(GET_PARAM(0), GET_PARAM(1)); } - +TEST_P(AV1FwdTxfm2dTest, DISABLED_Speed) { + AV1FwdTxfm2dSpeedTest(GET_PARAM(0), GET_PARAM(1)); +} using ::testing::Combine; using ::testing::Values; using ::testing::ValuesIn; @@ -323,9 +388,9 @@ static TX_SIZE fwd_txfm_for_sse2[] = { TX_64X16, }; -INSTANTIATE_TEST_CASE_P(SSE2, AV1FwdTxfm2dTest, - Combine(ValuesIn(fwd_txfm_for_sse2), - Values(av1_lowbd_fwd_txfm_sse2))); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1FwdTxfm2dTest, + Combine(ValuesIn(fwd_txfm_for_sse2), + Values(av1_lowbd_fwd_txfm_sse2))); #endif // HAVE_SSE2 #if HAVE_SSE4_1 @@ -336,9 +401,9 @@ static TX_SIZE fwd_txfm_for_sse41[] = { TX_64X32, }; -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1FwdTxfm2dTest, - Combine(ValuesIn(fwd_txfm_for_sse41), - Values(av1_lowbd_fwd_txfm_sse4_1))); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1FwdTxfm2dTest, + Combine(ValuesIn(fwd_txfm_for_sse41), + Values(av1_lowbd_fwd_txfm_sse4_1))); #endif // HAVE_SSE4_1 #if HAVE_AVX2 @@ -348,9 +413,9 @@ static TX_SIZE fwd_txfm_for_avx2[] = { TX_16X4, TX_8X32, TX_32X8, TX_16X64, TX_64X16, }; -INSTANTIATE_TEST_CASE_P(AVX2, AV1FwdTxfm2dTest, - Combine(ValuesIn(fwd_txfm_for_avx2), - Values(av1_lowbd_fwd_txfm_avx2))); +INSTANTIATE_TEST_SUITE_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, @@ -479,7 +544,7 @@ void AV1HighbdFwdTxfm2dSpeedTest(TX_SIZE tx_size, } } -typedef ::testing::tuple<TX_SIZE, Highbd_fwd_txfm_func> HighbdFwdTxfm2dParam; +typedef std::tuple<TX_SIZE, Highbd_fwd_txfm_func> HighbdFwdTxfm2dParam; class AV1HighbdFwdTxfm2dTest : public ::testing::TestWithParam<HighbdFwdTxfm2dParam> {}; @@ -503,9 +568,16 @@ static TX_SIZE Highbd_fwd_txfm_for_sse4_1[] = { 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))); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1HighbdFwdTxfm2dTest, + Combine(ValuesIn(Highbd_fwd_txfm_for_sse4_1), + Values(av1_highbd_fwd_txfm))); #endif // HAVE_SSE4_1 +#if HAVE_AVX2 +static TX_SIZE Highbd_fwd_txfm_for_avx2[] = { TX_8X8, TX_16X16, TX_32X32, + TX_64X64, TX_8X16, TX_16X8 }; +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HighbdFwdTxfm2dTest, + Combine(ValuesIn(Highbd_fwd_txfm_for_avx2), + Values(av1_highbd_fwd_txfm))); +#endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/av1_highbd_iht_test.cc b/media/libaom/src/test/av1_highbd_iht_test.cc index 2d6490c2a..8fea500db 100644 --- a/media/libaom/src/test/av1_highbd_iht_test.cc +++ b/media/libaom/src/test/av1_highbd_iht_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/av1_rtcd.h" @@ -25,15 +27,32 @@ namespace { -using ::testing::tuple; using libaom_test::ACMRandom; +using std::tuple; typedef void (*HbdHtFunc)(const int16_t *input, int32_t *output, int stride, TX_TYPE tx_type, int bd); typedef void (*IHbdHtFunc)(const int32_t *coeff, uint16_t *output, int stride, TX_TYPE tx_type, int bd); - +static const char *tx_type_name[] = { + "DCT_DCT", + "ADST_DCT", + "DCT_ADST", + "ADST_ADST", + "FLIPADST_DCT", + "DCT_FLIPADST", + "FLIPADST_FLIPADST", + "ADST_FLIPADST", + "FLIPADST_ADST", + "IDTX", + "V_DCT", + "H_DCT", + "V_ADST", + "H_ADST", + "V_FLIPADST", + "H_FLIPADST", +}; // Test parameter argument list: // <transform reference function, // optimized inverse transform function, @@ -138,7 +157,7 @@ void AV1HighbdInvHTNxN::RunBitexactCheck() { TEST_P(AV1HighbdInvHTNxN, InvTransResultCheck) { RunBitexactCheck(); } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSE4_1 #define PARAM_LIST_4X4 \ @@ -167,27 +186,28 @@ const IHbdHtParam kArrayIhtParam[] = { make_tuple(PARAM_LIST_4X4, FLIPADST_ADST, 12), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdInvHTNxN, - ::testing::ValuesIn(kArrayIhtParam)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1HighbdInvHTNxN, + ::testing::ValuesIn(kArrayIhtParam)); #endif // HAVE_SSE4_1 typedef void (*HighbdInvTxfm2dFunc)(const int32_t *input, uint8_t *output, int stride, const TxfmParam *txfm_param); -typedef ::testing::tuple<const HighbdInvTxfm2dFunc> AV1HighbdInvTxfm2dParam; +typedef std::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); + int bit_depth, int gt_int16 = 0); private: HighbdInvTxfm2dFunc target_func_; }; void AV1HighbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type_, TX_SIZE tx_size_, - int run_times, int bit_depth_) { + int run_times, int bit_depth_, + int gt_int16) { FwdTxfm2dFunc fwd_func_ = libaom_test::fwd_txfm_func_ls[tx_size_]; TxfmParam txfm_param; const int BLK_WIDTH = 64; @@ -234,8 +254,15 @@ void AV1HighbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type_, TX_SIZE tx_size_, inv_input[scan[i]] = 0; } txfm_param.eob = eob; - aom_usec_timer ref_timer, test_timer; + if (gt_int16) { + const uint16_t inv_input_mask = + static_cast<uint16_t>((1 << (bit_depth_ + 7)) - 1); + for (int i = 0; i < eob; i++) { + inv_input[scan[i]] = (rnd.Rand31() & inv_input_mask); + } + } + 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), @@ -264,7 +291,8 @@ void AV1HighbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type_, TX_SIZE tx_size_, 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; + << " bit_depth_: " << bit_depth_ + << " tx_type: " << tx_type_name[tx_type_] << " eob " << eob; } } } @@ -272,8 +300,8 @@ void AV1HighbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type_, TX_SIZE tx_size_, } TEST_P(AV1HighbdInvTxfm2d, match) { - int bitdepth_ar[2] = { 10, 12 }; - for (int k = 0; k < 2; ++k) { + int bitdepth_ar[3] = { 8, 10, 12 }; + for (int k = 0; k < 3; ++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) { @@ -287,6 +315,25 @@ TEST_P(AV1HighbdInvTxfm2d, match) { } } +TEST_P(AV1HighbdInvTxfm2d, gt_int16) { + int bitdepth_ar[3] = { 8, 10, 12 }; + static const TX_TYPE types[] = { + DCT_DCT, ADST_DCT, FLIPADST_DCT, IDTX, V_DCT, H_DCT, H_ADST, H_FLIPADST + }; + for (int k = 0; k < 3; ++k) { + int bd = bitdepth_ar[k]; + for (int j = 0; j < (int)(TX_SIZES_ALL); ++j) { + const TX_SIZE sz = static_cast<TX_SIZE>(j); + for (uint8_t i = 0; i < sizeof(types) / sizeof(TX_TYPE); ++i) { + const TX_TYPE tp = types[i]; + if (libaom_test::IsTxSizeTypeValid(sz, tp)) { + RunAV1InvTxfm2dTest(tp, sz, 1, bd, 1); + } + } + } + } +} + TEST_P(AV1HighbdInvTxfm2d, DISABLED_Speed) { int bitdepth_ar[2] = { 10, 12 }; for (int k = 0; k < 2; ++k) { @@ -304,12 +351,12 @@ TEST_P(AV1HighbdInvTxfm2d, DISABLED_Speed) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdInvTxfm2d, - ::testing::Values(av1_highbd_inv_txfm_add_sse4_1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1HighbdInvTxfm2d, + ::testing::Values(av1_highbd_inv_txfm_add_sse4_1)); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdInvTxfm2d, - ::testing::Values(av1_highbd_inv_txfm_add_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HighbdInvTxfm2d, + ::testing::Values(av1_highbd_inv_txfm_add_avx2)); #endif } // namespace diff --git a/media/libaom/src/test/av1_horz_only_frame_superres_test.cc b/media/libaom/src/test/av1_horz_only_frame_superres_test.cc index fd77ef35d..115fc84c0 100644 --- a/media/libaom/src/test/av1_horz_only_frame_superres_test.cc +++ b/media/libaom/src/test/av1_horz_only_frame_superres_test.cc @@ -9,6 +9,7 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> #include <vector> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -30,9 +31,9 @@ const int kPerfIters = 1000; const int kVPad = 32; const int kHPad = 32; -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; +using std::make_tuple; +using std::tuple; template <typename Pixel> class TestImage { @@ -297,9 +298,10 @@ class LowBDConvolveHorizRSTest TEST_P(LowBDConvolveHorizRSTest, Correctness) { CorrectnessTest(); } TEST_P(LowBDConvolveHorizRSTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_CASE_P(SSE4_1, LowBDConvolveHorizRSTest, - ::testing::Values(av1_convolve_horiz_rs_sse4_1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, LowBDConvolveHorizRSTest, + ::testing::Values(av1_convolve_horiz_rs_sse4_1)); +#if CONFIG_AV1_HIGHBITDEPTH typedef void (*HighBDConvolveHorizRsFunc)(const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, int w, int h, const int16_t *x_filters, @@ -354,9 +356,10 @@ const int kBDs[] = { 8, 10, 12 }; TEST_P(HighBDConvolveHorizRSTest, Correctness) { CorrectnessTest(); } TEST_P(HighBDConvolveHorizRSTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, HighBDConvolveHorizRSTest, ::testing::Combine(::testing::Values(av1_highbd_convolve_horiz_rs_sse4_1), ::testing::ValuesIn(kBDs))); +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/av1_inv_txfm1d_test.cc b/media/libaom/src/test/av1_inv_txfm1d_test.cc index bf3a44ed1..01d4a4d7f 100644 --- a/media/libaom/src/test/av1_inv_txfm1d_test.cc +++ b/media/libaom/src/test/av1_inv_txfm1d_test.cc @@ -16,6 +16,8 @@ #include "av1/common/av1_inv_txfm1d.h" #include "av1/encoder/av1_fwd_txfm1d.h" +typedef TX_SIZE TxSize; + using libaom_test::ACMRandom; using libaom_test::input_base; @@ -24,19 +26,15 @@ const int txfm_type_num = 2; const int txfm_size_ls[] = { 4, 8, 16, 32, 64 }; const TxfmFunc fwd_txfm_func_ls[][txfm_type_num] = { - { av1_fdct4_new, av1_fadst4_new }, - { av1_fdct8_new, av1_fadst8_new }, - { av1_fdct16_new, av1_fadst16_new }, - { av1_fdct32_new, NULL }, - { av1_fdct64_new, NULL }, + { av1_fdct4, av1_fadst4 }, { av1_fdct8, av1_fadst8 }, + { av1_fdct16, av1_fadst16 }, { av1_fdct32, NULL }, + { av1_fdct64, NULL }, }; const TxfmFunc inv_txfm_func_ls[][txfm_type_num] = { - { av1_idct4_new, av1_iadst4_new }, - { av1_idct8_new, av1_iadst8_new }, - { av1_idct16_new, av1_iadst16_new }, - { av1_idct32_new, NULL }, - { av1_idct64_new, NULL }, + { av1_idct4, av1_iadst4 }, { av1_idct8, av1_iadst8 }, + { av1_idct16, av1_iadst16 }, { av1_idct32, NULL }, + { av1_idct64, NULL }, }; // the maximum stage number of fwd/inv 1d dct/adst txfm is 12 @@ -77,7 +75,7 @@ TEST(av1_inv_txfm1d, InvAccuracyCheck) { ASSERT_EQ(NELEMENTS(inv_txfm_func_ls), TX_SIZES); for (int k = 0; k < count_test_block; ++k) { // choose a random transform to test - const TX_SIZE tx_size = static_cast<TX_SIZE>(rnd.Rand8() % TX_SIZES); + const TxSize tx_size = static_cast<TxSize>(rnd.Rand8() % TX_SIZES); const int tx_size_pix = txfm_size_ls[tx_size]; const TxfmFunc inv_txfm_func = inv_txfm_func_ls[tx_size][0]; @@ -88,9 +86,11 @@ TEST(av1_inv_txfm1d, InvAccuracyCheck) { memset(input + 32, 0, 32 * sizeof(input[0])); int32_t ref_output[64]; + memset(ref_output, 0, sizeof(ref_output)); reference_idct_1d_int(input, ref_output, tx_size_pix); int32_t output[64]; + memset(output, 0, sizeof(output)); inv_txfm_func(input, output, cos_bit, range_bit); for (int i = 0; i < tx_size_pix; ++i) { diff --git a/media/libaom/src/test/av1_inv_txfm2d_test.cc b/media/libaom/src/test/av1_inv_txfm2d_test.cc index 11e231ba6..eacdf85d4 100644 --- a/media/libaom/src/test/av1_inv_txfm2d_test.cc +++ b/media/libaom/src/test/av1_inv_txfm2d_test.cc @@ -12,6 +12,7 @@ #include <math.h> #include <stdio.h> #include <stdlib.h> +#include <tuple> #include <vector> #include "config/av1_rtcd.h" @@ -24,11 +25,11 @@ #include "test/util.h" using libaom_test::ACMRandom; -using libaom_test::InvTxfm2dFunc; -using libaom_test::LbdInvTxfm2dFunc; using libaom_test::bd; using libaom_test::compute_avg_abs_error; using libaom_test::input_base; +using libaom_test::InvTxfm2dFunc; +using libaom_test::LbdInvTxfm2dFunc; using ::testing::Combine; using ::testing::Range; @@ -36,11 +37,33 @@ using ::testing::Values; using std::vector; +typedef TX_TYPE TxType; +typedef TX_SIZE TxSize; + namespace { +static const char *tx_type_name[] = { + "DCT_DCT", + "ADST_DCT", + "DCT_ADST", + "ADST_ADST", + "FLIPADST_DCT", + "DCT_FLIPADST", + "FLIPADST_FLIPADST", + "ADST_FLIPADST", + "FLIPADST_ADST", + "IDTX", + "V_DCT", + "H_DCT", + "V_ADST", + "H_ADST", + "V_FLIPADST", + "H_FLIPADST", +}; + // AV1InvTxfm2dParam argument list: // tx_type_, tx_size_, max_error_, max_avg_error_ -typedef ::testing::tuple<TX_TYPE, TX_SIZE, int, double> AV1InvTxfm2dParam; +typedef std::tuple<TxType, TxSize, int, double> AV1InvTxfm2dParam; class AV1InvTxfm2d : public ::testing::TestWithParam<AV1InvTxfm2dParam> { public: @@ -86,7 +109,7 @@ class AV1InvTxfm2d : public ::testing::TestWithParam<AV1InvTxfm2dParam> { } double ref_coeffs[64 * 64] = { 0 }; ASSERT_LE(txfm2d_size, NELEMENTS(ref_coeffs)); - ASSERT_EQ(tx_type_, DCT_DCT); + ASSERT_EQ(tx_type_, static_cast<TxType>(DCT_DCT)); libaom_test::reference_hybrid_2d(ref_input, ref_coeffs, tx_type_, tx_size_); DECLARE_ALIGNED(16, int32_t, ref_coeffs_int[64 * 64]) = { 0 }; @@ -139,8 +162,8 @@ class AV1InvTxfm2d : public ::testing::TestWithParam<AV1InvTxfm2dParam> { int max_error_; double max_avg_error_; - TX_TYPE tx_type_; - TX_SIZE tx_size_; + TxType tx_type_; + TxSize tx_size_; }; static int max_error_ls[TX_SIZES_ALL] = { @@ -193,8 +216,8 @@ vector<AV1InvTxfm2dParam> GetInvTxfm2dParamList() { const int max_error = max_error_ls[s]; const double avg_error = avg_error_ls[s]; for (int t = 0; t < TX_TYPES; ++t) { - const TX_TYPE tx_type = static_cast<TX_TYPE>(t); - const TX_SIZE tx_size = static_cast<TX_SIZE>(s); + const TxType tx_type = static_cast<TxType>(t); + const TxSize tx_size = static_cast<TxSize>(s); if (libaom_test::IsTxSizeTypeValid(tx_size, tx_type)) { param_list.push_back( AV1InvTxfm2dParam(tx_type, tx_size, max_error, avg_error)); @@ -204,8 +227,8 @@ vector<AV1InvTxfm2dParam> GetInvTxfm2dParamList() { return param_list; } -INSTANTIATE_TEST_CASE_P(C, AV1InvTxfm2d, - ::testing::ValuesIn(GetInvTxfm2dParamList())); +INSTANTIATE_TEST_SUITE_P(C, AV1InvTxfm2d, + ::testing::ValuesIn(GetInvTxfm2dParamList())); TEST_P(AV1InvTxfm2d, RunRoundtripCheck) { RunRoundtripCheck(); } @@ -216,18 +239,18 @@ TEST(AV1InvTxfm2d, CfgTest) { int8_t high_range = libaom_test::high_range_arr[bd_idx]; for (int tx_size = 0; tx_size < TX_SIZES_ALL; ++tx_size) { for (int tx_type = 0; tx_type < TX_TYPES; ++tx_type) { - if (libaom_test::IsTxSizeTypeValid(static_cast<TX_SIZE>(tx_size), - static_cast<TX_TYPE>(tx_type)) == + if (libaom_test::IsTxSizeTypeValid(static_cast<TxSize>(tx_size), + static_cast<TxType>(tx_type)) == false) { continue; } TXFM_2D_FLIP_CFG cfg; - av1_get_inv_txfm_cfg(static_cast<TX_TYPE>(tx_type), - static_cast<TX_SIZE>(tx_size), &cfg); + av1_get_inv_txfm_cfg(static_cast<TxType>(tx_type), + static_cast<TxSize>(tx_size), &cfg); int8_t stage_range_col[MAX_TXFM_STAGE_NUM]; int8_t stage_range_row[MAX_TXFM_STAGE_NUM]; av1_gen_inv_stage_range(stage_range_col, stage_range_row, &cfg, - (TX_SIZE)tx_size, bd); + static_cast<TxSize>(tx_size), bd); libaom_test::txfm_stage_range_check(stage_range_col, cfg.stage_num_col, cfg.cos_bit_col, low_range, high_range); @@ -239,18 +262,19 @@ TEST(AV1InvTxfm2d, CfgTest) { } } -typedef ::testing::tuple<const LbdInvTxfm2dFunc> AV1LbdInvTxfm2dParam; +typedef std::tuple<const LbdInvTxfm2dFunc> AV1LbdInvTxfm2dParam; class AV1LbdInvTxfm2d : public ::testing::TestWithParam<AV1LbdInvTxfm2dParam> { public: virtual void SetUp() { target_func_ = GET_PARAM(0); } - void RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, int run_times); + void RunAV1InvTxfm2dTest(TxType tx_type, TxSize tx_size, int run_times, + int gt_int16 = 0); private: LbdInvTxfm2dFunc target_func_; }; -void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, - int run_times) { +void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TxType tx_type, TxSize tx_size, + int run_times, int gt_int16) { FwdTxfm2dFunc fwd_func_ = libaom_test::fwd_txfm_func_ls[tx_size]; InvTxfm2dFunc ref_func_ = libaom_test::inv_txfm_func_ls[tx_size]; if (fwd_func_ == NULL || ref_func_ == NULL || target_func_ == NULL) { @@ -275,6 +299,7 @@ void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, const int16_t eobmax = rows_nonezero * cols_nonezero; ACMRandom rnd(ACMRandom::DeterministicSeed()); int randTimes = run_times == 1 ? (eobmax + 500) : 1; + for (int cnt = 0; cnt < randTimes; ++cnt) { const int16_t max_in = (1 << (bd)) - 1; for (int r = 0; r < BLK_WIDTH; ++r) { @@ -291,7 +316,9 @@ void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, for (int i = eob; i < eobmax; i++) { inv_input[scan[i]] = 0; } - + if (gt_int16) { + inv_input[scan[eob - 1]] = ((int32_t)INT16_MAX * 100 / 141); + } aom_usec_timer timer; aom_usec_timer_start(&timer); for (int i = 0; i < run_times; ++i) { @@ -313,10 +340,13 @@ void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { uint8_t ref_value = static_cast<uint8_t>(ref_output[r * stride + c]); + if (ref_value != output[r * stride + c]) { + printf(" "); + } ASSERT_EQ(ref_value, output[r * stride + c]) << "[" << r << "," << c << "] " << cnt << " tx_size: " << static_cast<int>(tx_size) - << " tx_type: " << tx_type << " eob " << eob; + << " tx_type: " << tx_type_name[tx_type] << " eob " << eob; } } } @@ -325,21 +355,34 @@ void AV1LbdInvTxfm2d::RunAV1InvTxfm2dTest(TX_TYPE tx_type, TX_SIZE tx_size, TEST_P(AV1LbdInvTxfm2d, match) { 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); + if (libaom_test::IsTxSizeTypeValid(static_cast<TxSize>(j), + static_cast<TxType>(i))) { + RunAV1InvTxfm2dTest(static_cast<TxType>(i), static_cast<TxSize>(j), 1); } } } } -TEST_P(AV1LbdInvTxfm2d, DISABLED_Speed) { +TEST_P(AV1LbdInvTxfm2d, gt_int16) { + static const TxType types[] = { DCT_DCT, ADST_DCT, FLIPADST_DCT, IDTX, + V_DCT, H_DCT, H_ADST, H_FLIPADST }; for (int j = 0; j < (int)(TX_SIZES_ALL); ++j) { + const TxSize sz = static_cast<TxSize>(j); + for (uint8_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) { + const TxType tp = types[i]; + if (libaom_test::IsTxSizeTypeValid(sz, tp)) { + RunAV1InvTxfm2dTest(tp, sz, 1, 1); + } + } + } +} + +TEST_P(AV1LbdInvTxfm2d, DISABLED_Speed) { + for (int j = 1; 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), + if (libaom_test::IsTxSizeTypeValid(static_cast<TxSize>(j), + static_cast<TxType>(i))) { + RunAV1InvTxfm2dTest(static_cast<TxType>(i), static_cast<TxSize>(j), 10000000); } } @@ -349,30 +392,31 @@ TEST_P(AV1LbdInvTxfm2d, DISABLED_Speed) { #if HAVE_SSSE3 #if defined(_MSC_VER) || defined(__SSSE3__) #include "av1/common/x86/av1_inv_txfm_ssse3.h" -INSTANTIATE_TEST_CASE_P(SSSE3, AV1LbdInvTxfm2d, - ::testing::Values(av1_lowbd_inv_txfm2d_add_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1LbdInvTxfm2d, + ::testing::Values(av1_lowbd_inv_txfm2d_add_ssse3)); #endif // _MSC_VER || __SSSE3__ #endif // HAVE_SSSE3 #if HAVE_AVX2 extern "C" void av1_lowbd_inv_txfm2d_add_avx2(const int32_t *input, uint8_t *output, int stride, - TX_TYPE tx_type, TX_SIZE tx_size, + TxType tx_type, TxSize tx_size, int eob); -INSTANTIATE_TEST_CASE_P(AVX2, AV1LbdInvTxfm2d, - ::testing::Values(av1_lowbd_inv_txfm2d_add_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1LbdInvTxfm2d, + ::testing::Values(av1_lowbd_inv_txfm2d_add_avx2)); #endif // HAVE_AVX2 +// TODO(yunqing): Re-enable this unit test for NEON version after the functions +// are fixed. #if HAVE_NEON - extern "C" void av1_lowbd_inv_txfm2d_add_neon(const int32_t *input, uint8_t *output, int stride, TX_TYPE tx_type, TX_SIZE tx_size, int eob); -INSTANTIATE_TEST_CASE_P(NEON, AV1LbdInvTxfm2d, - ::testing::Values(av1_lowbd_inv_txfm2d_add_neon)); +INSTANTIATE_TEST_SUITE_P(NEON, AV1LbdInvTxfm2d, + ::testing::Values(av1_lowbd_inv_txfm2d_add_neon)); #endif // HAVE_NEON } // namespace diff --git a/media/libaom/src/test/av1_nn_predict_test.cc b/media/libaom/src/test/av1_nn_predict_test.cc new file mode 100644 index 000000000..c03cba8c5 --- /dev/null +++ b/media/libaom/src/test/av1_nn_predict_test.cc @@ -0,0 +1,217 @@ +/* + * 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 <tuple> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "aom/aom_integer.h" +#include "aom_ports/aom_timer.h" +#include "av1/encoder/ml.h" +#include "config/aom_config.h" +#include "config/aom_dsp_rtcd.h" +#include "config/av1_rtcd.h" +#include "test/util.h" +#include "test/register_state_check.h" +#include "test/acm_random.h" +#include "test/clear_system_state.h" + +namespace { +typedef void (*NnPredict_Func)(const float *const input_nodes, + const NN_CONFIG *const nn_config, + int reduce_prec, float *const output); + +typedef std::tuple<const NnPredict_Func> NnPredictTestParam; + +const float epsilon = 1e-3f; // Error threshold for functional equivalence + +class NnPredictTest : public ::testing::TestWithParam<NnPredictTestParam> { + public: + virtual void SetUp() { + const int MAX_NODES2 = NN_MAX_NODES_PER_LAYER * NN_MAX_NODES_PER_LAYER; + // Allocate two massive buffers on the heap for edge weights and node bias + // Then set-up the double-dimension arrays pointing into the big buffers + weights_buf = (float *)aom_malloc(MAX_NODES2 * (NN_MAX_HIDDEN_LAYERS + 1) * + sizeof(*weights_buf)); + bias_buf = + (float *)aom_malloc(NN_MAX_NODES_PER_LAYER * + (NN_MAX_HIDDEN_LAYERS + 1) * sizeof(*bias_buf)); + ASSERT_NE(weights_buf, nullptr); + ASSERT_NE(bias_buf, nullptr); + for (int i = 0; i < NN_MAX_HIDDEN_LAYERS + 1; i++) { + weights[i] = &weights_buf[i * MAX_NODES2]; + bias[i] = &bias_buf[i * NN_MAX_NODES_PER_LAYER]; + } + target_func_ = GET_PARAM(0); + } + virtual void TearDown() { + aom_free(weights_buf); + aom_free(bias_buf); + } + void RunNnPredictTest(const NN_CONFIG *const shape); + void RunNnPredictSpeedTest(const NN_CONFIG *const shape, const int run_times); + void RunNnPredictTest_all(const NN_CONFIG *const shapes, + const int num_shapes); + void RunNnPredictSpeedTest_all(const NN_CONFIG *const shapes, + const int num_shapes, const int run_times); + + private: + NnPredict_Func target_func_; + libaom_test::ACMRandom rng_; + float *weights[NN_MAX_HIDDEN_LAYERS + 1] = { 0 }; + float *bias[NN_MAX_HIDDEN_LAYERS + 1] = { 0 }; + float *weights_buf = nullptr, *bias_buf = nullptr; +}; + +void NnPredictTest::RunNnPredictTest(const NN_CONFIG *const shape) { + libaom_test::ClearSystemState(); + float inputs[NN_MAX_NODES_PER_LAYER] = { 0 }; + float outputs_test[NN_MAX_NODES_PER_LAYER] = { 0 }; + float outputs_ref[NN_MAX_NODES_PER_LAYER] = { 0 }; + + NN_CONFIG nn_config; + memcpy(&nn_config, shape, sizeof(nn_config)); + + char shape_str[32] = { 0 }; + snprintf(shape_str, sizeof(shape_str), "%d", shape->num_inputs); + for (int layer = 0; layer < shape->num_hidden_layers; layer++) + snprintf(&shape_str[strlen(shape_str)], + sizeof(shape_str) - strlen(shape_str), "x%d", + shape->num_hidden_nodes[layer]); + snprintf(&shape_str[strlen(shape_str)], sizeof(shape_str) - strlen(shape_str), + "x%d", shape->num_outputs); + + for (int i = 0; i < NN_MAX_HIDDEN_LAYERS + 1; i++) { + nn_config.weights[i] = weights[i]; + nn_config.bias[i] = bias[i]; + } + + for (int iter = 0; iter < 10000 && !HasFatalFailure(); ++iter) { + for (int node = 0; node < shape->num_inputs; node++) { + inputs[node] = ((float)rng_.Rand31() - (1 << 30)) / (1u << 31); + } + for (int layer = 0; layer < shape->num_hidden_layers; layer++) { + for (int node = 0; node < NN_MAX_NODES_PER_LAYER; node++) { + bias[layer][node] = ((float)rng_.Rand31() - (1 << 30)) / (1u << 31); + } + for (int node = 0; node < NN_MAX_NODES_PER_LAYER * NN_MAX_NODES_PER_LAYER; + node++) { + weights[layer][node] = ((float)rng_.Rand31() - (1 << 30)) / (1u << 31); + } + } + // Now the outputs: + int layer = shape->num_hidden_layers; + for (int node = 0; node < NN_MAX_NODES_PER_LAYER; node++) { + bias[layer][node] = ((float)rng_.Rand31() - (1 << 30)) / (1u << 31); + } + for (int node = 0; node < NN_MAX_NODES_PER_LAYER * NN_MAX_NODES_PER_LAYER; + node++) { + weights[layer][node] = ((float)rng_.Rand31() - (1 << 30)) / (1u << 31); + } + + av1_nn_predict_c(inputs, &nn_config, 0, outputs_ref); + target_func_(inputs, &nn_config, 0, outputs_test); + libaom_test::ClearSystemState(); + + for (int node = 0; node < shape->num_outputs; node++) { + if (outputs_ref[node] < epsilon) { + ASSERT_LE(outputs_test[node], epsilon) + << "Reference output was near-zero, test output was not (" + << shape_str << ")"; + } else { + const float error = outputs_ref[node] - outputs_test[node]; + const float relative_error = fabsf(error / outputs_ref[node]); + ASSERT_LE(relative_error, epsilon) + << "Excessive relative error between reference and test (" + << shape_str << ")"; + } + } + } +} + +void NnPredictTest::RunNnPredictSpeedTest(const NN_CONFIG *const shape, + const int run_times) { + libaom_test::ClearSystemState(); + float inputs[NN_MAX_NODES_PER_LAYER] = { 0 }; + float outputs_test[NN_MAX_NODES_PER_LAYER] = { 0 }; + float outputs_ref[NN_MAX_NODES_PER_LAYER] = { 0 }; + + NN_CONFIG nn_config; + memcpy(&nn_config, shape, sizeof(nn_config)); + + for (int i = 0; i < NN_MAX_HIDDEN_LAYERS; i++) { + nn_config.weights[i] = weights[i]; + nn_config.bias[i] = bias[i]; + } + // Don't bother actually changing the values for inputs/weights/bias: it + // shouldn't make any difference for a speed test. + + aom_usec_timer timer; + aom_usec_timer_start(&timer); + for (int i = 0; i < run_times; ++i) { + av1_nn_predict_c(inputs, &nn_config, 0, outputs_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_(inputs, &nn_config, 0, outputs_test); + } + aom_usec_timer_mark(&timer); + libaom_test::ClearSystemState(); + const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer)); + + printf("%d", shape->num_inputs); + for (int layer = 0; layer < shape->num_hidden_layers; layer++) + printf("x%d", shape->num_hidden_nodes[layer]); + printf("x%d: ", shape->num_outputs); + printf("%7.2f/%7.2fns (%3.2f)\n", time1, time2, time1 / time2); +} + +// This is all the neural network shapes observed executed in a few different +// runs of the encoder. It also conveniently covers all the kernels +// implemented. +static const NN_CONFIG shapes[] = { + { 10, 16, 1, { 64 }, { 0 }, { 0 } }, { 12, 1, 1, { 12 }, { 0 }, { 0 } }, + { 12, 1, 1, { 24 }, { 0 }, { 0 } }, { 12, 1, 1, { 32 }, { 0 }, { 0 } }, + { 18, 4, 1, { 24 }, { 0 }, { 0 } }, { 18, 4, 1, { 32 }, { 0 }, { 0 } }, + { 4, 1, 1, { 16 }, { 0 }, { 0 } }, { 8, 1, 1, { 16 }, { 0 }, { 0 } }, + { 8, 4, 1, { 16 }, { 0 }, { 0 } }, { 8, 1, 1, { 24 }, { 0 }, { 0 } }, + { 8, 1, 1, { 32 }, { 0 }, { 0 } }, { 8, 1, 1, { 64 }, { 0 }, { 0 } }, + { 9, 3, 1, { 32 }, { 0 }, { 0 } }, { 4, 4, 1, { 8 }, { 0 }, { 0 } }, +}; + +void NnPredictTest::RunNnPredictTest_all(const NN_CONFIG *const shapes, + const int num_shapes) { + for (int i = 0; i < num_shapes; i++) RunNnPredictTest(&shapes[i]); +} + +void NnPredictTest::RunNnPredictSpeedTest_all(const NN_CONFIG *const shapes, + const int num_shapes, + const int run_times) { + for (int i = 0; i < num_shapes; i++) + NnPredictTest::RunNnPredictSpeedTest(&shapes[i], run_times); +} + +TEST_P(NnPredictTest, RandomValues) { + RunNnPredictTest_all(shapes, sizeof(shapes) / sizeof(*shapes)); +} + +TEST_P(NnPredictTest, DISABLED_Speed) { + RunNnPredictSpeedTest_all(shapes, sizeof(shapes) / sizeof(*shapes), 10000000); +} + +#if HAVE_SSE3 +INSTANTIATE_TEST_SUITE_P(SSE3, NnPredictTest, + ::testing::Values(av1_nn_predict_sse3)); +#endif + +} // namespace diff --git a/media/libaom/src/test/av1_quantize_test.cc b/media/libaom/src/test/av1_quantize_test.cc index aaf093918..39a3c33d8 100644 --- a/media/libaom/src/test/av1_quantize_test.cc +++ b/media/libaom/src/test/av1_quantize_test.cc @@ -73,7 +73,7 @@ class AV1QuantizeTest : public ::testing::TestWithParam<QuantizeFuncParams> { const SCAN_ORDER scanOrder = av1_default_scan_orders[txSize]; for (int i = 0; i < numTests; i++) { int err_count = 0; - ref_eob = eob = -1; + ref_eob = eob = UINT16_MAX; for (int j = 0; j < count; j++) { coeff_ptr[j] = rnd(coeffRange); } @@ -83,7 +83,7 @@ class AV1QuantizeTest : public ::testing::TestWithParam<QuantizeFuncParams> { quant_shift_ptr[j] = rnd.Rand16(); // int16_t positive dequant_ptr[j] = abs(rnd(dequantRange)); - quant_ptr[j] = (1 << 16) / dequant_ptr[j]; + quant_ptr[j] = static_cast<int16_t>((1 << 16) / dequant_ptr[j]); round_ptr[j] = (abs(rnd(roundFactorRange)) * dequant_ptr[j]) >> 7; } for (int j = 2; j < 8; ++j) { @@ -145,7 +145,7 @@ class AV1QuantizeTest : public ::testing::TestWithParam<QuantizeFuncParams> { const SCAN_ORDER scanOrder = av1_default_scan_orders[txSize]; for (int i = 0; i < numTests; i++) { - ref_eob = eob = -1; + ref_eob = eob = UINT16_MAX; for (int j = 0; j < count; j++) { coeff_ptr[j] = 0; } @@ -218,7 +218,7 @@ const QuantizeFuncParams qfps[4] = { 1024), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1QuantizeTest, ::testing::ValuesIn(qfps)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1QuantizeTest, ::testing::ValuesIn(qfps)); #endif // HAVE_SSE4_1 #if HAVE_AVX2 @@ -233,7 +233,7 @@ const QuantizeFuncParams qfps_avx2[4] = { 1024), }; -INSTANTIATE_TEST_CASE_P(AVX2, AV1QuantizeTest, ::testing::ValuesIn(qfps_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1QuantizeTest, ::testing::ValuesIn(qfps_avx2)); #endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/av1_round_shift_array_test.cc b/media/libaom/src/test/av1_round_shift_array_test.cc index 181a39460..993fa9f19 100644 --- a/media/libaom/src/test/av1_round_shift_array_test.cc +++ b/media/libaom/src/test/av1_round_shift_array_test.cc @@ -12,8 +12,9 @@ #include <math.h> #include <stdio.h> #include <stdlib.h> +#include <tuple> -#include "config/aom_dsp_rtcd.h" +#include "config/av1_rtcd.h" #include "aom_mem/aom_mem.h" #include "aom_ports/aom_timer.h" @@ -33,7 +34,7 @@ const int kValidBitCheck[] = { }; #endif // HAVE_SSE4_1 || HAVE_NEON -typedef ::testing::tuple<comp_round_shift_array_func, BLOCK_SIZE, int> +typedef std::tuple<comp_round_shift_array_func, BLOCK_SIZE, int> CompRoundShiftParam; class AV1CompRoundShiftTest @@ -111,7 +112,7 @@ TEST_P(AV1CompRoundShiftTest, DISABLED_Speed) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AV1CompRoundShiftTest, ::testing::Combine(::testing::Values(&av1_round_shift_array_sse4_1), ::testing::ValuesIn(txsize_to_bsize), @@ -119,7 +120,7 @@ INSTANTIATE_TEST_CASE_P( #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AV1CompRoundShiftTest, ::testing::Combine(::testing::Values(&av1_round_shift_array_neon), ::testing::ValuesIn(txsize_to_bsize), diff --git a/media/libaom/src/test/av1_txfm_test.cc b/media/libaom/src/test/av1_txfm_test.cc index d5b0ce325..aedd45d13 100644 --- a/media/libaom/src/test/av1_txfm_test.cc +++ b/media/libaom/src/test/av1_txfm_test.cc @@ -94,7 +94,7 @@ double Sqrt2 = pow(2, 0.5); double invSqrt2 = 1 / pow(2, 0.5); double dct_matrix(double n, double k, int size) { - return cos(M_PI * (2 * n + 1) * k / (2 * size)); + return cos(PI * (2 * n + 1) * k / (2 * size)); } void reference_dct_1d(const double *in, double *out, int size) { @@ -119,7 +119,7 @@ void reference_idct_1d(const double *in, double *out, int size) { } } -// TODO(any): Copied from the old 'fadst4' (same as the new 'av1_fadst4_new' +// TODO(any): Copied from the old 'fadst4' (same as the new 'av1_fadst4' // function). Should be replaced by a proper reference function that takes // 'double' input & output. static void fadst4_new(const tran_low_t *input, tran_low_t *output) { @@ -179,7 +179,7 @@ void reference_adst_1d(const double *in, double *out, int size) { for (int k = 0; k < size; ++k) { out[k] = 0; for (int n = 0; n < size; ++n) { - out[k] += in[n] * sin(M_PI * (2 * n + 1) * (2 * k + 1) / (4 * size)); + out[k] += in[n] * sin(PI * (2 * n + 1) * (2 * k + 1) / (4 * size)); } } } diff --git a/media/libaom/src/test/av1_txfm_test.h b/media/libaom/src/test/av1_txfm_test.h index a18164741..5a56d28f1 100644 --- a/media/libaom/src/test/av1_txfm_test.h +++ b/media/libaom/src/test/av1_txfm_test.h @@ -29,14 +29,14 @@ #include "av1/common/enums.h" namespace libaom_test { -typedef enum { +enum { TYPE_DCT = 0, TYPE_ADST, TYPE_IDTX, TYPE_IDCT, TYPE_IADST, TYPE_LAST -} TYPE_TXFM; +} UENUM1BYTE(TYPE_TXFM); int get_txfm1d_size(TX_SIZE tx_size); diff --git a/media/libaom/src/test/av1_wedge_utils_test.cc b/media/libaom/src/test/av1_wedge_utils_test.cc index e8fbe69a4..f9dc838ff 100644 --- a/media/libaom/src/test/av1_wedge_utils_test.cc +++ b/media/libaom/src/test/av1_wedge_utils_test.cc @@ -221,7 +221,8 @@ TEST_P(WedgeUtilsSSEOptTest, ExtremeValues) { // av1_wedge_sign_from_residuals ////////////////////////////////////////////////////////////////////////////// -typedef int (*FSign)(const int16_t *ds, const uint8_t *m, int N, int64_t limit); +typedef int8_t (*FSign)(const int16_t *ds, const uint8_t *m, int N, + int64_t limit); typedef libaom_test::FuncParam<FSign> TestFuncsFSign; class WedgeUtilsSignOptTest : public FunctionEquivalenceTest<FSign> { @@ -354,34 +355,34 @@ TEST_P(WedgeUtilsDeltaSquaresOptTest, RandomValues) { } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, WedgeUtilsSSEOptTest, ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_c, av1_wedge_sse_from_residuals_sse2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, WedgeUtilsSignOptTest, ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_c, av1_wedge_sign_from_residuals_sse2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, WedgeUtilsDeltaSquaresOptTest, ::testing::Values(TestFuncsFDS(av1_wedge_compute_delta_squares_c, av1_wedge_compute_delta_squares_sse2))); #endif // HAVE_SSE2 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, WedgeUtilsSSEOptTest, ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_sse2, av1_wedge_sse_from_residuals_avx2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, WedgeUtilsSignOptTest, ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_sse2, av1_wedge_sign_from_residuals_avx2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, WedgeUtilsDeltaSquaresOptTest, ::testing::Values(TestFuncsFDS(av1_wedge_compute_delta_squares_sse2, av1_wedge_compute_delta_squares_avx2))); diff --git a/media/libaom/src/test/avg_test.cc b/media/libaom/src/test/avg_test.cc new file mode 100644 index 000000000..1742aec5f --- /dev/null +++ b/media/libaom/src/test/avg_test.cc @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. 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 <stdlib.h> +#include <tuple> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/aom_dsp_rtcd.h" + +#include "test/acm_random.h" +#include "test/clear_system_state.h" +#include "test/register_state_check.h" +#include "test/util.h" + +namespace { + +using libaom_test::ACMRandom; + +template <typename Pixel> +class AverageTestBase : public ::testing::Test { + public: + AverageTestBase(int width, int height) + : width_(width), height_(height), source_data_(NULL), source_stride_(0), + bit_depth_(8) {} + + virtual void TearDown() { + aom_free(source_data_); + source_data_ = NULL; + libaom_test::ClearSystemState(); + } + + protected: + // Handle blocks up to 4 blocks 64x64 with stride up to 128 + static const int kDataAlignment = 16; + static const int kDataBlockSize = 64 * 128; + + virtual void SetUp() { + source_data_ = static_cast<Pixel *>( + aom_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); + ASSERT_TRUE(source_data_ != NULL); + source_stride_ = (width_ + 31) & ~31; + bit_depth_ = 8; + rnd_.Reset(ACMRandom::DeterministicSeed()); + } + + // Sum Pixels + static unsigned int ReferenceAverage8x8(const Pixel *source, int pitch) { + unsigned int average = 0; + for (int h = 0; h < 8; ++h) { + for (int w = 0; w < 8; ++w) average += source[h * pitch + w]; + } + return (average + 32) >> 6; + } + + static unsigned int ReferenceAverage4x4(const Pixel *source, int pitch) { + unsigned int average = 0; + for (int h = 0; h < 4; ++h) { + for (int w = 0; w < 4; ++w) average += source[h * pitch + w]; + } + return (average + 8) >> 4; + } + + void FillConstant(Pixel fill_constant) { + for (int i = 0; i < width_ * height_; ++i) { + source_data_[i] = fill_constant; + } + } + + void FillRandom() { + for (int i = 0; i < width_ * height_; ++i) { + source_data_[i] = rnd_.Rand16() & ((1 << bit_depth_) - 1); + } + } + + int width_, height_; + Pixel *source_data_; + int source_stride_; + int bit_depth_; + + ACMRandom rnd_; +}; +typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch); + +// Arguments: width, height, pitch, block size, avg function. +typedef std::tuple<int, int, int, int, AverageFunction> AvgFunc; + +class AverageTest : public AverageTestBase<uint8_t>, + public ::testing::WithParamInterface<AvgFunc> { + public: + AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {} + + protected: + void CheckAverages() { + const int block_size = GET_PARAM(3); + unsigned int expected = 0; + if (block_size == 8) { + expected = + ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_); + } else if (block_size == 4) { + expected = + ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_); + } + + unsigned int actual; + ASM_REGISTER_STATE_CHECK( + actual = GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_)); + + EXPECT_EQ(expected, actual); + } +}; + +TEST_P(AverageTest, MinValue) { + FillConstant(0); + CheckAverages(); +} + +TEST_P(AverageTest, MaxValue) { + FillConstant(255); + CheckAverages(); +} + +TEST_P(AverageTest, Random) { + // The reference frame, but not the source frame, may be unaligned for + // certain types of searches. + for (int i = 0; i < 1000; i++) { + FillRandom(); + CheckAverages(); + } +} + +typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref, + const int ref_stride, const int height); + +// Params: height, asm function, c function. +typedef std::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam; + +class IntProRowTest : public AverageTestBase<uint8_t>, + public ::testing::WithParamInterface<IntProRowParam> { + public: + IntProRowTest() + : AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) { + asm_func_ = GET_PARAM(1); + c_func_ = GET_PARAM(2); + } + + protected: + virtual void SetUp() { + source_data_ = static_cast<uint8_t *>( + aom_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); + ASSERT_TRUE(source_data_ != NULL); + + hbuf_asm_ = static_cast<int16_t *>( + aom_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16)); + hbuf_c_ = static_cast<int16_t *>( + aom_memalign(kDataAlignment, sizeof(*hbuf_c_) * 16)); + } + + virtual void TearDown() { + aom_free(source_data_); + source_data_ = NULL; + aom_free(hbuf_c_); + hbuf_c_ = NULL; + aom_free(hbuf_asm_); + hbuf_asm_ = NULL; + } + + void RunComparison() { + ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_, source_data_, 0, height_)); + ASM_REGISTER_STATE_CHECK(asm_func_(hbuf_asm_, source_data_, 0, height_)); + EXPECT_EQ(0, memcmp(hbuf_c_, hbuf_asm_, sizeof(*hbuf_c_) * 16)) + << "Output mismatch"; + } + + private: + IntProRowFunc asm_func_; + IntProRowFunc c_func_; + int16_t *hbuf_asm_; + int16_t *hbuf_c_; +}; + +typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width); + +// Params: width, asm function, c function. +typedef std::tuple<int, IntProColFunc, IntProColFunc> IntProColParam; + +class IntProColTest : public AverageTestBase<uint8_t>, + public ::testing::WithParamInterface<IntProColParam> { + public: + IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) { + asm_func_ = GET_PARAM(1); + c_func_ = GET_PARAM(2); + } + + protected: + void RunComparison() { + ASM_REGISTER_STATE_CHECK(sum_c_ = c_func_(source_data_, width_)); + ASM_REGISTER_STATE_CHECK(sum_asm_ = asm_func_(source_data_, width_)); + EXPECT_EQ(sum_c_, sum_asm_) << "Output mismatch"; + } + + private: + IntProColFunc asm_func_; + IntProColFunc c_func_; + int16_t sum_asm_; + int16_t sum_c_; +}; + +TEST_P(IntProRowTest, MinValue) { + FillConstant(0); + RunComparison(); +} + +TEST_P(IntProRowTest, MaxValue) { + FillConstant(255); + RunComparison(); +} + +TEST_P(IntProRowTest, Random) { + FillRandom(); + RunComparison(); +} + +TEST_P(IntProColTest, MinValue) { + FillConstant(0); + RunComparison(); +} + +TEST_P(IntProColTest, MaxValue) { + FillConstant(255); + RunComparison(); +} + +TEST_P(IntProColTest, Random) { + FillRandom(); + RunComparison(); +} + +using std::make_tuple; + +INSTANTIATE_TEST_SUITE_P( + C, AverageTest, + ::testing::Values(make_tuple(16, 16, 1, 8, &aom_avg_8x8_c), + make_tuple(16, 16, 1, 4, &aom_avg_4x4_c))); + +#if HAVE_SSE2 +INSTANTIATE_TEST_SUITE_P( + SSE2, AverageTest, + ::testing::Values(make_tuple(16, 16, 0, 8, &aom_avg_8x8_sse2), + make_tuple(16, 16, 5, 8, &aom_avg_8x8_sse2), + make_tuple(32, 32, 15, 8, &aom_avg_8x8_sse2), + make_tuple(16, 16, 0, 4, &aom_avg_4x4_sse2), + make_tuple(16, 16, 5, 4, &aom_avg_4x4_sse2), + make_tuple(32, 32, 15, 4, &aom_avg_4x4_sse2))); + +INSTANTIATE_TEST_SUITE_P( + SSE2, IntProRowTest, + ::testing::Values(make_tuple(16, &aom_int_pro_row_sse2, &aom_int_pro_row_c), + make_tuple(32, &aom_int_pro_row_sse2, &aom_int_pro_row_c), + make_tuple(64, &aom_int_pro_row_sse2, &aom_int_pro_row_c), + make_tuple(128, &aom_int_pro_row_sse2, + &aom_int_pro_row_c))); + +INSTANTIATE_TEST_SUITE_P( + SSE2, IntProColTest, + ::testing::Values(make_tuple(16, &aom_int_pro_col_sse2, &aom_int_pro_col_c), + make_tuple(32, &aom_int_pro_col_sse2, &aom_int_pro_col_c), + make_tuple(64, &aom_int_pro_col_sse2, &aom_int_pro_col_c), + make_tuple(128, &aom_int_pro_col_sse2, + &aom_int_pro_col_c))); +#endif + +#if HAVE_NEON +INSTANTIATE_TEST_SUITE_P( + NEON, AverageTest, + ::testing::Values(make_tuple(16, 16, 0, 8, &aom_avg_8x8_neon), + make_tuple(16, 16, 5, 8, &aom_avg_8x8_neon), + make_tuple(32, 32, 15, 8, &aom_avg_8x8_neon), + make_tuple(16, 16, 0, 4, &aom_avg_4x4_neon), + make_tuple(16, 16, 5, 4, &aom_avg_4x4_neon), + make_tuple(32, 32, 15, 4, &aom_avg_4x4_neon))); +#endif + +} // namespace diff --git a/media/libaom/src/test/blend_a64_mask_1d_test.cc b/media/libaom/src/test/blend_a64_mask_1d_test.cc index f8844eef8..1b6350c79 100644 --- a/media/libaom/src/test/blend_a64_mask_1d_test.cc +++ b/media/libaom/src/test/blend_a64_mask_1d_test.cc @@ -194,13 +194,13 @@ static void blend_a64_vmask_ref(uint8_t *dst, uint32_t dst_stride, 0, 0); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, BlendA64Mask1DTest8B, ::testing::Values(TestFuncs(blend_a64_hmask_ref, aom_blend_a64_hmask_c), TestFuncs(blend_a64_vmask_ref, aom_blend_a64_vmask_c))); #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BlendA64Mask1DTest8B, ::testing::Values( TestFuncs(blend_a64_hmask_ref, aom_blend_a64_hmask_sse4_1), @@ -208,17 +208,17 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_SSE4_1 #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON, BlendA64Mask1DTest8B, - ::testing::Values(TestFuncs(blend_a64_hmask_ref, - aom_blend_a64_hmask_neon), - TestFuncs(blend_a64_vmask_ref, - aom_blend_a64_vmask_neon))); +INSTANTIATE_TEST_SUITE_P( + NEON, BlendA64Mask1DTest8B, + ::testing::Values(TestFuncs(blend_a64_hmask_ref, aom_blend_a64_hmask_neon), + TestFuncs(blend_a64_vmask_ref, + aom_blend_a64_vmask_neon))); #endif // HAVE_NEON ////////////////////////////////////////////////////////////////////////////// // High bit-depth version ////////////////////////////////////////////////////////////////////////////// - +#if CONFIG_AV1_HIGHBITDEPTH typedef void (*FHBD)(uint8_t *dst, uint32_t dst_stride, const uint8_t *src0, uint32_t src0_stride, const uint8_t *src1, uint32_t src1_stride, const uint8_t *mask, int w, int h, @@ -321,7 +321,7 @@ static void highbd_blend_a64_vmask_ref( BlendA64Mask1DTestHBD::kMaxMaskSize, w, h, 0, 0, bd); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, BlendA64Mask1DTestHBD, ::testing::Values(TestFuncsHBD(highbd_blend_a64_hmask_ref, aom_highbd_blend_a64_hmask_c), @@ -329,11 +329,12 @@ INSTANTIATE_TEST_CASE_P( aom_highbd_blend_a64_vmask_c))); #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BlendA64Mask1DTestHBD, ::testing::Values(TestFuncsHBD(highbd_blend_a64_hmask_ref, aom_highbd_blend_a64_hmask_sse4_1), TestFuncsHBD(highbd_blend_a64_vmask_ref, aom_highbd_blend_a64_vmask_sse4_1))); #endif // HAVE_SSE4_1 +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/blend_a64_mask_test.cc b/media/libaom/src/test/blend_a64_mask_test.cc index 66ca6fc5f..5c2c291fd 100644 --- a/media/libaom/src/test/blend_a64_mask_test.cc +++ b/media/libaom/src/test/blend_a64_mask_test.cc @@ -86,6 +86,7 @@ class BlendA64MaskTest : public FunctionEquivalenceTest<BlendA64Func> { w_ = block_size_wide[block_size]; h_ = block_size_high[block_size]; run_times = run_times > 1 ? run_times / w_ : 1; + ASSERT_GT(run_times, 0); subx_ = subx; suby_ = suby; @@ -245,16 +246,16 @@ TEST_P(BlendA64MaskTest8B, DISABLED_Speed) { } } #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 +INSTANTIATE_TEST_SUITE_P(SSE4_1, BlendA64MaskTest8B, + ::testing::Values(TestFuncs( + aom_blend_a64_mask_c, aom_blend_a64_mask_sse4_1))); +#endif // HAVE_SSE4_1 #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 +INSTANTIATE_TEST_SUITE_P(AVX2, BlendA64MaskTest8B, + ::testing::Values(TestFuncs(aom_blend_a64_mask_sse4_1, + aom_blend_a64_mask_avx2))); +#endif // HAVE_AVX2 ////////////////////////////////////////////////////////////////////////////// // 8 bit _d16 version @@ -341,21 +342,21 @@ TEST_P(BlendA64MaskTest8B_d16, ExtremeValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BlendA64MaskTest8B_d16, ::testing::Values(TestFuncs_d16(aom_lowbd_blend_a64_d16_mask_c, aom_lowbd_blend_a64_d16_mask_sse4_1))); #endif // HAVE_SSE4_1 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_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( +INSTANTIATE_TEST_SUITE_P( NEON, BlendA64MaskTest8B_d16, ::testing::Values(TestFuncs_d16(aom_lowbd_blend_a64_d16_mask_c, aom_lowbd_blend_a64_d16_mask_neon))); @@ -364,7 +365,7 @@ INSTANTIATE_TEST_CASE_P( ////////////////////////////////////////////////////////////////////////////// // High bit-depth version ////////////////////////////////////////////////////////////////////////////// - +#if CONFIG_AV1_HIGHBITDEPTH typedef void (*FHBD)(uint8_t *dst, uint32_t dst_stride, const uint8_t *src0, uint32_t src0_stride, const uint8_t *src1, uint32_t src1_stride, const uint8_t *mask, @@ -456,7 +457,7 @@ TEST_P(BlendA64MaskTestHBD, ExtremeValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BlendA64MaskTestHBD, ::testing::Values(TestFuncsHBD(aom_highbd_blend_a64_mask_c, aom_highbd_blend_a64_mask_sse4_1))); @@ -482,6 +483,7 @@ class BlendA64MaskTestHBD_d16 static const int kSrcMaxBitsMaskHBD = (1 << 16) - 1; void Execute(const uint16_t *p_src0, const uint16_t *p_src1, int run_times) { + ASSERT_GT(run_times, 0) << "Cannot run 0 iterations of the test."; ConvolveParams conv_params; conv_params.round_0 = (bit_depth_ == 12) ? ROUND0_BITS + 2 : ROUND0_BITS; conv_params.round_1 = COMPOUND_ROUND1_BITS; @@ -566,18 +568,53 @@ TEST_P(BlendA64MaskTestHBD_d16, DISABLED_SaturatedValues) { } } } +TEST_P(BlendA64MaskTestHBD_d16, DISABLED_Speed) { + const int kRunTimes = 10000000; + for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) { + for (bit_depth_ = 8; bit_depth_ <= 12; bit_depth_ += 2) { + for (int i = 0; i < kBufSize; ++i) { + dst_ref_[i] = rng_.Rand12() % (1 << bit_depth_); + dst_tst_[i] = rng_.Rand12() % (1 << bit_depth_); + + src0_[i] = rng_.Rand16(); + src1_[i] = rng_.Rand16(); + } + + for (int i = 0; i < kMaxMaskSize; ++i) + mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1); + + RunOneTest(bsize, 1, 1, kRunTimes); + RunOneTest(bsize, 0, 0, kRunTimes); + } + } +} -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, BlendA64MaskTestHBD_d16, ::testing::Values(TestFuncsHBD_d16(aom_highbd_blend_a64_d16_mask_c, NULL))); +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P( + SSE4_1, BlendA64MaskTestHBD_d16, + ::testing::Values(TestFuncsHBD_d16(aom_highbd_blend_a64_d16_mask_c, + aom_highbd_blend_a64_d16_mask_sse4_1))); +#endif // HAVE_SSE4_1 + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, BlendA64MaskTestHBD_d16, + ::testing::Values(TestFuncsHBD_d16(aom_highbd_blend_a64_d16_mask_c, + aom_highbd_blend_a64_d16_mask_avx2))); +#endif // HAVE_AVX2 + // TODO(slavarnway): Enable the following in the avx2 commit. (56501) #if 0 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BlendA64MaskTestHBD, ::testing::Values(TestFuncsHBD(aom_highbd_blend_a64_mask_c, aom_highbd_blend_a64_mask_avx2))); #endif // HAVE_AVX2 #endif +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/blockd_test.cc b/media/libaom/src/test/blockd_test.cc index ab624007c..17e696863 100644 --- a/media/libaom/src/test/blockd_test.cc +++ b/media/libaom/src/test/blockd_test.cc @@ -56,7 +56,7 @@ TEST(BlockdTest, GetPartitionSubsize) { BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID }, { BLOCK_INVALID, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4, + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16, BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32, @@ -65,7 +65,7 @@ TEST(BlockdTest, GetPartitionSubsize) { BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID }, { BLOCK_INVALID, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4, + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16, BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32, @@ -74,7 +74,7 @@ TEST(BlockdTest, GetPartitionSubsize) { BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID }, { BLOCK_INVALID, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8, + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32, BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64, @@ -83,7 +83,7 @@ TEST(BlockdTest, GetPartitionSubsize) { BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID }, { BLOCK_INVALID, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8, + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32, BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64, diff --git a/media/libaom/src/test/borders_test.cc b/media/libaom/src/test/borders_test.cc index 893237ef3..31eacab12 100644 --- a/media/libaom/src/test/borders_test.cc +++ b/media/libaom/src/test/borders_test.cc @@ -33,7 +33,7 @@ class BordersTestLarge virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, 1); encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); diff --git a/media/libaom/src/test/cdef_test.cc b/media/libaom/src/test/cdef_test.cc index becc07291..a2ec1e31e 100644 --- a/media/libaom/src/test/cdef_test.cc +++ b/media/libaom/src/test/cdef_test.cc @@ -11,6 +11,7 @@ #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -28,8 +29,8 @@ using libaom_test::ACMRandom; namespace { -typedef ::testing::tuple<cdef_filter_block_func, cdef_filter_block_func, - BLOCK_SIZE, int, int> +typedef std::tuple<cdef_filter_block_func, cdef_filter_block_func, BLOCK_SIZE, + int, int> cdef_dir_param_t; class CDEFBlockTest : public ::testing::TestWithParam<cdef_dir_param_t> { @@ -116,7 +117,7 @@ void test_cdef(int bsize, int iterations, cdef_filter_block_func cdef, ref_cdef(depth == 8 ? (uint8_t *)ref_d : 0, ref_d, size, s + CDEF_HBORDER + CDEF_VBORDER * CDEF_BSTRIDE, pristrength, secstrength, dir, pridamping, - secdamping, bsize, (1 << depth) - 1, depth - 8); + secdamping, bsize, depth - 8); // If cdef and ref_cdef are the same, we're just testing // speed if (cdef != ref_cdef) @@ -124,7 +125,7 @@ void test_cdef(int bsize, int iterations, cdef_filter_block_func cdef, cdef(depth == 8 ? (uint8_t *)d : 0, d, size, s + CDEF_HBORDER + CDEF_VBORDER * CDEF_BSTRIDE, pristrength, secstrength, dir, pridamping, - secdamping, bsize, (1 << depth) - 1, depth - 8)); + secdamping, bsize, depth - 8)); if (ref_cdef != cdef) { for (pos = 0; pos < max_pos && !error; pos++) { error = ref_d[pos] != d[pos]; @@ -185,7 +186,7 @@ void test_cdef_speed(int bsize, int iterations, cdef_filter_block_func cdef, typedef int (*find_dir_t)(const uint16_t *img, int stride, int32_t *var, int coeff_shift); -typedef ::testing::tuple<find_dir_t, find_dir_t> find_dir_param_t; +typedef std::tuple<find_dir_t, find_dir_t> find_dir_param_t; class CDEFFindDirTest : public ::testing::TestWithParam<find_dir_param_t> { public: @@ -285,140 +286,140 @@ TEST_P(CDEFFindDirSpeedTest, DISABLED_TestSpeed) { test_finddir_speed(finddir, ref_finddir); } -using ::testing::make_tuple; +using std::make_tuple; // VS compiling for 32 bit targets does not support vector types in // structs as arguments, which makes the v256 type of the intrinsics // hard to support, so optimizations for this target are disabled. #if defined(_WIN64) || !defined(_MSC_VER) || defined(__clang__) #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, CDEFBlockTest, ::testing::Combine(::testing::Values(&cdef_filter_block_sse2), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSE2, CDEFFindDirTest, - ::testing::Values(make_tuple(&cdef_find_dir_sse2, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSE2, CDEFFindDirTest, + ::testing::Values(make_tuple(&cdef_find_dir_sse2, + &cdef_find_dir_c))); #endif #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSSE3, CDEFBlockTest, ::testing::Combine(::testing::Values(&cdef_filter_block_ssse3), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSSE3, CDEFFindDirTest, - ::testing::Values(make_tuple(&cdef_find_dir_ssse3, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSSE3, CDEFFindDirTest, + ::testing::Values(make_tuple(&cdef_find_dir_ssse3, + &cdef_find_dir_c))); #endif #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, CDEFBlockTest, ::testing::Combine(::testing::Values(&cdef_filter_block_sse4_1), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSE4_1, CDEFFindDirTest, - ::testing::Values(make_tuple(&cdef_find_dir_sse4_1, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSE4_1, CDEFFindDirTest, + ::testing::Values(make_tuple(&cdef_find_dir_sse4_1, + &cdef_find_dir_c))); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, CDEFBlockTest, ::testing::Combine(::testing::Values(&cdef_filter_block_avx2), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(AVX2, CDEFFindDirTest, - ::testing::Values(make_tuple(&cdef_find_dir_avx2, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(AVX2, CDEFFindDirTest, + ::testing::Values(make_tuple(&cdef_find_dir_avx2, + &cdef_find_dir_c))); #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, CDEFBlockTest, ::testing::Combine(::testing::Values(&cdef_filter_block_neon), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(NEON, CDEFFindDirTest, - ::testing::Values(make_tuple(&cdef_find_dir_neon, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(NEON, CDEFFindDirTest, + ::testing::Values(make_tuple(&cdef_find_dir_neon, + &cdef_find_dir_c))); #endif // Test speed for all supported architectures #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, CDEFSpeedTest, ::testing::Combine(::testing::Values(&cdef_filter_block_sse2), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSE2, CDEFFindDirSpeedTest, - ::testing::Values(make_tuple(&cdef_find_dir_sse2, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSE2, CDEFFindDirSpeedTest, + ::testing::Values(make_tuple(&cdef_find_dir_sse2, + &cdef_find_dir_c))); #endif #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSSE3, CDEFSpeedTest, ::testing::Combine(::testing::Values(&cdef_filter_block_ssse3), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSSE3, CDEFFindDirSpeedTest, - ::testing::Values(make_tuple(&cdef_find_dir_ssse3, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSSE3, CDEFFindDirSpeedTest, + ::testing::Values(make_tuple(&cdef_find_dir_ssse3, + &cdef_find_dir_c))); #endif #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, CDEFSpeedTest, ::testing::Combine(::testing::Values(&cdef_filter_block_sse4_1), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(SSE4_1, CDEFFindDirSpeedTest, - ::testing::Values(make_tuple(&cdef_find_dir_sse4_1, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(SSE4_1, CDEFFindDirSpeedTest, + ::testing::Values(make_tuple(&cdef_find_dir_sse4_1, + &cdef_find_dir_c))); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, CDEFSpeedTest, ::testing::Combine(::testing::Values(&cdef_filter_block_avx2), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(AVX2, CDEFFindDirSpeedTest, - ::testing::Values(make_tuple(&cdef_find_dir_avx2, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(AVX2, CDEFFindDirSpeedTest, + ::testing::Values(make_tuple(&cdef_find_dir_avx2, + &cdef_find_dir_c))); #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, CDEFSpeedTest, ::testing::Combine(::testing::Values(&cdef_filter_block_neon), ::testing::Values(&cdef_filter_block_c), ::testing::Values(BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8), ::testing::Range(0, 16), ::testing::Range(8, 13, 2))); -INSTANTIATE_TEST_CASE_P(NEON, CDEFFindDirSpeedTest, - ::testing::Values(make_tuple(&cdef_find_dir_neon, - &cdef_find_dir_c))); +INSTANTIATE_TEST_SUITE_P(NEON, CDEFFindDirSpeedTest, + ::testing::Values(make_tuple(&cdef_find_dir_neon, + &cdef_find_dir_c))); #endif #endif // defined(_WIN64) || !defined(_MSC_VER) diff --git a/media/libaom/src/test/cfl_test.cc b/media/libaom/src/test/cfl_test.cc index e4d438d6a..d2973159c 100644 --- a/media/libaom/src/test/cfl_test.cc +++ b/media/libaom/src/test/cfl_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/av1_rtcd.h" @@ -17,37 +19,44 @@ #include "test/util.h" #include "test/acm_random.h" -using ::testing::make_tuple; +using std::make_tuple; using libaom_test::ACMRandom; #define NUM_ITERATIONS (100) #define NUM_ITERATIONS_SPEED (INT16_MAX) -#define ALL_CFL_TX_SIZES(function) \ - make_tuple(TX_4X4, &function), make_tuple(TX_4X8, &function), \ - make_tuple(TX_4X16, &function), make_tuple(TX_8X4, &function), \ - make_tuple(TX_8X8, &function), make_tuple(TX_8X16, &function), \ - make_tuple(TX_8X32, &function), make_tuple(TX_16X4, &function), \ - make_tuple(TX_16X8, &function), make_tuple(TX_16X16, &function), \ - make_tuple(TX_16X32, &function), make_tuple(TX_32X8, &function), \ - make_tuple(TX_32X16, &function), make_tuple(TX_32X32, &function) - -#define ALL_CFL_TX_SIZES_SUBSAMPLE(fun420, fun422, fun444) \ - make_tuple(TX_4X4, &fun420, &fun422, &fun444), \ - make_tuple(TX_4X8, &fun420, &fun422, &fun444), \ - make_tuple(TX_4X16, &fun420, &fun422, &fun444), \ - make_tuple(TX_8X4, &fun420, &fun422, &fun444), \ - make_tuple(TX_8X8, &fun420, &fun422, &fun444), \ - make_tuple(TX_8X16, &fun420, &fun422, &fun444), \ - make_tuple(TX_8X32, &fun420, &fun422, &fun444), \ - make_tuple(TX_16X4, &fun420, &fun422, &fun444), \ - make_tuple(TX_16X8, &fun420, &fun422, &fun444), \ - make_tuple(TX_16X16, &fun420, &fun422, &fun444), \ - make_tuple(TX_16X32, &fun420, &fun422, &fun444), \ - make_tuple(TX_32X8, &fun420, &fun422, &fun444), \ - make_tuple(TX_32X16, &fun420, &fun422, &fun444), \ - make_tuple(TX_32X32, &fun420, &fun422, &fun444) +#define ALL_CFL_TX_SIZES(function) \ + make_tuple(static_cast<TX_SIZE>(TX_4X4), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_4X8), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_4X16), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_8X4), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_8X8), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_8X16), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_8X32), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_16X4), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_16X8), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_16X16), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_16X32), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_32X8), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_32X16), &function), \ + make_tuple(static_cast<TX_SIZE>(TX_32X32), &function) + +#define ALL_CFL_TX_SIZES_SUBSAMPLE(fun420, fun422, fun444) \ + make_tuple(static_cast<TX_SIZE>(TX_4X4), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_4X8), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_4X16), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_8X4), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_8X8), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_8X16), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_8X32), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_16X4), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_16X8), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_16X16), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_16X32), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_32X8), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_32X16), &fun420, &fun422, &fun444), \ + make_tuple(static_cast<TX_SIZE>(TX_32X32), &fun420, &fun422, &fun444) namespace { @@ -84,7 +93,7 @@ class CFLTest { tx_size = tx; width = tx_size_wide[tx_size]; height = tx_size_high[tx_size]; - rnd(ACMRandom::DeterministicSeed()); + rnd.Reset(ACMRandom::DeterministicSeed()); } protected: @@ -159,14 +168,14 @@ class CFLTestWithAlignedData : public CFLTest { }; typedef cfl_subtract_average_fn (*sub_avg_fn)(TX_SIZE tx_size); -typedef ::testing::tuple<TX_SIZE, sub_avg_fn> sub_avg_param; +typedef std::tuple<TX_SIZE, sub_avg_fn> sub_avg_param; class CFLSubAvgTest : public ::testing::TestWithParam<sub_avg_param>, public CFLTestWithData<int16_t> { public: virtual void SetUp() { - CFLTest::init(::testing::get<0>(this->GetParam())); - sub_avg = ::testing::get<1>(this->GetParam())(tx_size); - sub_avg_ref = get_subtract_average_fn_c(tx_size); + CFLTest::init(std::get<0>(this->GetParam())); + sub_avg = std::get<1>(this->GetParam())(tx_size); + sub_avg_ref = cfl_get_subtract_average_fn_c(tx_size); } virtual ~CFLSubAvgTest() {} @@ -209,10 +218,10 @@ class CFLSubsampleTest : public ::testing::TestWithParam<S>, public CFLTestWithData<I> { public: virtual void SetUp() { - CFLTest::init(::testing::get<0>(this->GetParam())); - fun_420 = ::testing::get<1>(this->GetParam())(this->tx_size); - fun_422 = ::testing::get<2>(this->GetParam())(this->tx_size); - fun_444 = ::testing::get<3>(this->GetParam())(this->tx_size); + CFLTest::init(std::get<0>(this->GetParam())); + fun_420 = std::get<1>(this->GetParam())(this->tx_size); + fun_422 = std::get<2>(this->GetParam())(this->tx_size); + fun_444 = std::get<3>(this->GetParam())(this->tx_size); } protected: @@ -262,8 +271,8 @@ class CFLSubsampleTest : public ::testing::TestWithParam<S>, }; typedef cfl_subsample_lbd_fn (*get_subsample_lbd_fn)(TX_SIZE tx_size); -typedef ::testing::tuple<TX_SIZE, get_subsample_lbd_fn, get_subsample_lbd_fn, - get_subsample_lbd_fn> +typedef std::tuple<TX_SIZE, get_subsample_lbd_fn, get_subsample_lbd_fn, + get_subsample_lbd_fn> subsample_lbd_param; class CFLSubsampleLBDTest : public CFLSubsampleTest<subsample_lbd_param, cfl_subsample_lbd_fn, @@ -303,9 +312,10 @@ TEST_P(CFLSubsampleLBDTest, DISABLED_SubsampleLBD444SpeedTest) { subsampleSpeedTest(fun_444, fun_444_ref, &ACMRandom::Rand8); } +#if CONFIG_AV1_HIGHBITDEPTH typedef cfl_subsample_hbd_fn (*get_subsample_hbd_fn)(TX_SIZE tx_size); -typedef ::testing::tuple<TX_SIZE, get_subsample_hbd_fn, get_subsample_hbd_fn, - get_subsample_hbd_fn> +typedef std::tuple<TX_SIZE, get_subsample_hbd_fn, get_subsample_hbd_fn, + get_subsample_hbd_fn> subsample_hbd_param; class CFLSubsampleHBDTest : public CFLSubsampleTest<subsample_hbd_param, cfl_subsample_hbd_fn, @@ -344,16 +354,17 @@ TEST_P(CFLSubsampleHBDTest, SubsampleHBD444Test) { TEST_P(CFLSubsampleHBDTest, DISABLED_SubsampleHBD444SpeedTest) { subsampleSpeedTest(fun_444, fun_444_ref, &ACMRandom::Rand12); } +#endif // CONFIG_AV1_HIGHBITDEPTH typedef cfl_predict_lbd_fn (*get_predict_fn)(TX_SIZE tx_size); -typedef ::testing::tuple<TX_SIZE, get_predict_fn> predict_param; +typedef std::tuple<TX_SIZE, get_predict_fn> predict_param; class CFLPredictTest : public ::testing::TestWithParam<predict_param>, public CFLTestWithAlignedData<uint8_t> { public: virtual void SetUp() { - CFLTest::init(::testing::get<0>(this->GetParam())); - predict = ::testing::get<1>(this->GetParam())(tx_size); - predict_ref = get_predict_lbd_fn_c(tx_size); + CFLTest::init(std::get<0>(this->GetParam())); + predict = std::get<1>(this->GetParam())(tx_size); + predict_ref = cfl_get_predict_lbd_fn_c(tx_size); } virtual ~CFLPredictTest() {} @@ -391,15 +402,16 @@ TEST_P(CFLPredictTest, DISABLED_PredictSpeedTest) { assertFaster(ref_elapsed_time, elapsed_time); } +#if CONFIG_AV1_HIGHBITDEPTH typedef cfl_predict_hbd_fn (*get_predict_fn_hbd)(TX_SIZE tx_size); -typedef ::testing::tuple<TX_SIZE, get_predict_fn_hbd> predict_param_hbd; +typedef std::tuple<TX_SIZE, get_predict_fn_hbd> predict_param_hbd; class CFLPredictHBDTest : public ::testing::TestWithParam<predict_param_hbd>, public CFLTestWithAlignedData<uint16_t> { public: virtual void SetUp() { - CFLTest::init(::testing::get<0>(this->GetParam())); - predict = ::testing::get<1>(this->GetParam())(tx_size); - predict_ref = get_predict_hbd_fn_c(tx_size); + CFLTest::init(std::get<0>(this->GetParam())); + predict = std::get<1>(this->GetParam())(tx_size); + predict_ref = cfl_get_predict_hbd_fn_c(tx_size); } virtual ~CFLPredictHBDTest() {} @@ -438,13 +450,14 @@ TEST_P(CFLPredictHBDTest, DISABLED_PredictHBDSpeedTest) { printSpeed(ref_elapsed_time, elapsed_time, width, height); assertFaster(ref_elapsed_time, elapsed_time); } +#endif // CONFIG_AV1_HIGHBITDEPTH #if HAVE_SSE2 const sub_avg_param sub_avg_sizes_sse2[] = { ALL_CFL_TX_SIZES( - get_subtract_average_fn_sse2) }; + cfl_get_subtract_average_fn_sse2) }; -INSTANTIATE_TEST_CASE_P(SSE2, CFLSubAvgTest, - ::testing::ValuesIn(sub_avg_sizes_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, CFLSubAvgTest, + ::testing::ValuesIn(sub_avg_sizes_sse2)); #endif @@ -455,34 +468,36 @@ const subsample_lbd_param subsample_lbd_sizes_ssse3[] = { cfl_get_luma_subsampling_444_lbd_ssse3) }; +const predict_param predict_sizes_ssse3[] = { ALL_CFL_TX_SIZES( + cfl_get_predict_lbd_fn_ssse3) }; + +INSTANTIATE_TEST_SUITE_P(SSSE3, CFLSubsampleLBDTest, + ::testing::ValuesIn(subsample_lbd_sizes_ssse3)); + +INSTANTIATE_TEST_SUITE_P(SSSE3, CFLPredictTest, + ::testing::ValuesIn(predict_sizes_ssse3)); + +#if CONFIG_AV1_HIGHBITDEPTH const subsample_hbd_param subsample_hbd_sizes_ssse3[] = { ALL_CFL_TX_SIZES_SUBSAMPLE(cfl_get_luma_subsampling_420_hbd_ssse3, cfl_get_luma_subsampling_422_hbd_ssse3, cfl_get_luma_subsampling_444_hbd_ssse3) }; -const predict_param predict_sizes_ssse3[] = { ALL_CFL_TX_SIZES( - get_predict_lbd_fn_ssse3) }; - const predict_param_hbd predict_sizes_hbd_ssse3[] = { ALL_CFL_TX_SIZES( - get_predict_hbd_fn_ssse3) }; + cfl_get_predict_hbd_fn_ssse3) }; -INSTANTIATE_TEST_CASE_P(SSSE3, CFLSubsampleLBDTest, - ::testing::ValuesIn(subsample_lbd_sizes_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, CFLSubsampleHBDTest, + ::testing::ValuesIn(subsample_hbd_sizes_ssse3)); -INSTANTIATE_TEST_CASE_P(SSSE3, CFLSubsampleHBDTest, - ::testing::ValuesIn(subsample_hbd_sizes_ssse3)); - -INSTANTIATE_TEST_CASE_P(SSSE3, CFLPredictTest, - ::testing::ValuesIn(predict_sizes_ssse3)); - -INSTANTIATE_TEST_CASE_P(SSSE3, CFLPredictHBDTest, - ::testing::ValuesIn(predict_sizes_hbd_ssse3)); -#endif +INSTANTIATE_TEST_SUITE_P(SSSE3, CFLPredictHBDTest, + ::testing::ValuesIn(predict_sizes_hbd_ssse3)); +#endif // CONFIG_AV1_HIGHBITDEPTH +#endif // HAVE_SSSE3 #if HAVE_AVX2 const sub_avg_param sub_avg_sizes_avx2[] = { ALL_CFL_TX_SIZES( - get_subtract_average_fn_avx2) }; + cfl_get_subtract_average_fn_avx2) }; const subsample_lbd_param subsample_lbd_sizes_avx2[] = { ALL_CFL_TX_SIZES_SUBSAMPLE(cfl_get_luma_subsampling_420_lbd_avx2, @@ -490,38 +505,42 @@ const subsample_lbd_param subsample_lbd_sizes_avx2[] = { cfl_get_luma_subsampling_444_lbd_avx2) }; +const predict_param predict_sizes_avx2[] = { ALL_CFL_TX_SIZES( + cfl_get_predict_lbd_fn_avx2) }; + +INSTANTIATE_TEST_SUITE_P(AVX2, CFLSubAvgTest, + ::testing::ValuesIn(sub_avg_sizes_avx2)); + +INSTANTIATE_TEST_SUITE_P(AVX2, CFLSubsampleLBDTest, + ::testing::ValuesIn(subsample_lbd_sizes_avx2)); + +INSTANTIATE_TEST_SUITE_P(AVX2, CFLPredictTest, + ::testing::ValuesIn(predict_sizes_avx2)); + +#if CONFIG_AV1_HIGHBITDEPTH const subsample_hbd_param subsample_hbd_sizes_avx2[] = { ALL_CFL_TX_SIZES_SUBSAMPLE(cfl_get_luma_subsampling_420_hbd_avx2, cfl_get_luma_subsampling_422_hbd_avx2, cfl_get_luma_subsampling_444_hbd_avx2) }; -const predict_param predict_sizes_avx2[] = { ALL_CFL_TX_SIZES( - get_predict_lbd_fn_avx2) }; - const predict_param_hbd predict_sizes_hbd_avx2[] = { ALL_CFL_TX_SIZES( - get_predict_hbd_fn_avx2) }; + cfl_get_predict_hbd_fn_avx2) }; -INSTANTIATE_TEST_CASE_P(AVX2, CFLSubAvgTest, - ::testing::ValuesIn(sub_avg_sizes_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, CFLSubsampleHBDTest, + ::testing::ValuesIn(subsample_hbd_sizes_avx2)); -INSTANTIATE_TEST_CASE_P(AVX2, CFLSubsampleLBDTest, - ::testing::ValuesIn(subsample_lbd_sizes_avx2)); - -INSTANTIATE_TEST_CASE_P(AVX2, CFLSubsampleHBDTest, - ::testing::ValuesIn(subsample_hbd_sizes_avx2)); - -INSTANTIATE_TEST_CASE_P(AVX2, CFLPredictTest, - ::testing::ValuesIn(predict_sizes_avx2)); - -INSTANTIATE_TEST_CASE_P(AVX2, CFLPredictHBDTest, - ::testing::ValuesIn(predict_sizes_hbd_avx2)); -#endif +INSTANTIATE_TEST_SUITE_P(AVX2, CFLPredictHBDTest, + ::testing::ValuesIn(predict_sizes_hbd_avx2)); +#endif // CONFIG_AV1_HIGHBITDEPTH +#endif // HAVE_AVX2 #if HAVE_NEON - const sub_avg_param sub_avg_sizes_neon[] = { ALL_CFL_TX_SIZES( - get_subtract_average_fn_neon) }; + cfl_get_subtract_average_fn_neon) }; + +const predict_param predict_sizes_neon[] = { ALL_CFL_TX_SIZES( + cfl_get_predict_lbd_fn_neon) }; const subsample_lbd_param subsample_lbd_sizes_neon[] = { ALL_CFL_TX_SIZES_SUBSAMPLE(cfl_get_luma_subsampling_420_lbd_neon, @@ -529,39 +548,38 @@ const subsample_lbd_param subsample_lbd_sizes_neon[] = { cfl_get_luma_subsampling_444_lbd_neon) }; +INSTANTIATE_TEST_SUITE_P(NEON, CFLSubAvgTest, + ::testing::ValuesIn(sub_avg_sizes_neon)); + +INSTANTIATE_TEST_SUITE_P(NEON, CFLSubsampleLBDTest, + ::testing::ValuesIn(subsample_lbd_sizes_neon)); + +INSTANTIATE_TEST_SUITE_P(NEON, CFLPredictTest, + ::testing::ValuesIn(predict_sizes_neon)); + +#if CONFIG_AV1_HIGHBITDEPTH const subsample_hbd_param subsample_hbd_sizes_neon[] = { ALL_CFL_TX_SIZES_SUBSAMPLE(cfl_get_luma_subsampling_420_hbd_neon, cfl_get_luma_subsampling_422_hbd_neon, cfl_get_luma_subsampling_444_hbd_neon) }; -const predict_param predict_sizes_neon[] = { ALL_CFL_TX_SIZES( - get_predict_lbd_fn_neon) }; - const predict_param_hbd predict_sizes_hbd_neon[] = { ALL_CFL_TX_SIZES( - get_predict_hbd_fn_neon) }; + cfl_get_predict_hbd_fn_neon) }; -INSTANTIATE_TEST_CASE_P(NEON, CFLSubAvgTest, - ::testing::ValuesIn(sub_avg_sizes_neon)); +INSTANTIATE_TEST_SUITE_P(NEON, CFLSubsampleHBDTest, + ::testing::ValuesIn(subsample_hbd_sizes_neon)); -INSTANTIATE_TEST_CASE_P(NEON, CFLSubsampleLBDTest, - ::testing::ValuesIn(subsample_lbd_sizes_neon)); - -INSTANTIATE_TEST_CASE_P(NEON, CFLSubsampleHBDTest, - ::testing::ValuesIn(subsample_hbd_sizes_neon)); - -INSTANTIATE_TEST_CASE_P(NEON, CFLPredictTest, - ::testing::ValuesIn(predict_sizes_neon)); - -INSTANTIATE_TEST_CASE_P(NEON, CFLPredictHBDTest, - ::testing::ValuesIn(predict_sizes_hbd_neon)); -#endif +INSTANTIATE_TEST_SUITE_P(NEON, CFLPredictHBDTest, + ::testing::ValuesIn(predict_sizes_hbd_neon)); +#endif // CONFIG_AV1_HIGHBITDEPTH +#endif // HAVE_NEON #if HAVE_VSX const sub_avg_param sub_avg_sizes_vsx[] = { ALL_CFL_TX_SIZES( - get_subtract_average_fn_vsx) }; + cfl_get_subtract_average_fn_vsx) }; -INSTANTIATE_TEST_CASE_P(VSX, CFLSubAvgTest, - ::testing::ValuesIn(sub_avg_sizes_vsx)); +INSTANTIATE_TEST_SUITE_P(VSX, CFLSubAvgTest, + ::testing::ValuesIn(sub_avg_sizes_vsx)); #endif } // namespace diff --git a/media/libaom/src/test/cnn_test.cc b/media/libaom/src/test/cnn_test.cc new file mode 100644 index 000000000..4410493d3 --- /dev/null +++ b/media/libaom/src/test/cnn_test.cc @@ -0,0 +1,2496 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <assert.h> +#include <math.h> +#include <stdio.h> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/av1_rtcd.h" + +#include "av1/encoder/cnn.h" + +#define SQR(x) ((x) * (x)) + +// Best possible pixelwise guarenteed preicison given each float has at most +// 3 specified decimals. +#define PIXELWISE_FLOAT_TOL 1E-2 + +#define MSE_FLOAT_TOL 1E-6 +#define MSE_INT_TOL 0 + +namespace { + +class CNNTest : public ::testing::Test { + protected: + static void RunCNNTest(int image_width, int image_height, const float *input, + const float *expected, const CNN_CONFIG *cnn_config, + int in_stride, CNN_THREAD_DATA *thread_data, + double tolerance) { + int out_width, out_height, out_channels; + av1_find_cnn_output_size(image_width, image_height, cnn_config, &out_width, + &out_height, &out_channels); + + const int out_size = out_width * out_height; + const int out_stride = out_width; + + float *output_ = + (float *)aom_malloc(sizeof(*output_) * out_size * out_channels); + float *output[CNN_MAX_CHANNELS] = { nullptr }; + for (int channel = 0; channel < out_channels; ++channel) { + output[channel] = output_ + (channel * out_size); + } + const int num_outputs = 1; + const int output_chs[1] = { out_channels }; + const int output_strides[1] = { out_stride }; + CNN_MULTI_OUT output_struct = { num_outputs, output_chs, output_strides, + output }; + + RunMultiOutCNNTest(&input, image_width, image_height, in_stride, cnn_config, + thread_data, &output_struct, &expected, tolerance); + + aom_free(output_); + } + + static void RunMultiOutCNNTest(const float **input, int image_width, + int image_height, int in_stride, + const CNN_CONFIG *cnn_config, + CNN_THREAD_DATA *thread_data, + CNN_MULTI_OUT *output, const float **expected, + double tolerance) { + const int num_outputs = output->num_outputs; + const int *output_chs = output->output_channels; + + int *out_widths = (int *)aom_calloc(num_outputs, sizeof(*out_widths)); + int *out_heights = (int *)aom_calloc(num_outputs, sizeof(*out_heights)); + int *not_used = (int *)aom_calloc(num_outputs, sizeof(*not_used)); + + av1_find_cnn_output_size(image_width, image_height, cnn_config, out_widths, + out_heights, not_used); + av1_cnn_predict(input, image_width, image_height, in_stride, cnn_config, + thread_data, output); + + int channel_offset = 0; + for (int output_idx = 0; output_idx < num_outputs; output_idx++) { + const float *expected_out = expected[output_idx]; + const int curr_output_chs = output_chs[output_idx]; + const int out_size = out_widths[output_idx] * out_heights[output_idx]; + + double mse = 0; + int expected_ite = 0; + for (int channel = 0; channel < curr_output_chs; ++channel) { + const float *buf_out = output->output_buffer[channel_offset]; + + for (int i = 0; i < out_size; ++i) { + EXPECT_NEAR(expected_out[expected_ite], buf_out[i], + PIXELWISE_FLOAT_TOL) + << " output " << output_idx << " channel " << channel << " pixel " + << expected_ite % out_size << ": " << expected_out[expected_ite] + << "/" << buf_out[i] << std::endl; + mse += SQR(expected_out[expected_ite] - buf_out[i]); + expected_ite++; + } + + channel_offset++; + } + mse /= (out_size * curr_output_chs); + EXPECT_LE(mse, tolerance) << " output " << output_idx << std::endl; + } + + aom_free(out_widths); + aom_free(out_heights); + aom_free(not_used); + } + + static void AssignLayerWeightsBiases(CNN_CONFIG *cnn_config, float *weights, + float *bias) { + size_t weight_offset = 0; + size_t bias_offset = 0; + for (int layer = 0; layer < cnn_config->num_layers; ++layer) { + CNN_LAYER_CONFIG *layer_config = &cnn_config->layer_config[layer]; + layer_config->weights = weights + weight_offset; + layer_config->bias = bias + bias_offset; + weight_offset += layer_config->filter_width * + layer_config->filter_height * layer_config->in_channels * + layer_config->out_channels; + bias_offset += layer_config->out_channels; + + ASSERT_NE(layer_config->weights, nullptr); + ASSERT_NE(layer_config->bias, nullptr); + } + } +}; + +} // namespace + +TEST_F(CNNTest, TestMultilayerConvolution) { + int image_height = 16; + int image_width = 16; + int filter_height = 5; + int filter_width = 4; + + float input[] = { + -3, 1, -3, 2, -2, -2, 2, -2, 1, -2, -3, 1, 2, 2, 2, -2, 0, 1, -1, + -3, -1, -1, 1, 0, -3, 1, 0, -1, 1, 0, 0, -3, -3, -3, 0, 2, 1, -1, + 2, 0, 1, -3, -1, 2, 2, 1, -2, 0, -1, 0, -2, -2, -1, 1, 0, 0, 0, + -2, -2, -2, 1, 1, -2, 1, 1, -2, -2, 1, -2, -1, -2, -3, 2, -3, -1, 1, + 0, -2, -2, -2, 1, -2, -2, -1, -1, 2, 2, 2, -1, 1, -3, -3, 0, 2, 0, + 2, 1, -3, -3, 1, 2, 2, 1, -2, -3, 0, -3, 0, -3, -2, 0, 1, 1, 0, + -3, 2, -1, 2, 1, 0, 1, -2, 1, -1, -1, 2, 0, -2, -3, 1, 1, -2, -1, + -3, -3, -1, 0, -3, -2, 0, 0, 1, 0, -3, -2, -1, 1, 0, 2, 1, 0, -3, + -2, -3, -3, -1, 0, -2, 2, -1, -3, 0, -1, -1, 2, 0, -3, -2, -1, 0, 0, + 1, -2, 1, 2, 1, 2, 2, -3, 2, -1, 0, 0, -1, 0, 2, 2, -1, 2, -2, + 1, 1, -3, -3, 1, -1, -1, -2, 2, -2, -2, 2, -1, -3, 2, -3, 1, -1, -1, + -3, 1, -1, 1, 0, -3, -3, 1, -3, -3, 0, 2, 2, -2, -1, 2, 0, 2, 1, + -1, -3, 0, 0, -1, -1, 1, 0, 2, 0, -3, 2, 1, 0, 1, -3, 2, -3, -3, + -1, -3, -3, 2, 0, 2, -2, 1, -1, + }; + + float weights[] = { + -2, 2, -2, 2, -1, -3, 2, 2, 0, 0, -3, -1, -2, -3, 1, -1, 0, 0, 0, + 2, -2, 2, -2, -3, 1, 1, 1, -3, -1, 0, 1, 2, -2, 0, -1, -3, -1, -2, + 2, -3, -3, 1, -2, -3, 0, 2, 1, -3, -3, -1, -3, -2, -1, -3, -1, -3, -2, + -1, -3, -1, -2, -2, -3, 2, 0, -3, 0, -3, -3, 1, -3, -1, 0, -1, 1, 1, + -1, 1, -2, 0, 2, 0, -3, 1, -1, -1, 2, 0, 1, -3, -3, 1, 2, -3, -3, + 1, -3, 2, 0, -3, 1, 2, 2, -2, -1, -2, 1, 1, 0, -2, -2, 1, 2, -1, + -3, 1, -2, 2, -3, -2, -3, 2, 1, 0, -2, 0, 1, -3, 2, -2, -2, 0, 2, + -3, 2, 0, 0, 1, -2, 1, 1, -2, -1, -2, 1, -2, 0, -2, -2, 0, -1, -1, + -3, -3, -3, 1, -3, -2, 2, -1, 2, 0, 2, -2, 2, -2, 1, -3, -3, -1, 0, + 2, 2, 1, -1, -3, -1, -3, 2, 1, -2, 0, -3, -1, -3, -1, 2, 1, 0, 2, + -1, 1, 0, 1, 2, -1, -2, 2, 1, -3, -1, -3, 0, 1, -2, 0, -2, -3, 0, + -2, 2, 2, 0, 0, 2, -3, 2, -3, -2, 1, 2, -3, -3, -1, -3, 0, -3, -3, + -2, -2, -2, 0, 0, 1, 0, 0, -1, 0, 0, -3, 0, -3, -1, -2, 1, -2, -1, + 2, -2, 0, 0, 1, 0, -2, -1, 0, -3, 1, 0, -1, -3, 1, -1, 1, -1, -3, + 1, 0, 1, 1, -1, 2, 2, 0, 0, 1, -3, 2, -2, -2, -3, -2, -1, -2, 2, + 0, 2, -2, -3, -1, -3, 2, 2, -1, 2, 2, -1, 0, -3, 1, + }; + + float bias[] = { + 1, -1, 0, 1, 1, 1, -2, + }; + + float expected_same[] = { + -1125, 2926, 6406, 631, -1244, 97, -1454, 2526, 1065, 3292, 3464, + 2553, -330, 532, 1038, 1182, -402, 3758, 3392, 9854, 4365, 1408, + 4736, 3134, 3838, 2409, 3221, 4350, 6750, 4045, 815, 1188, 2959, + 9802, 9590, 4572, 5740, 4253, 1701, 7974, 7012, 6854, 7093, 3907, + 4539, 3886, 4267, 3505, 465, 7824, 9219, 10026, 7968, 957, 2295, + 5594, 10811, 9641, 5950, 10043, 8783, 3132, 1421, 1110, 4108, 13929, + 10660, -84, -61, 3932, -180, 6811, 13393, 15147, 15640, 9337, 6961, + 3808, 1604, 1398, 1047, 6739, 10144, 6517, 4698, 2678, 7389, 2595, + 5248, 12075, 11272, 13951, 8820, 1090, 2199, 2206, 2788, 12116, 6683, + 2612, -291, 3183, 9414, 12316, 14524, 12333, 13208, 7832, 4664, 4657, + 3534, 1298, -666, 4250, 7707, 9103, 5760, 688, 9571, 15782, 14203, + 14878, 17339, 14684, 8690, 5671, 875, 1429, 1531, 6173, 2984, 5558, + 2996, 7928, 6733, 16117, 15262, 12757, 7980, 3923, 4795, 5973, 2051, + 455, -1922, 1816, 5906, 3321, 10908, 10910, 7377, 12204, 12809, 11195, + 7451, 6666, 74, -1645, -35, -391, 3813, 7324, 892, 1656, 6095, + 12193, 14648, 12156, 14663, 10251, 10325, 7821, 3925, 323, 697, 442, + 1324, 4669, 7002, 5485, 5171, 5086, 10582, 11053, 9709, 11353, 8543, + 5256, 2873, 235, -628, 1496, 1878, -867, 3420, 6865, 5937, 10182, + 13277, 10069, 10789, 5998, 624, -2082, 4417, 1258, -1080, -819, -1430, + 1033, 5220, 6335, 8471, 8980, 11908, 14430, 12584, 8404, 1576, -803, + 985, 1481, 1367, -193, 873, 3684, 2288, 6676, 9477, 11155, 9602, + 9707, 10507, 4739, 3174, -575, -178, 3002, 1710, 423, -477, 554, + 3088, 2029, 5113, 5000, 3771, 6090, 5365, 1185, 2855, 399, -312, + -1577, 176, 955, + }; + + float expected_replicate[] = { + 13768, 13528, 12999, 6906, 4618, 4043, 2611, 9955, 6685, 4776, 2753, + 1036, 3063, 4544, 5183, 7349, 12451, 12501, 9131, 12753, 8908, 4058, + 6299, 7542, 7115, 3307, 3360, 3543, 9754, 7808, 5991, 9019, 14320, + 14919, 12492, 6871, 7373, 3336, 2085, 10604, 9377, 6882, 5009, 3103, + 6220, 6278, 7588, 10196, 11045, 11563, 11842, 11911, 8279, 2030, 1858, + 6368, 12123, 9909, 6347, 10345, 9365, 4038, 1673, 3051, 16492, 16649, + 12276, 408, -301, 4122, -654, 7864, 14038, 15279, 15315, 9744, 8243, + 5298, 746, 380, 9824, 9124, 10895, 6640, 4712, 2669, 6980, 2759, + 5385, 12345, 11336, 13129, 8600, 2370, 3682, 5219, 12407, 13123, 6784, + 2612, -291, 3183, 9414, 12316, 14524, 12333, 13397, 7543, 3916, 4153, + 4477, 4314, 7983, 8418, 9163, 9103, 5760, 688, 9571, 15782, 14203, + 14878, 17718, 14570, 7940, 6642, 5094, 7133, 9964, 10219, 3224, 5558, + 2996, 7928, 6733, 16117, 15262, 12757, 7958, 4401, 5187, 5476, 5529, + 6055, 2206, 3909, 6015, 3321, 10908, 10910, 7377, 12204, 12809, 11195, + 6967, 6840, 481, -1600, 274, 1, 10373, 8514, 1123, 2117, 6758, + 12736, 16223, 13585, 15988, 11771, 10600, 7918, 4156, 2840, 3111, 3287, + 6359, 7652, 8813, 6530, 6967, 7789, 13671, 13990, 13247, 13241, 9836, + 5251, 3024, 2313, 1834, 4187, 2637, -1312, 2139, 7378, 7665, 11933, + 15591, 15314, 15678, 9531, 2820, -1516, 3400, 1314, 22, 363, -2896, + -898, 5906, 7308, 10650, 12975, 16978, 20370, 18817, 12381, 4118, -861, + -137, 236, 1802, 1632, -350, 2334, 3400, 8680, 14064, 18216, 18675, + 21765, 22871, 11491, 4937, -1555, -11, 1669, 2392, 3265, -5254, -217, + 5001, 8063, 13444, 18884, 19706, 22794, 21064, 9545, 6689, -7, 289, + -2021, 504, 2347, + }; + + float expected_valid[] = { + 2612, -291, 3183, 9414, 12316, 14524, 12333, 9103, 5760, 688, + 9571, 15782, 14203, 14878, 5558, 2996, 7928, 6733, 16117, 15262, + 12757, 3321, 10908, 10910, 7377, 12204, 12809, 11195, + }; + + CNN_CONFIG cnn_config = { 3, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + 3, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + 3, + filter_width, + filter_height, + 3, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + 3, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + }, + } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + for (int i = 0; i < cnn_config.num_layers; ++i) { + cnn_config.layer_config[i].pad = PADDING_SAME_REPLICATE; + } + + RunCNNTest(image_width, image_height, input, expected_replicate, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + for (int i = 0; i < cnn_config.num_layers; ++i) { + cnn_config.layer_config[i].pad = PADDING_VALID; + } + + RunCNNTest(image_width, image_height, input, expected_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestRELUSingleLayer) { + int image_width = 8; + int image_height = 8; + int filter_height = 5; + int filter_width = 4; + float input[] = { + 0, -2, -3, 1, -1, 2, -2, 1, -3, -1, 0, 1, -2, -3, -2, -2, + 1, -3, 2, -3, -1, -1, 2, 0, -2, -3, 0, -2, -3, 1, -1, -1, + 2, -2, 0, -2, -3, -3, 1, 1, -1, 1, 0, 1, -3, 0, 2, 2, + 0, -3, 1, -3, 2, -2, 1, -1, -1, -2, -3, -2, -1, -3, -2, -1, + }; + float expected_same[] = { + 9, 0, 1, 1, 0, 3, 0, 19, 0, 12, 10, 0, 0, 0, 5, 0, + 0, 18, 21, 7, 19, 4, 3, 0, 0, 9, 16, 0, 11, 16, 0, 11, + 12, 2, 0, 11, 0, 16, 6, 0, 8, 22, 13, 10, 12, 0, 0, 0, + 0, 1, 2, 12, 29, 6, 10, 0, 13, 0, 0, 5, 8, 10, 0, 0, + }; + float expected_replicate[] = { + 18, 17, 12, 2, 0, 0, 5, 11, 0, 17, 22, 6, 0, 0, 17, 0, + 0, 18, 21, 7, 19, 4, 3, 5, 3, 9, 16, 0, 11, 16, 0, 3, + 3, 2, 0, 11, 0, 16, 6, 0, 17, 22, 13, 10, 12, 0, 0, 0, + 0, 4, 1, 10, 30, 7, 10, 0, 23, 8, 0, 13, 15, 19, 8, 10, + }; + float expected_valid[] = { + 18, 21, 7, 19, 4, 9, 16, 0, 11, 16, 2, 0, 11, 0, 16, 22, 13, 10, 12, 0, + }; + float weights[] = { + -2, -3, 1, 2, 2, -2, -3, 0, -3, 2, 2, -3, -3, -2, 0, 1, 2, 0, -1, -1, + }; + float bias[] = { -3 }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { { + 1, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + RELU, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].pad = PADDING_SAME_REPLICATE; + + RunCNNTest(image_width, image_height, input, expected_replicate, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].pad = PADDING_VALID; + + RunCNNTest(image_width, image_height, input, expected_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestVaryingStridesVaryingDimImages) { + float weights[] = { + 1, -5, -3, -4, -1, 1, 2, -3, 2, 2, -1, 1, -5, 1, 1, + -3, -5, 3, 1, 4, -2, -5, -2, -3, -5, 0, -1, -5, 2, -2, + -2, 1, -2, -4, 1, 3, -2, 2, 0, -3, 2, -3, -2, -3, + }; + float bias[] = { 2 }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { + { + 1, + 4, + 11, + 1, + 7, + 6, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + }, + } }; + + int image_height = 24; + int image_width = 17; + float input[] = { + -1, -3, 4, 4, -5, 4, 3, -5, -1, -3, 4, -4, 2, -3, 3, -5, 2, -1, -5, + 1, -1, 3, 1, -3, -3, 4, 0, 2, -3, -5, -5, -4, 0, -5, -2, -3, -1, -2, + 2, -5, 4, 4, 0, -4, -3, 1, -3, -5, -4, -4, 1, -2, -3, 3, -3, -3, -1, + -5, -5, -2, 3, 1, -1, -5, -5, 1, -4, -2, -1, -2, -4, -4, 2, -2, 2, 1, + -2, -4, -1, 1, -2, -5, 3, -2, -1, -1, -5, -3, 1, -2, -2, -3, -1, -2, -4, + -2, 1, -4, -1, 4, 3, -4, 0, 4, 2, 2, 4, -3, -5, 2, 2, 1, -1, -4, + -2, 1, 3, 2, 0, 4, -1, -3, 2, 1, -4, 2, 2, -4, -2, 0, -2, -1, 4, + 4, 2, 3, -4, 2, -4, -5, 4, -1, -3, -1, 0, -4, 1, 3, -1, -3, -5, 3, + -2, -4, 1, 2, -2, -3, -3, -5, 1, -3, -1, 0, -1, 3, -4, -1, -5, -5, 1, + 0, 0, -2, -2, 2, -2, 0, 0, 2, 0, -3, 0, -1, -4, -4, -1, 3, -4, -4, + -1, 0, -5, -3, -2, 4, -3, -4, -4, 0, -5, 1, -2, -3, -3, -4, 4, 3, 4, + 3, 3, -1, 3, 1, -3, -2, 3, 3, 0, 2, -4, -3, 2, 2, 0, -2, 4, -2, + 2, -2, -1, -4, -2, 2, -4, 3, -1, 4, 1, 1, 4, -1, -4, -4, 1, 1, -2, + 4, -1, 3, 2, -3, 4, 3, 1, 4, 0, -4, 2, 0, 2, 4, -2, -2, 4, 2, + -1, -2, 1, -3, 2, 3, -5, -3, 4, 4, 2, -5, -4, -5, -2, -4, 2, 0, 2, + -5, 4, -4, -2, -5, 2, 1, 0, 4, 1, -2, -3, -4, -3, -4, 3, 3, 2, 0, + -3, 1, -5, 4, 0, 4, -1, 3, -5, -5, -2, -1, -1, 4, 3, 3, 4, 3, -4, + 4, -3, -3, -1, -4, -1, -4, -1, -2, 4, -2, -4, 4, 4, -3, -4, -1, 1, 2, + -1, -2, -2, 3, 2, 2, -3, 0, -1, 0, 3, 2, -5, 0, -4, 0, 0, 2, -4, + -1, -1, 0, -2, 0, 1, 0, 0, 4, -5, -1, -5, 2, -1, 0, 2, -1, 1, 3, + -3, -5, -2, -3, 4, -2, -2, -1, -3, -4, -1, -2, -4, 1, 4, -3, -2, -1, 3, + -3, -2, 3, 2, 1, -4, -3, -5, 1, + }; + float expected_1[] = { + 41, -26, 5, 76, 13, 83, -21, 53, -54, -14, 21, 121, + }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected_1, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].skip_width = 6; + cnn_config.layer_config[0].skip_height = 7; + + float expected_2[] = { + 21, -50, 41, 20, 72, 127, -21, 103, 62, -37, 83, -3, + }; + RunCNNTest(image_width, image_height, input, expected_2, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].skip_width = 3; + cnn_config.layer_config[0].skip_height = 10; + + float expected_3[] = { + -26, -21, -35, 69, 49, 4, -51, -43, -56, + -41, 15, -44, 40, -62, 63, 38, 27, 47, + }; + RunCNNTest(image_width, image_height, input, expected_3, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].skip_width = 10; + cnn_config.layer_config[0].skip_height = 3; + + float expected_4[] = { + 21, 49, 28, 87, 50, 40, 102, 81, 58, 85, 51, 66, 36, 19, -37, -45, + }; + + RunCNNTest(image_width, image_height, input, expected_4, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestMaxPool) { + int image_width = 8; + int image_height = 8; + int stride = 3; + float input[] = { + 1, -4, -4, 8, 0, 7, -5, -2, 8, 2, 2, 8, 5, -1, -1, 9, + -3, 0, -2, 0, 6, 3, -4, 8, 7, 8, 7, -1, 4, -1, 0, 2, + -5, -2, 8, 5, 5, 4, 2, 7, 4, 6, 2, 8, 8, -4, -3, -4, + -3, -1, 2, 3, 3, 6, -5, 8, 9, 5, 0, -2, -1, 6, 5, 7, + }; + + float expected[] = { + 49, 58, 70, 68, 68, 70, 48, 57, 88, + }; + + float weights[] = { + 3, 1, 3, 4, -1, 5, -2, 1, -4, + }; + + float bias[] = { + -3, + }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { { + 1, + 3, + 3, + 1, + stride, + stride, + 1, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestDeconvolveNonActivationSingleLayerSingleKernel) { + int image_width = 4; + int image_height = 7; + float input[] = { + 9, 6, 181, 9, 218, 30, 80, 108, 68, 216, 70, 128, 179, 228, + 33, 212, 34, 14, 48, 27, 230, 23, 202, 113, 80, 56, 122, 112, + }; + + float expected_1_same[] = { + 15, -30, 36, -525, 377, -193, 558, 531, 6, -24, -15, 124, + 166, -561, -356, -754, -3, -3, -3, -3, -3, -3, -3, -3, + 433, -311, 711, 381, 247, -317, 453, 129, 215, -627, -409, -885, + 17, -255, -55, -647, -3, -3, -3, -3, -3, -3, -3, -3, + 133, -719, 633, -225, 785, 191, 463, 79, 65, 9, 77, -853, + -365, -949, -15, -667, -3, -3, -3, -3, -3, -3, -3, -3, + 355, -866, 990, 207, 747, 12, 520, -116, 176, -312, -133, -1370, + -426, -802, 143, -771, -3, -3, -3, -3, -3, -3, -3, -3, + 65, -79, 127, -59, 135, -90, 195, 114, 31, -91, -57, -133, + 17, -176, -72, -276, -3, -3, -3, -3, -3, -3, -3, -3, + 457, -302, 733, 58, 470, -475, 829, 490, 227, -670, -440, -790, + 153, -588, -294, -1150, -3, -3, -3, -3, -3, -3, -3, -3, + 157, -251, 349, -185, 409, -293, 587, 251, 77, -187, -107, -369, + 7, -481, -135, -827, -3, -3, -3, -3, -3, -3, -3, -3, + }; + float expected_1_valid[] = { + -30, 15, -30, 36, -525, 377, -193, 558, 531, 24, 24, 6, + 6, -24, -15, 124, 166, -561, -356, -754, -21, -39, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -657, 433, -311, + 711, 381, 247, -317, 453, 129, 321, 321, 215, 215, -627, -409, + -885, 17, -255, -55, -647, -219, -435, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -207, 133, -719, 633, -225, 785, + 191, 463, 79, 381, 381, 65, 65, 9, 77, -853, -365, -949, + -15, -667, -259, -515, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -540, 355, -866, 990, 207, 747, 12, 520, -116, + 633, 633, 176, 176, -312, -133, -1370, -426, -802, 143, -771, -427, + -851, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -105, 65, -79, 127, -59, 135, -90, 195, 114, 78, 78, 31, + 31, -91, -57, -133, 17, -176, -72, -276, -57, -111, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -693, 457, -302, + 733, 58, 470, -475, 829, 490, 336, 336, 227, 227, -670, -440, + -790, 153, -588, -294, -1150, -229, -455, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -243, 157, -251, 349, -185, 409, + -293, 587, 251, 333, 333, 77, 77, -187, -107, -369, 7, -481, + -135, -827, -227, -451, + }; + float weights_1[] = { -3, 2, -1, 3, 3, 1, 1, -3, -2, -4 }; + float bias_1[] = { -3 }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { { + 1, + 5, + 2, + 1, + 2, + 3, + 0, + weights_1, + bias_1, + PADDING_SAME_ZERO, + NONE, + 1, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected_1_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + // Change padding to valid + cnn_config.layer_config[0].pad = PADDING_VALID; + + RunCNNTest(image_width, image_height, input, expected_1_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + float expected_12_same[] = { + 15, -12, 6, 36, -9, -528, 377, -184, 513, 558, -12, 24, + 6, -30, -15, -33, -21, 166, 154, -546, -356, -718, -30, -21, + 433, -221, 561, 711, -33, -153, 247, -83, -87, 453, -111, 321, + 215, -657, -409, -845, -93, 17, -43, -243, -55, -215, -327, -219, + 133, -71, -447, 633, -219, 435, 785, -73, -177, 463, -131, 381, + 65, -207, 77, -59, -651, -365, -797, -213, -15, -155, -387, -259, + 355, -182, -150, 990, -231, 582, 747, -36, -540, 520, -215, 633, + 176, -540, -133, -491, -687, -426, -882, -102, 143, 77, -639, -427, + 65, -37, 57, 127, -17, -105, 135, -51, 60, 195, -30, 78, + 31, -105, -57, -125, -45, 17, -11, -147, -72, -168, -84, -57, + 457, -233, 618, 733, -26, -540, 470, -205, 264, 829, -116, 336, + 227, -693, -440, -900, -72, 153, 107, -609, -294, -698, -342, -229, + 157, -83, 69, 349, -59, -201, 409, -125, 27, 587, -115, 333, + 77, -243, -107, -267, -171, 7, -105, -369, -135, -379, -339, -227, + }; + float expected_12_valid[] = { + -30, 15, -12, 6, 36, -9, -528, 377, -184, 513, 558, -12, + 24, 24, 6, 6, -30, -15, -33, -21, 166, 154, -546, -356, + -718, -30, -21, -39, -657, 433, -221, 561, 711, -33, -153, 247, + -83, -87, 453, -111, 321, 321, 215, 215, -657, -409, -845, -93, + 17, -43, -243, -55, -215, -327, -219, -435, -207, 133, -71, -447, + 633, -219, 435, 785, -73, -177, 463, -131, 381, 381, 65, 65, + -207, 77, -59, -651, -365, -797, -213, -15, -155, -387, -259, -515, + -540, 355, -182, -150, 990, -231, 582, 747, -36, -540, 520, -215, + 633, 633, 176, 176, -540, -133, -491, -687, -426, -882, -102, 143, + 77, -639, -427, -851, -105, 65, -37, 57, 127, -17, -105, 135, + -51, 60, 195, -30, 78, 78, 31, 31, -105, -57, -125, -45, + 17, -11, -147, -72, -168, -84, -57, -111, -693, 457, -233, 618, + 733, -26, -540, 470, -205, 264, 829, -116, 336, 336, 227, 227, + -693, -440, -900, -72, 153, 107, -609, -294, -698, -342, -229, -455, + -243, 157, -83, 69, 349, -59, -201, 409, -125, 27, 587, -115, + 333, 333, 77, 77, -243, -107, -267, -171, 7, -105, -369, -135, + -379, -339, -227, -451, + }; + + // Change skip_width, skip_height to {2, 3} + cnn_config.layer_config[0].skip_width = 3; + cnn_config.layer_config[0].skip_height = 2; + // Set padding to same + cnn_config.layer_config[0].pad = PADDING_SAME_ZERO; + + RunCNNTest(image_width, image_height, input, expected_12_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + // Change padding to valid + cnn_config.layer_config[0].pad = PADDING_VALID; + RunCNNTest(image_width, image_height, input, expected_12_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].filter_width = 4; + cnn_config.layer_config[0].filter_height = 3; + float weights_2[] = { -1, -3, -1, -3, 0, 2, -2, 4, 3, 0, 1, 4 }; + float bias_2[] = { -4 }; + cnn_config.layer_config[0].weights = weights_2; + cnn_config.layer_config[0].bias = bias_2; + + cnn_config.layer_config[0].skip_width = 5; + cnn_config.layer_config[0].skip_height = 2; + float expected_2_same[] = { + -13, -31, -13, -31, -4, -10, -22, -10, -22, -4, -185, -547, + -185, -547, -4, -13, -31, -13, -31, -4, -4, 14, -22, 32, + -4, -4, 8, -16, 20, -4, -4, 358, -366, 720, -4, -4, + 14, -22, 32, -4, -195, -658, -213, -622, -4, -16, -94, -28, + -70, -4, 459, -244, 97, 480, -4, -85, -328, -103, -292, -4, + -4, 432, -440, 868, -4, -4, 56, -64, 116, -4, -4, 156, + -164, 316, -4, -4, 212, -220, 428, -4, 582, -208, 146, 664, + -4, -130, -652, -190, -532, -4, 166, -214, 6, 106, -4, 192, + -388, -24, 44, -4, -4, 132, -140, 268, -4, -4, 428, -436, + 860, -4, -4, 136, -144, 276, -4, -4, 252, -260, 508, -4, + 21, -541, -115, -269, -4, 416, -688, -16, 176, -4, 173, -103, + 33, 177, -4, 168, -640, -88, -128, -4, -4, 354, -362, 712, + -4, -4, 452, -460, 908, -4, -4, 62, -70, 128, -4, -4, + 420, -428, 844, -4, 499, -106, 141, 610, -4, 666, -46, 210, + 866, -4, 47, -148, -19, -16, -4, 605, -85, 181, 763, -4, + -4, 64, -72, 132, -4, -4, 24, -32, 52, -4, -4, 92, + -100, 188, -4, -4, 50, -58, 104, -4, -132, -694, -200, -558, + -4, 15, -73, -13, -17, -4, -62, -610, -158, -418, -4, -36, + -343, -90, -235, -4, -4, 456, -464, 916, -4, -4, 42, -50, + 88, -4, -4, 400, -408, 804, -4, -4, 222, -230, 448, -4, + 606, -244, 146, 676, -4, 9, -172, -37, -80, -4, 480, -370, + 76, 438, -4, 223, -340, -3, 112, -4, -4, 156, -164, 316, + -4, -4, 108, -116, 220, -4, -4, 240, -248, 484, -4, -4, + 220, -228, 444, -4, + }; + float expected_2_valid[] = { + -13, -31, -13, -31, -4, -10, -22, -10, -22, -4, -185, -547, + -185, -547, -4, -13, -31, -13, -31, -4, 14, -22, 32, -4, + -4, 8, -16, 20, -4, -4, 358, -366, 720, -4, -4, 14, + -22, 32, -195, -658, -213, -622, -4, -16, -94, -28, -70, -4, + 459, -244, 97, 480, -4, -85, -328, -103, -292, -4, 432, -440, + 868, -4, -4, 56, -64, 116, -4, -4, 156, -164, 316, -4, + -4, 212, -220, 428, 582, -208, 146, 664, -4, -130, -652, -190, + -532, -4, 166, -214, 6, 106, -4, 192, -388, -24, 44, -4, + 132, -140, 268, -4, -4, 428, -436, 860, -4, -4, 136, -144, + 276, -4, -4, 252, -260, 508, 21, -541, -115, -269, -4, 416, + -688, -16, 176, -4, 173, -103, 33, 177, -4, 168, -640, -88, + -128, -4, 354, -362, 712, -4, -4, 452, -460, 908, -4, -4, + 62, -70, 128, -4, -4, 420, -428, 844, 499, -106, 141, 610, + -4, 666, -46, 210, 866, -4, 47, -148, -19, -16, -4, 605, + -85, 181, 763, -4, 64, -72, 132, -4, -4, 24, -32, 52, + -4, -4, 92, -100, 188, -4, -4, 50, -58, 104, -132, -694, + -200, -558, -4, 15, -73, -13, -17, -4, -62, -610, -158, -418, + -4, -36, -343, -90, -235, -4, 456, -464, 916, -4, -4, 42, + -50, 88, -4, -4, 400, -408, 804, -4, -4, 222, -230, 448, + 606, -244, 146, 676, -4, 9, -172, -37, -80, -4, 480, -370, + 76, 438, -4, 223, -340, -3, 112, -4, 156, -164, 316, -4, + -4, 108, -116, 220, -4, -4, 240, -248, 484, -4, -4, 220, + -228, 444, 236, -4, 76, 316, -4, 164, -4, 52, 220, -4, + 362, -4, 118, 484, -4, 332, -4, 108, 444, + }; + // Set padding to same + cnn_config.layer_config[0].pad = PADDING_SAME_ZERO; + + RunCNNTest(image_width, image_height, input, expected_2_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].pad = PADDING_VALID; + + RunCNNTest(image_width, image_height, input, expected_2_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].skip_width = 2; + cnn_config.layer_config[0].skip_height = 5; + float expected_21_same[] = { + -31, -19, -49, -191, -565, -194, -574, -13, 14, -22, 44, -16, + 382, -366, 738, -22, -4, 23, 32, 545, 20, 204, 720, 5, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -658, -252, -748, -114, -334, -192, -568, -112, + 432, -440, 928, -64, 276, -164, 532, -220, -4, 304, 868, 266, + 116, 400, 316, 104, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -208, -288, -856, -290, + -862, -202, -598, -132, 132, -140, 700, -436, 1000, -144, 532, -260, + -4, 712, 268, 422, 860, 450, 276, 124, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -541, -411, -1225, -265, -787, -249, -739, -216, 354, -362, 1168, -460, + 974, -70, 552, -428, -4, 859, 712, 323, 908, 665, 128, 208, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -106, -52, -148, -66, -190, -79, -229, -31, + 64, -72, 160, -32, 148, -100, 242, -58, -4, 72, 132, 154, + 52, 125, 188, 23, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -694, -257, -763, -229, + -679, -319, -949, -117, 456, -464, 962, -50, 492, -408, 1030, -230, + -4, 295, 916, 625, 88, 537, 804, 109, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -244, -140, -412, -182, -538, -238, -706, -116, 156, -164, 428, -116, + 464, -248, 708, -228, -4, 244, 316, 418, 220, 454, 484, 108, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, + }; + float expected_21_valid[] = { + -13, -31, -19, -49, -191, -565, -194, -574, -13, -31, -4, 14, + -22, 44, -16, 382, -366, 738, -22, 32, 23, -4, 23, 32, + 545, 20, 204, 720, 5, 32, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -222, -658, -252, -748, -114, -334, -192, -568, -112, -328, + -4, 432, -440, 928, -64, 276, -164, 532, -220, 428, 650, -4, + 304, 868, 266, 116, 400, 316, 104, 428, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -72, -208, -288, -856, -290, -862, -202, -598, + -132, -388, -4, 132, -140, 700, -436, 1000, -144, 532, -260, 508, + 200, -4, 712, 268, 422, 860, 450, 276, 124, 508, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -183, -541, -411, -1225, -265, -787, + -249, -739, -216, -640, -4, 354, -362, 1168, -460, 974, -70, 552, + -428, 844, 533, -4, 859, 712, 323, 908, 665, 128, 208, 844, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -38, -106, -52, -148, + -66, -190, -79, -229, -31, -85, -4, 64, -72, 160, -32, 148, + -100, 242, -58, 104, 98, -4, 72, 132, 154, 52, 125, 188, + 23, 104, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -234, -694, + -257, -763, -229, -679, -319, -949, -117, -343, -4, 456, -464, 962, + -50, 492, -408, 1030, -230, 448, 686, -4, 295, 916, 625, 88, + 537, 804, 109, 448, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -84, -244, -140, -412, -182, -538, -238, -706, -116, -340, -4, 156, + -164, 428, -116, 464, -248, 708, -228, 444, 236, -4, 244, 316, + 418, 220, 454, 484, 108, 444, + }; + + cnn_config.layer_config[0].pad = PADDING_SAME_ZERO; + + RunCNNTest(image_width, image_height, input, expected_21_same, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); + + cnn_config.layer_config[0].pad = PADDING_VALID; + + RunCNNTest(image_width, image_height, input, expected_21_valid, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestLargeKernelsAndStrides) { + float input_10x11[] = { + 4, 4, 2, 4, 2, -5, -2, 3, -1, 0, 0, 1, 2, 0, -5, -2, -5, 1, -3, + -1, 4, -3, 2, -2, 1, 0, 1, -3, -3, -4, -2, -2, 1, -4, -1, 4, 1, -4, + -4, -4, 3, 2, -5, 3, -5, 1, 2, -4, 1, -1, 3, 4, -2, 3, -3, 3, 0, + 2, -4, -5, -5, -2, -1, -2, 1, 1, 1, -2, 4, -5, 4, -1, -1, 2, 3, -4, + 2, 2, 3, 0, 0, 1, 0, 3, 2, 3, 1, -2, 3, -4, 3, 2, 4, -2, 0, + 4, -4, 1, -3, -3, -3, -5, 1, -3, -5, 0, 4, -1, -3, 2, + }; + + float weights_10x11[] = { + -3, 4, -4, -3, -5, 1, -2, 3, 1, -4, -4, 0, -1, 0, 3, 1, -3, -2, 0, + -1, 1, 3, -4, -4, -3, -3, -2, 4, 3, -5, 4, 2, -3, 4, -2, -1, 2, -1, + -5, 0, -3, 0, 3, -5, -5, 3, -4, -1, -5, 3, 4, 0, 4, -5, 2, -1, 2, + -1, -1, -1, -5, 0, -4, 3, -1, 1, 1, -1, 3, 2, -5, -4, 0, -4, 4, -5, + -3, 4, -5, 2, -5, -4, -4, -1, 3, 3, 0, 2, -4, 1, -2, 1, 1, 0, 3, + -2, 0, 1, 2, 4, -3, -1, -5, -5, 2, -4, 1, 1, 2, -4, -2, -2, 2, 1, + 3, 4, -5, 1, -1, -3, -3, -1, -2, -5, 1, -1, 0, 1, 4, 4, 0, 0, 4, + -3, -1, -5, -3, 0, 1, 1, 1, -5, 3, 4, 3, -5, 3, -2, -2, 0, -4, 0, + 0, -2, 1, -4, -1, 0, -5, -2, -2, -5, -3, -3, 1, 1, -3, 2, 4, 2, 4, + -4, -3, 3, 1, 1, 3, -4, 4, -2, -3, -3, -3, -3, -4, -2, 3, -5, 2, 4, + -1, -4, -4, 4, -2, -1, 3, -3, -4, -4, -2, 4, 1, 0, 2, -1, 4, -3, 1, + 4, -3, 4, 4, 0, -4, 3, -2, -3, 2, 3, -1, -3, 2, 1, 4, -2, -3, 1, + 4, -2, 2, -2, -5, -2, 1, 4, -1, -4, 4, -5, 2, -5, -4, -1, -2, 3, 1, + 2, 1, -5, 1, -5, -4, -1, -2, 2, -2, -4, -3, -2, -2, 4, -1, 2, 2, -4, + 2, -2, 4, -4, -2, -2, 1, -1, 1, 1, 1, -4, -5, -2, 3, -4, -1, 3, -2, + 3, 2, -5, -4, 0, 3, -2, -4, -5, 3, -2, -4, 2, -2, 1, -4, 0, 2, -5, + 1, -4, -1, -1, 4, -5, -4, 0, -5, -4, -3, -5, -4, 0, 2, 0, -4, 2, -2, + 1, 1, -3, 2, 0, -4, 0, -4, 1, 0, -5, -1, -1, -1, -5, 4, 2, 2, -4, + 3, -2, -2, 2, -3, -2, -1, 2, -4, -5, 2, -2, -4, -5, -5, -1, 2, -1, 0, + -5, -2, -2, -5, 0, 1, -1, -5, 0, 3, 2, 3, 0, -3, -2, 0, -5, -1, -2, + 2, -4, -1, 2, 2, -5, 2, -4, 0, 3, -3, 1, 0, 0, 1, -5, -3, 1, -1, + 0, -4, -3, 2, -4, -4, 4, -1, 0, 1, 2, -4, -5, 4, -2, 1, -4, -4, -3, + -1, -1, 1, -1, -4, -1, -4, -3, 2, -1, -2, -4, 1, 1, 0, -2, 0, -4, 3, + -3, 0, -4, -1, -4, 2, -1, -2, -5, -1, -2, -3, 3, -1, 0, -3, 0, 1, -5, + 1, -5, 0, 1, + }; + + float bias_10x11[] = { 3 }; + + float expected_10x11[] = { + 118, + }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { { + 1, + 23, + 20, + 1, + 15, + 20, + 0, + weights_10x11, + bias_10x11, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + int image_height = 10; + int image_width = 11; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input_10x11, expected_10x11, + &cnn_config, image_width, &thread_data, MSE_INT_TOL); + + float input_11x10[] = { + -2, -2, 3, -5, -1, -3, 1, 3, 2, 1, 1, -5, 4, 1, 3, -5, 3, -3, -5, + 0, -1, -3, -3, 1, 1, -5, -1, -5, -5, -3, 0, 1, -3, -1, -3, -3, 0, 3, + 4, -4, -1, 3, -3, -1, -3, 1, -3, -2, -1, -4, -3, 2, -4, 1, -4, -1, -3, + -5, -1, 2, 3, 0, 2, 2, -5, 4, 1, 2, -1, -4, 4, -4, -4, 0, -1, 1, + -1, 1, -3, -3, -2, 1, 2, 4, 4, 4, -3, -3, 0, 1, 0, 1, 4, 1, 3, + 4, -3, -2, -4, 4, 2, 0, 3, 4, -1, 2, -2, 1, -3, -2, + }; + + float weights_11x10[] = { + 4, -1, 1, -1, 2, 4, 3, 3, -4, 3, -5, 1, -1, -1, -2, -2, 0, 2, -3, + -2, 3, -5, -1, 0, -1, -2, -2, -1, 2, 4, 3, 1, 0, 0, -3, 3, -4, -1, + -5, 4, -2, -2, 1, 2, -1, -3, 1, 2, -5, 1, -3, 3, 3, 0, -4, -4, -5, + -3, -4, -4, 4, -2, 4, 4, -2, 2, -5, -1, -2, -5, -1, 4, -3, 3, -2, 0, + -4, -3, 0, -1, -2, 4, 2, 0, -2, -5, -4, 1, 4, -4, -2, 2, -2, 1, 1, + -4, 1, -4, -4, -2, 4, 2, -1, -5, -5, 1, -3, -3, 3, -3, -5, -3, 4, -1, + -1, -3, 0, -4, 3, -1, 0, -2, 0, -5, -2, -5, 2, 0, -5, 2, 3, -2, 2, + 4, -1, 1, -3, 2, 3, 2, 0, -5, -4, -5, 2, 1, 1, -1, -2, 3, 4, 2, + -2, 4, -2, 3, 1, -4, -3, -1, 4, 4, -3, -5, -2, 2, 0, 3, -2, 3, -1, + -4, 0, -2, 0, 3, 4, -2, -3, -2, 0, 3, 4, 2, -4, 0, 1, 2, 2, -1, + -1, 4, 1, 4, -2, -1, -1, -5, 1, -3, 3, 3, -1, -4, 3, -5, 0, 0, -1, + -4, -1, -2, 4, -2, 3, 3, -3, 1, -1, 2, -1, 4, 4, -2, -2, 4, -2, 0, + 3, -3, -5, -1, -2, 4, -4, 2, -4, 0, -2, 3, -3, 2, 2, -2, -5, -1, 4, + 3, -2, -1, 3, 3, -1, 3, 0, -3, 0, 4, 2, 0, -1, 4, 1, 1, 2, 1, + 3, 1, 1, 1, -3, -5, -4, 4, -4, 2, 0, 0, -4, 1, 4, -5, 4, 4, 0, + 1, 0, -2, -4, -4, -3, 0, 1, -5, 4, 0, -3, -2, -4, 2, 4, 1, -5, 1, + -4, 1, 0, -3, -3, 0, 2, -5, 4, 3, -2, -5, 3, 1, -1, 0, 3, -2, -2, + 3, -2, -5, 4, 1, -2, 2, -1, 0, 4, 0, -5, 3, -2, 1, 2, 1, -5, -3, + -2, -5, 4, -4, 0, 3, 2, -1, -4, -1, 2, 1, -2, 3, -1, -4, 2, 0, -3, + 1, -1, 2, -5, -4, -1, -5, 1, 4, 3, 4, 2, -3, 1, -5, -1, 3, 0, -1, + -4, 3, 4, -5, 4, 4, -3, 2, -3, -1, -3, -5, -3, 2, -3, -2, 1, 1, 0, + -5, 3, 2, 1, -5, 1, 1, 1, 3, 4, -4, -1, -2, 0, -5, -3, -5, -2, -4, + 3, 3, 3, 4, 0, -4, -1, -5, 0, -3, 1, 4, 4, -4, 4, -5, -5, -1, -2, + -5, 3, -4, 4, 3, 0, -3, 2, -2, 0, 0, 4, 4, 0, -2, 1, -1, -3, 2, + -1, 1, -3, -5, + }; + + float bias_11x10[] = { + -5, + }; + + float expected_11x10[] = { + 36, -84, 95, 45, 18, 46, 77, -54, -99, -149, 66, 49, 161, 11, + 39, 61, -66, 61, 4, -3, 34, -44, -23, 31, 64, 29, 47, 72, + -27, -27, 121, -3, 100, 1, 30, -78, -12, -89, -59, 8, -16, 112, + 91, -102, -26, -4, 30, 54, 4, -84, -24, -58, 27, -53, -33, 5, + 53, -26, 63, 50, -103, -130, -23, 6, -104, -207, 73, 23, 77, 132, + 38, 32, -130, -44, -60, 7, 27, 176, 45, -32, -2, 99, -97, 63, + 69, 126, 47, 63, 136, -57, 5, 16, -40, -157, 8, 38, -44, -10, + 91, 7, 122, 140, 30, -105, 4, -1, 113, 64, 180, 141, + }; + + cnn_config.layer_config[0].weights = weights_11x10; + cnn_config.layer_config[0].bias = bias_11x10; + cnn_config.layer_config[0].filter_width = 20; + cnn_config.layer_config[0].filter_height = 23; + cnn_config.layer_config[0].skip_width = 1; + cnn_config.layer_config[0].skip_height = 1; + image_height = 11; + image_width = 10; + + RunCNNTest(image_width, image_height, input_11x10, expected_11x10, + &cnn_config, image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestSoftsignSingleLayer) { + int image_width = 8; + int image_height = 8; + int filter_height = 5; + int filter_width = 4; + float input[] = { + -0.5220f, 0.8410f, -0.8990f, -0.0090f, 0.6710f, -0.9470f, -0.8240f, + -0.0870f, 0.5380f, 0.4750f, 0.570f, -0.3760f, -0.6960f, -0.5940f, + -0.3830f, 0.080f, -0.0980f, -0.4940f, -0.4030f, 0.9460f, -0.6020f, + 0.4220f, 0.6190f, 0.6640f, -0.9210f, -0.1470f, -0.2480f, -0.1120f, + -0.580f, -0.0650f, 0.3330f, 0.9860f, -0.7430f, 0.7610f, 0.4840f, + 0.1030f, 0.9570f, 0.6120f, -0.5240f, -0.1220f, -0.5850f, -0.270f, + 0.7840f, -0.9790f, 0.7290f, -0.30f, -0.6460f, 0.0780f, 0.4750f, + -0.0510f, 0.4550f, 0.3850f, -0.7230f, 0.4460f, -0.6260f, -0.810f, + 0.8720f, -0.2120f, -0.580f, -0.9510f, -0.8430f, -0.1340f, -0.0850f, + 0.9190f, + }; + float expected_same[] = { + 0.430f, 0.660f, 0.5510f, -0.610f, 0.450f, -0.1610f, 0.0520f, 0.3240f, + 0.6820f, 0.3820f, 0.6360f, 0.7480f, 0.3080f, 0.090f, 0.3910f, 0.1730f, + 0.340f, 0.6660f, -0.4990f, 0.4280f, 0.1540f, 0.120f, 0.4670f, 0.6150f, + -0.3880f, 0.7590f, 0.4190f, 0.7350f, 0.5310f, -0.5160f, -0.1760f, 0.6790f, + -0.6780f, 0.5470f, 0.5750f, -0.6420f, 0.7210f, -0.4620f, 0.5430f, 0.770f, + -0.1990f, 0.3950f, 0.7860f, -0.4380f, 0.7540f, 0.2640f, -0.6430f, 0.4510f, + -0.1260f, 0.1590f, -0.2110f, -0.0560f, 0.6570f, 0.680f, 0.5870f, 0.4720f, + 0.4040f, 0.3630f, 0.670f, 0.2360f, 0.410f, 0.6980f, -0.5350f, 0.3940f, + }; + float expected_replicate[] = { + 0.540f, 0.7230f, -0.3530f, -0.2130f, 0.7440f, -0.4470f, -0.6260f, + -0.2050f, 0.7230f, 0.4630f, 0.5920f, 0.7440f, 0.6080f, 0.3130f, + -0.5670f, -0.4720f, 0.5480f, 0.6660f, -0.4990f, 0.4280f, 0.1540f, + 0.120f, 0.3390f, 0.6090f, 0.4160f, 0.7590f, 0.4190f, 0.7350f, + 0.5310f, -0.5160f, -0.490f, 0.4450f, -0.610f, 0.5470f, 0.5750f, + -0.6420f, 0.7210f, -0.4620f, 0.3150f, 0.7370f, -0.5820f, 0.3950f, + 0.7860f, -0.4380f, 0.7540f, 0.2640f, -0.7430f, -0.5340f, -0.6270f, + 0.4430f, 0.4730f, 0.4570f, 0.7450f, 0.630f, 0.2620f, 0.3140f, + -0.1840f, 0.1810f, 0.7210f, 0.2760f, 0.6430f, 0.6720f, -0.4390f, + 0.2040f, + }; + float expected_valid[] = { + 0.6660f, -0.4990f, 0.4280f, 0.1540f, 0.120f, 0.7590f, 0.4190f, + 0.7350f, 0.5310f, -0.5160f, 0.5470f, 0.5750f, -0.6420f, 0.7210f, + -0.4620f, 0.3950f, 0.7860f, -0.4380f, 0.7540f, 0.2640f, + }; + float weights[] = { + 0.6210f, 0.3710f, -0.2770f, -0.7230f, -0.2450f, 0.6770f, 0.3080f, + -0.9880f, -0.080f, 0.7190f, -0.6760f, -0.0170f, -0.8970f, 0.8260f, + 0.7390f, -0.4550f, -0.4260f, -0.6330f, 0.0880f, -0.9390f, + }; + float bias[] = { + 0.750f, + }; + + CNN_CONFIG cnn_config = { 1, + 0, + 0, + 0, + 0, + { { + 1, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + SOFTSIGN, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected_same, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); + + cnn_config.layer_config[0].pad = PADDING_SAME_REPLICATE; + + RunCNNTest(image_width, image_height, input, expected_replicate, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); + + cnn_config.layer_config[0].pad = PADDING_VALID; + + RunCNNTest(image_width, image_height, input, expected_valid, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); +} + +TEST_F(CNNTest, TestBranchTensorAdd) { + int filter_width = 2; + int filter_height = 3; + + int image_width = 4; + int image_height = 4; + + float input[] = { + -3, -2, -2, 0, -1, 3, 2, -2, 1, 3, 4, 0, 2, -5, -4, 0, + }; + + float weights[] = { + -3, -1, 4, -1, -3, 3, 3, 0, 2, 0, 3, 2, 4, 4, 4, -5, 1, -4, + 2, -4, 1, -3, 0, 4, -5, 4, 0, -4, -3, -1, 0, 0, -2, 0, 0, 2, + -5, -1, 1, -3, 3, 4, 3, 0, 1, -1, 1, 1, 2, 4, -2, -5, 2, -2, + 3, -2, 4, -1, 0, 2, 3, 2, -2, -1, -3, 1, 3, 4, -1, -3, 0, -4, + 4, 2, -3, -3, -1, 0, 1, 0, 3, 3, -3, 0, 3, 2, -5, -3, 4, -5, + 3, -1, -1, -3, 0, 1, -1, -4, 2, 4, -1, 4, -1, 1, 3, 4, 4, 4, + 0, -1, -3, -3, -3, -3, 2, -3, -2, 2, 3, -3, + }; + + float bias[] = { + 3, 4, -1, -1, 2, 1, -2, 1, 4, 1, 3, + }; + + float expected[] = { + -11502, -4101, -3424, 668, -17950, -5470, -5504, 626, + 4835, 446, 1779, -3483, 3679, -4214, 4578, -105, + }; + + int channels = 2; + + CNN_CONFIG cnn_config = { 6, + 0, + 0, + 0, + 0, + { { + 1, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_INPUT, + BRANCH_NOC, + { + 0x02, + 0, + 0x00, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_ADD, + { + 0x00, + 0, + 0x02, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestBranchTensorConcatenation) { + int filter_width = 2; + int filter_height = 3; + + int image_width = 4; + int image_height = 4; + + float input[] = { + -3, -2, -2, 0, -1, 3, 2, -2, 1, 3, 4, 0, 2, -5, -4, 0, + }; + + float weights[] = { + 3, 0, 2, 0, 2, 3, 1, -3, 1, -5, -3, 0, -4, 4, 0, -5, 0, -5, -1, + -2, -5, 0, -3, 2, -4, 2, 0, 2, -1, 0, -4, 3, 0, 0, -1, -5, 2, -1, + 4, -4, -2, -3, -3, 3, 4, -2, -1, -4, -1, 4, 4, -1, 4, 3, -4, 2, -2, + -4, -3, -2, 3, -3, -5, -1, 3, -2, 4, 1, -4, -3, -5, -5, -3, 4, -2, -2, + -1, -5, -5, 0, -1, -2, -3, 3, -4, -5, 2, -3, 1, 0, -5, 2, 2, -2, 0, + 2, 2, -2, 4, 2, 2, 0, 1, -5, -3, 0, 2, -2, 1, 2, -5, 2, 3, 3, + -1, 3, 0, -3, 3, -4, -4, 3, 3, -4, -2, 2, -2, 2, -2, -1, 3, 0, + }; + + float bias[] = { + -3, -5, 4, -4, -3, -2, 0, 3, -4, 4, -3, + }; + + float expected[] = { + -33533, -32087, -6741, -2124, 39979, 41453, 14034, 689, + -22611, -42203, -14882, -239, 15781, 15963, 9524, 837, + }; + + int channels = 2; + + CNN_CONFIG cnn_config = { 6, + 0, + 0, + 0, + 0, + { { + 1, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_INPUT, + BRANCH_NOC, + { + 0x02, + 0, + 0x00, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_CAT, + { + 0x00, + 0, + 0x02, + }, + {}, + -1, + }, + { + channels + channels, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + } } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +// TODO(logangw): Add test to test all combinations of branch_copy_type. + +TEST_F(CNNTest, TestBranchCombinations) { + int filter_width = 2; + int filter_height = 3; + + int image_width = 4; + int image_height = 4; + + float input[] = { + 3, 2, -5, -4, 4, -2, -4, -3, 4, 2, -3, 2, -3, 1, -5, -1, + }; + + float weights[] = { + 2, 3, 0, 4, 4, 3, 1, 0, 1, -5, 4, -3, 3, 0, 4, -1, -1, -5, + 2, 1, -3, -5, 3, -1, -3, -2, 0, -2, 3, 0, -2, -4, -2, -2, 2, -5, + 4, -5, 0, 1, -5, -4, -3, -4, 2, -2, 1, 0, 3, -2, -4, 3, 4, -4, + -1, -1, -3, -2, -2, -1, 2, 0, 2, -1, 2, -4, -4, -1, 2, 0, 3, -2, + -2, 3, -3, 4, -2, 4, 3, 4, 1, 0, -2, -3, -5, 1, -3, 2, 0, -2, + -2, -1, -1, -5, -2, -3, -1, 3, 3, 4, 4, 0, 2, 1, 3, -3, 2, -5, + -5, 1, -5, -1, 3, 3, 2, -4, -1, 3, -4, -2, -5, -2, 1, 3, 2, 2, + -5, -2, -3, -1, -2, -4, -1, -2, 2, 1, -4, -4, 2, 0, 2, 0, 2, -3, + -2, -4, 4, 0, 1, -3, -5, 4, -1, 2, 3, -5, -1, 0, 4, -1, -1, 3, + -1, -3, 3, 1, 4, 3, 4, 3, -4, -5, -1, 3, 3, -4, 3, 1, 3, -5, + 3, 4, -5, 4, 2, -1, -5, 2, 1, 0, 4, 0, -3, 2, 0, 2, -2, 1, + -1, -2, -1, -5, 4, 3, 3, -2, 2, 4, -5, -5, -3, -2, 4, 0, -4, 1, + }; + + float bias[] = { + -1, 4, 0, 2, 2, -2, 0, -4, -5, -1, 1, -2, 3, 0, 4, -2, 1, 0, 0, + }; + + float expected[] = { + 149496, 15553, -24193, -20956, 134094, 86432, -68283, -6366, + -53031, 133739, 67407, -13539, -53205, -58635, -20033, 1979, + }; + + int channels = 2; + + CNN_CONFIG cnn_config = { 10, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_INPUT, + BRANCH_NOC, + { + 0x06, + 0, + 0x00, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 2, + BRANCH_OUTPUT, + BRANCH_NOC, + { + 0x08, + 0, + 0x00, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 3, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 2, + BRANCH_NO_COPY, + BRANCH_ADD, + { + 0x00, + 0, + 0x08, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 2, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 1, + BRANCH_NO_COPY, + BRANCH_ADD, + { + 0x00, + 0, + 0x0C, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + channels, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_ADD, + { + 0x00, + 0, + 0x02, + }, + {}, + -1, + }, + { + channels, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + }, + } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestSplittingTensors) { + int filter_width = 2; + int filter_height = 3; + + int image_width = 4; + int image_height = 4; + + float input[] = { + -1, -1, 2, 1, 3, 2, 4, -3, -4, -2, 2, -3, 1, -3, 4, -2, + }; + + float weights[] = { + -4, 1, 0, 2, 3, 4, 4, -4, -5, -3, 2, 2, -4, -3, 3, 2, + 4, -4, -3, -4, -4, 1, -3, -5, -3, 4, 2, -2, 2, -1, -4, -1, + -2, -3, 1, 1, 0, -5, -1, 3, 3, -5, -3, 0, -3, 1, -3, -1, + 1, -3, -2, -2, 4, -2, 0, 1, 2, 2, -4, 2, 4, 0, -5, -2, + 4, 4, -5, 1, 0, 2, -2, -5, -5, -3, -5, -5, 4, -3, 0, 0, + -4, -4, 0, -5, -4, 0, 0, -3, -5, -3, -1, 2, -1, 4, -1, 2, + }; + + float bias[] = { + -4, -2, -3, -3, 3, 1, -2, + }; + + float expected[] = { + 530, -762, 1469, 777, 849, -771, -1698, 600, + -658, -1821, 98, -668, -1798, 30, 887, -971, + }; + + CNN_CONFIG cnn_config = { 3, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + 4, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_OUTPUT, + BRANCH_NOC, + { + 0x02, + 2, + 0x00, + }, + {}, + -1, + }, + { + 4, + filter_width, + filter_height, + 2, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_CAT, + { + 0x00, + 0, + 0x02, + }, + {}, + -1, + }, + { + 4, + filter_width, + filter_height, + 1, + 1, + 1, + 0, + nullptr, + nullptr, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + }, + } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_INT_TOL); +} + +TEST_F(CNNTest, TestOutputChannelsCount) { + int filter_width = 1; + int filter_height = 1; + + int image_width = 2; + int image_height = 2; + + float input[] = { 0, 0, 0, 0 }; + + float weights[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + float bias[] = { 0, 0, 0, 0, 0, 0 }; + + float expected[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + CNN_CONFIG cnn_config = { 3, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + 2, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_INPUT, + BRANCH_NOC, + { + 0x06, + 0, + 0x00, + }, + {}, + -1, + }, + { + 1, + filter_width, + filter_height, + 2, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 2, + BRANCH_NO_COPY, + BRANCH_CAT, + { + 0x00, + 0, + 0x03, + }, + {}, + -1, + }, + { + 2, + filter_width, + filter_height, + 2, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_CAT, + { + 0x00, + 0, + 0x04, + }, + {}, + 0, + }, + } }; + + // Weights and biases need to be specified separately because + // of the offset. + AssignLayerWeightsBiases(&cnn_config, weights, bias); + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); +} + +TEST_F(CNNTest, TestBatchNorm) { + int image_width = 28; + int image_height = 28; + int filter_height = 7; + int filter_width = 7; + float input[] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0117647f, 0.0705882f, 0.0705882f, 0.0705882f, + 0.494118f, 0.533333f, 0.686275f, 0.101961f, 0.65098f, 1.0f, + 0.968627f, 0.498039f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.117647f, 0.141176f, 0.368627f, 0.603922f, + 0.666667f, 0.992157f, 0.992157f, 0.992157f, 0.992157f, 0.992157f, + 0.882353f, 0.67451f, 0.992157f, 0.94902f, 0.764706f, 0.25098f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.192157f, + 0.933333f, 0.992157f, 0.992157f, 0.992157f, 0.992157f, 0.992157f, + 0.992157f, 0.992157f, 0.992157f, 0.984314f, 0.364706f, 0.321569f, + 0.321569f, 0.219608f, 0.152941f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0705882f, 0.858824f, 0.992157f, + 0.992157f, 0.992157f, 0.992157f, 0.992157f, 0.776471f, 0.713725f, + 0.968627f, 0.945098f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.313725f, 0.611765f, 0.419608f, 0.992157f, + 0.992157f, 0.803922f, 0.0431373f, 0.0f, 0.168627f, 0.603922f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.054902f, 0.00392157f, 0.603922f, 0.992157f, 0.352941f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.545098f, 0.992157f, 0.745098f, 0.00784314f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0431373f, + 0.745098f, 0.992157f, 0.27451f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.137255f, 0.945098f, + 0.882353f, 0.627451f, 0.423529f, 0.00392157f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.317647f, 0.941176f, 0.992157f, + 0.992157f, 0.466667f, 0.0980392f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.176471f, 0.729412f, 0.992157f, 0.992157f, + 0.588235f, 0.105882f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0627451f, 0.364706f, 0.988235f, 0.992157f, 0.733333f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.976471f, 0.992157f, 0.976471f, 0.25098f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.180392f, 0.509804f, 0.717647f, 0.992157f, + 0.992157f, 0.811765f, 0.00784314f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.152941f, 0.580392f, + 0.898039f, 0.992157f, 0.992157f, 0.992157f, 0.980392f, 0.713725f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0941176f, 0.447059f, 0.866667f, 0.992157f, 0.992157f, 0.992157f, + 0.992157f, 0.788235f, 0.305882f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0901961f, 0.258824f, 0.835294f, 0.992157f, + 0.992157f, 0.992157f, 0.992157f, 0.776471f, 0.317647f, 0.00784314f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0705882f, 0.670588f, + 0.858824f, 0.992157f, 0.992157f, 0.992157f, 0.992157f, 0.764706f, + 0.313725f, 0.0352941f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.215686f, 0.67451f, 0.886275f, 0.992157f, 0.992157f, 0.992157f, + 0.992157f, 0.956863f, 0.521569f, 0.0431373f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.533333f, 0.992157f, + 0.992157f, 0.992157f, 0.831373f, 0.529412f, 0.517647f, 0.0627451f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }; + float expected[] = { + -0.836424f, -0.857365f, -1.62739f, -1.62739f, -0.836424f, 5.40742f, + 0.920853f, -0.692567f, -0.836424f, -0.534405f, -1.62739f, -0.836424f, + 1.32602f, 1.36312f, 0.112766f, -0.836424f, -0.192962f, 1.56975f, + 2.45777f, 0.944414f, -0.192962f, -1.5519f, -1.5519f, -0.554006f, + -0.192962f, 1.4231f, -1.5519f, -0.192962f, 1.3661f, -1.5519f, + -1.5519f, -0.192962f, -0.843708f, -0.359025f, -0.843708f, -0.843708f, + -0.843708f, 4.53065f, 0.0429584f, -0.796804f, -0.843708f, 0.3473f, + -0.843708f, -0.843708f, -0.114439f, 3.14817f, 0.0811934f, -0.843708f + }; + float kernel[] = { + 0.119643f, -0.237864f, 0.0462892f, 0.0502297f, -0.0134528f, + 0.146347f, 0.153133f, 0.0513307f, 0.0752369f, 0.0135557f, + -0.111434f, 0.0941854f, 0.0788362f, 0.0299412f, 0.111762f, + 0.144066f, 0.00431504f, -0.0177954f, 0.0738092f, -0.0344215f, + 0.0832582f, 0.053989f, -0.112691f, 0.0962145f, 0.0186525f, + -0.00660205f, -0.111962f, -0.126801f, -0.231625f, 0.17309f, + 0.0748875f, -0.179569f, -0.00513812f, -0.156579f, -0.147322f, + 0.184168f, 0.189308f, -0.200359f, -0.0156733f, 0.140649f, + 0.0858496f, -0.0263217f, -0.0740749f, -0.112563f, 0.107528f, + 0.0609729f, -0.221625f, 0.0769944f, -0.00900815f, -0.00136441f, + -0.0236521f, -0.0418025f, -0.00286299f, 0.12241f, 0.0964093f, + -0.0150897f, 0.0532171f, 0.0625916f, 0.116939f, 0.118024f, + 0.161918f, -0.00909767f, 0.100897f, -0.054563f, -0.175179f, + -0.0687892f, 0.00734235f, 0.109833f, -0.113776f, 0.0595405f, + -0.170255f, 0.0124815f, -0.0363301f, -0.0127038f, 0.0445554f, + -0.0729894f, 0.107428f, -0.0341417f, 0.132619f, 0.00984557f, + -0.00443654f, 0.202929f, 0.0945134f, 0.0148725f, 0.00998574f, + -0.0226449f, 0.0478197f, -0.0793442f, 0.0707599f, -0.084225f, + 0.0865795f, 0.071104f, -0.047894f, 0.0838322f, 0.0635493f, + -0.00370265f, -0.157247f, -0.0289622f, -0.0590963f, 0.13207f, + 0.00468011f, -0.0345372f, 0.217939f, 0.18861f, -0.0290393f, + -0.0440664f, 0.0126197f, -0.129132f, -0.124943f, 0.0968156f, + -0.0853643f, -0.182305f, 0.00461618f, -0.147095f, -0.230282f, + 0.00856019f, 0.0278893f, -0.0300229f, 0.0417871f, 0.0804717f, + -0.0768571f, -0.0397085f, -0.0601096f, 0.100901f, -0.0184926f, + 0.0350673f, 0.0971094f, -0.0171837f, -0.289644f, -0.0899041f, + 0.08998f, -0.160319f, -0.0195103f, 0.0392167f, -0.137864f, + -0.0136294f, 0.0330886f, -0.0409244f, -0.092533f, -0.0427934f, + -0.191144f, -0.0969461f, 0.112035f, 0.138611f, 0.128717f, + 0.191184f, 0.197462f + }; + float bias[] = { 0.186703f, 0.204358f, -0.0230452f }; + + float bn_gamma[] = { 1.32173f, 1.26171f, 1.21966f }; + float bn_beta[] = { -0.232595f, -0.222652f, -0.232209f }; + float bn_mean[] = { 0.329233f, 0.199894f, 0.12389f }; + float bn_std[] = { 0.311986f, 0.189737f, 0.247104f }; + + CNN_BATCHNORM_PARAMS bn_params = { + bn_gamma, + bn_beta, + bn_mean, + bn_std, + }; + + CNN_CONFIG cnn_config = { + 1, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + 3, + 7, + 7, + 0, + kernel, + bias, + PADDING_VALID, + RELU, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + bn_params, + 0, + }, + }, + }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); +} + +TEST_F(CNNTest, TestMultithreading) { + int image_height = 2; + int image_width = 2; + int filter_height = 3; + int filter_width = 3; + + float input[] = { + -2, + 4, + 1, + 0, + }; + + float weights[] = { + -4, 2, -2, 0, -4, 4, -3, -3, -3, -1, 1, 0, -5, -3, 0, -5, 0, 0, + -1, 0, 2, -5, 0, 1, 4, 2, 1, 0, -2, -1, -5, -3, 2, -2, 1, -5, + }; + + float bias[] = { + -4, + -3, + -2, + 3, + }; + + float expected[] = { + 2, 10, -8, -17, -24, 5, -15, 6, -5, -5, 7, -10, 4, 13, 9, -14, + }; + + CNN_CONFIG cnn_config = { + 1, + 0, + 0, + 0, + 0, + { + { + 1, + filter_width, + filter_height, + 4, + 1, + 1, + 0, + weights, + bias, + PADDING_SAME_ZERO, + NONE, + 0, + 0, + BRANCH_NO_COPY, + BRANCH_NOC, + {}, + {}, + 0, + }, + }, + }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); + + const AVxWorkerInterface *const winterface = aom_get_worker_interface(); + AVxWorker workers[4]; + + for (int i = 0; i < 4; ++i) { + winterface->init(&workers[i]); + } + + thread_data = { 4, workers }; + + RunCNNTest(image_width, image_height, input, expected, &cnn_config, + image_width, &thread_data, MSE_FLOAT_TOL); + + for (int i = 0; i < 4; ++i) { + winterface->end(&workers[i]); + } +} + +TEST_F(CNNTest, TestMultiOutput) { + const int image_dim = 8; + const int image_ch = 3; + const int filter_dim = 2; + const int stride = 2; + const int num_filters = 2; + + const float input_[] = { + 1.7537929121f, 0.134331551012f, 0.123580039877f, 0.957731845246f, + 0.391006834217f, 1.00699352042f, -0.778177955829f, -0.814166433059f, + -0.656374394915f, 0.321967305228f, -2.19455719176f, 0.708035038966f, + 0.409148822266f, -0.318254408902f, 0.152450211189f, -0.250210793369f, + 0.826811563186f, 1.6804156584f, 0.273626975978f, 0.437936241887f, + -0.329935520167f, -0.288761611645f, 0.156937008304f, 0.271054157295f, + -0.0224828854332f, 1.70110336895f, -0.989066699309f, 1.30863131729f, + -0.165813705702f, 0.00380178619265f, -0.0837342367587f, 0.760954783156f, + -0.413610373524f, 1.17968204175f, 0.720295719536f, 0.308718974472f, + -1.10091337671f, 0.693160033687f, -0.0202862320697f, 1.0221927503f, + -1.24521801881f, -0.478501952308f, -1.71648619442f, -0.182571723636f, + 0.339292649504f, 2.0806519131f, 0.967974033444f, 0.175248672328f, + 0.0658124561472f, 0.795504169496f, 0.750592557361f, -1.46631013249f, + -1.79052846838f, -1.03672179515f, -0.841985521653f, 1.20995011489f, + 0.140859718215f, -0.651552622661f, 0.451065110806f, 1.1189443693f, + 0.100213260593f, -0.834076868118f, -1.28734321611f, 1.22064420095f, + -0.364143084361f, 0.750961509335f, -0.888689074553f, -0.8253547106f, + -1.21800999027f, -0.966670603566f, 1.37384014741f, 0.47281264834f, + -0.420416235531f, 0.520163906493f, 0.501296589423f, 1.53418976951f, + 0.715234751485f, 0.644551588907f, 0.0763504863375f, -0.0018541943723f, + 0.322853189656f, -0.795099723224f, -0.125177096675f, 1.4476577471f, + -0.585888410088f, -1.44391754955f, -0.610543221933f, -0.221859179799f, + 0.252060200774f, -0.86287169623f, -0.0350246229157f, 1.0932311997f, + 0.899464648842f, -0.468806951704f, -0.300861137168f, 1.15776414206f, + 1.03268544738f, -0.171579585622f, -0.179136557119f, -0.354091003368f, + -0.612298249394f, -1.20237379258f, 1.54604109659f, 0.130664370287f, + 0.885225111868f, 1.0362799581f, 0.980561720868f, -0.619379186999f, + -1.33818929924f, -0.237233737961f, -1.89335425073f, 0.567821011321f, + 0.862420368465f, -1.37380916821f, 0.352190056666f, 0.611261516274f, + 0.393237747152f, 0.894686247967f, 0.190405182149f, 0.264872662911f, + -0.0657009133797f, 0.0580512653493f, -0.401825294366f, 0.4106081318f, + 0.49484512188f, -0.0751103149442f, -1.43243736382f, 1.79855656009f, + -1.1075351975f, 0.000354882733011f, -0.950716438608f, 1.27129831688f, + 1.00495189838f, 0.110358656713f, 1.08315032822f, -0.972676676218f, + -0.0757668962831f, 1.88932045165f, -0.0672638136275f, 0.425913010161f, + -0.781540372017f, 0.976000248609f, 0.687218504122f, 1.31374513445f, + -0.932658930672f, -1.25339468479f, 0.422071294078f, -0.24189927912f, + 0.216906604642f, -1.88720997548f, 1.99252872889f, 0.353943735777f, + 0.737434784132f, -1.17848645017f, 1.70424254896f, 0.775297112968f, + -0.516392797501f, 0.398130609129f, 0.737248101457f, 0.166282500886f, + 1.24699015468f, 0.47116183125f, 1.19091180182f, -0.372695424578f, + 0.219773209389f, -0.829467838962f, -0.52533122724f, 1.98707754595f, + 0.553692606972f, -0.933228902369f, 1.55427751643f, -1.08813399144f, + -0.325686682094f, 0.205091443796f, -1.70381666435f, 0.466465327942f, + 1.73126863447f, -0.939133672634f, 1.48318077459f, -0.599414038168f, + -1.1583078687f, 0.518116190201f, 0.133571482458f, 0.84958342672f, + 1.02205000597f, -0.0772082009087f, -1.69567503859f, 1.4697939436f, + 1.67813743122f, -0.627911582938f, 0.131380509137f, -1.35717850726f, + }; + const float *input[3] = { input_, &input_[image_dim * image_dim], + &input_[2 * image_dim * image_dim] }; + + const float bias[] = { 0.0f, 0.0f }; + + const float weights_1[] = { + -0.489547413618f, 0.141916424749f, -0.279286485585f, -0.115322211094f, + 0.299572786936f, 0.205289980785f, -0.536254480088f, -0.253626313744f, + -0.422883815849f, -0.169702966298f, -0.540104704793f, 0.495319646763f, + 0.298799079422f, -0.10054550901f, -0.306085047056f, 0.171061886165f, + -0.108058703878f, -0.410734629888f, -0.0640674673049f, -0.386524840979f, + -0.157203423678f, -0.362138920529f, -0.216206085209f, 0.147502517971f, + }; + + const float weights_2[] = { + 0.207580604357f, 0.480821146263f, -0.29111909562f, 0.47422567493f, + 0.206892553253f, -0.235067084092f, 0.354516800602f, -0.212399370252f, + -0.419071343731f, -0.050350731631f, -0.0516457320279f, -0.0359310500731f, + 0.567044864811f, -0.060341127522f, 0.0501464839637f, -0.437785677916f, + }; + + const float weights_3[] = { + -0.0690452401448f, -0.356657338763f, -0.219464031809f, 0.551288365843f, + 0.181372090853f, -0.00245268542109f, 0.409000696276f, -0.593209108763f, + 0.587352566749f, -0.243720660227f, 0.266232713887f, -0.00439285245097f, + 0.252883228305f, 0.152646192631f, 0.0918944932026f, 0.398853715057f, + }; + + const float weights_4[] = { + 0.207560791573f, 0.194201350401f, 0.227802322443f, 0.206533663345f, + 0.0557331066805f, 0.0224159800424f, -0.143939197467f, -0.27703361602f, + 0.130643888389f, -0.269456557461f, 0.186242862864f, -0.162879944774f, + -0.145503996718f, -0.0768822987581f, -0.203127976359f, -0.238119922873f, + -0.258806479994f, 0.0357957680385f, -0.1027606976f, -0.287920082345f, + 0.189047820993f, 0.250711538481f, -0.272815714175f, -0.0431449742024f, + 0.207261230996f, -0.0396472677451f, 0.131236557412f, 0.174291832499f, + -0.251515885765f, -0.107164007499f, 0.185824534748f, -0.00561585838161f, + 0.273393799578f, -0.139563699075f, -0.263922456031f, -0.118859844081f, + 0.109230982597f, -0.170170294794f, 0.0123025648515f, -0.0839368964355f, + -0.0774058234297f, 0.255847138286f, -0.208430879637f, 0.279170114319f, + -0.272890330712f, -0.217725903006f, -0.295923275459f, -0.17008723953f, + -0.284281803405f, 0.281406323629f, 0.266910044663f, -0.209963914338f, + 0.271980962964f, 0.142013581699f, -0.143896509026f, -0.290509242975f, + -0.305768180935f, 0.196902832117f, -0.090424189662f, -0.147460802346f, + 0.217722016651f, 0.12353848977f, -0.169177363577f, -0.0454230918512f, + }; + + const float expected_0[] = { + -2.04858441055f, -2.12883075791f, -0.045177363807f, 0.763949675768f, + -0.544361512821f, -1.58123168032f, 1.89319847039f, 0.16859080901f, + -1.16023321135f, -0.396988107751f, 1.76637090744f, -1.40434786514f, + 0.908227575669f, 0.817064817605f, 0.215631134908f, -0.848605613428f, + -0.106756747018f, 0.0193027166685f, 0.801345615113f, -0.395407237598f, + -1.79983795658f, -1.73054496242f, 0.0584392594454f, -0.388786095569f, + -0.237269619354f, 0.000843578271263f, -1.24043512104f, 0.487839445893f, + -0.394259726605f, 0.559632843424f, -0.527224052291f, -1.53792340282f, + }; + + const float expected_1[] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.4057888292f, 0.325309571755f, + 0.0f, 1.22013465602f, + }; + + const float expected_2[] = { + 0.156119444687f, + 0.517385299817f, + }; + + const float expected_3[] = { + 0.224177852984f, + 0.503384419034f, + 0.156119444687f, + 0.517385299817f, + }; + + const float *expected[] = { expected_0, expected_1, expected_2, expected_3 }; + + CNN_CONFIG cnn_config = { + 4, // num_layers + 0, // is_residue + 0, // ext_width + 0, // ext_height + 0, // strict_bounds + { + // layer_config + { + image_ch, // in_channels + filter_dim, // filter_width + filter_dim, // filter_height + num_filters, // out_channels + stride, // skip_width + stride, // skip_height + 0, // max_pool + weights_1, // weights + bias, // bias + PADDING_SAME_ZERO, // pad + NONE, // activation + 0, // deconvolve + 0, // branch + BRANCH_OUTPUT, // branch_copy_type + BRANCH_NOC, // branch_combine_type + { 2, 0, 0 }, // branch_config + {}, // bn_params + 0, // output_num + }, + { + num_filters, // in_channels + filter_dim, // filter_width + filter_dim, // filter_height + num_filters, // out_channels + stride, // skip_width + stride, // skip_height + 0, // max_pool + weights_2, // weights + bias, // bias + PADDING_SAME_ZERO, // pad + RELU, // activation + 0, // deconvolve + 0, // branch + BRANCH_NO_COPY, // branch_copy_type + BRANCH_NOC, // branch_combine_type + {}, // branch_config + {}, // bn_params + 1, // output_num + }, + { + num_filters, // in_channels + filter_dim, // filter_width + filter_dim, // filter_height + num_filters, // out_channels + stride, // skip_width + stride, // skip_height + 0, // max_pool + weights_3, // weights + bias, // bias + PADDING_SAME_ZERO, // pad + RELU, // activation + 0, // deconvolve + 0, // branch + BRANCH_NO_COPY, // branch_copy_type + BRANCH_NOC, // branch_combine_type + {}, // branch_config + {}, // bn_params + 2, // output_num + }, + { + num_filters, // in_channels + 2 * filter_dim, // filter_width + 2 * filter_dim, // filter_height + num_filters, // out_channels + 2 * stride, // skip_width + 2 * stride, // skip_height + 0, // max_pool + weights_4, // weights + bias, // bias + PADDING_VALID, // pad + RELU, // activation + 0, // deconvolve + 1, // branch + BRANCH_NO_COPY, // branch_copy_type + BRANCH_CAT, // branch_combine_type + { 0, 0, 1 }, // branch_config + {}, // bn_params + 3, // output_num + }, + }, + }; + + CNN_THREAD_DATA thread_data = { 1, NULL }; + + const int num_outputs = 4; + const int output_chs[4] = { filter_dim, filter_dim, filter_dim, + 2 * filter_dim }; + const int output_dims[4] = { 4, 2, 1, 1 }; + const int output_sizes[4] = { + output_chs[0] * output_dims[0] * output_dims[0], + output_chs[1] * output_dims[1] * output_dims[1], + output_chs[2] * output_dims[2] * output_dims[2], + output_chs[3] * output_dims[3] * output_dims[3], + }; + float *const output_ = (float *)aom_malloc( + sizeof(*output_) * + (output_sizes[0] + output_sizes[1] + output_sizes[2] + output_sizes[3])); + float *output[CNN_MAX_CHANNELS] = { nullptr }; + int ch_ite = 0; + float *output_ite = output_; + for (int output_idx = 0; output_idx < num_outputs; output_idx++) { + for (int channel = 0; channel < output_chs[output_idx]; ++channel) { + output[ch_ite++] = output_ite; + output_ite += output_dims[output_idx] * output_dims[output_idx]; + } + } + CNN_MULTI_OUT output_struct = { num_outputs, output_chs, output_dims, + output }; + + RunMultiOutCNNTest(input, image_dim, image_dim, image_dim, &cnn_config, + &thread_data, &output_struct, expected, MSE_FLOAT_TOL); + + aom_free(output_); +} diff --git a/media/libaom/src/test/codec_factory.h b/media/libaom/src/test/codec_factory.h index dd99110ee..801b8948f 100644 --- a/media/libaom/src/test/codec_factory.h +++ b/media/libaom/src/test/codec_factory.h @@ -11,6 +11,8 @@ #ifndef AOM_TEST_CODEC_FACTORY_H_ #define AOM_TEST_CODEC_FACTORY_H_ +#include <tuple> + #include "config/aom_config.h" #include "aom/aom_decoder.h" @@ -40,11 +42,11 @@ class CodecFactory { const aom_codec_flags_t flags) const = 0; virtual Encoder *CreateEncoder(aom_codec_enc_cfg_t cfg, - const unsigned long init_flags, + const aom_codec_flags_t init_flags, TwopassStatsStore *stats) const = 0; virtual aom_codec_err_t DefaultEncoderConfig(aom_codec_enc_cfg_t *cfg, - int usage) const = 0; + unsigned int usage) const = 0; }; /* Provide CodecTestWith<n>Params classes for a variable number of parameters @@ -54,27 +56,28 @@ class CodecFactory { template <class T1> class CodecTestWithParam : public ::testing::TestWithParam< - ::testing::tuple<const libaom_test::CodecFactory *, T1> > {}; + std::tuple<const libaom_test::CodecFactory *, T1> > {}; template <class T1, class T2> class CodecTestWith2Params : public ::testing::TestWithParam< - ::testing::tuple<const libaom_test::CodecFactory *, T1, T2> > {}; + std::tuple<const libaom_test::CodecFactory *, T1, T2> > {}; template <class T1, class T2, class T3> class CodecTestWith3Params : public ::testing::TestWithParam< - ::testing::tuple<const libaom_test::CodecFactory *, T1, T2, T3> > {}; + std::tuple<const libaom_test::CodecFactory *, T1, T2, T3> > {}; template <class T1, class T2, class T3, class T4> class CodecTestWith4Params - : public ::testing::TestWithParam< ::testing::tuple< - const libaom_test::CodecFactory *, T1, T2, T3, T4> > {}; + : public ::testing::TestWithParam< + std::tuple<const libaom_test::CodecFactory *, T1, T2, T3, T4> > {}; template <class T1, class T2, class T3, class T4, class T5> class CodecTestWith5Params - : public ::testing::TestWithParam< ::testing::tuple< - const libaom_test::CodecFactory *, T1, T2, T3, T4, T5> > {}; + : public ::testing::TestWithParam< + std::tuple<const libaom_test::CodecFactory *, T1, T2, T3, T4, T5> > { +}; /* * AV1 Codec Definitions @@ -98,7 +101,7 @@ class AV1Decoder : public Decoder { class AV1Encoder : public Encoder { public: - AV1Encoder(aom_codec_enc_cfg_t cfg, const uint32_t init_flags, + AV1Encoder(aom_codec_enc_cfg_t cfg, const aom_codec_flags_t init_flags, TwopassStatsStore *stats) : Encoder(cfg, init_flags, stats) {} @@ -132,7 +135,7 @@ class AV1CodecFactory : public CodecFactory { } virtual Encoder *CreateEncoder(aom_codec_enc_cfg_t cfg, - const unsigned long init_flags, + const aom_codec_flags_t init_flags, TwopassStatsStore *stats) const { #if CONFIG_AV1_ENCODER return new AV1Encoder(cfg, init_flags, stats); @@ -145,7 +148,7 @@ class AV1CodecFactory : public CodecFactory { } virtual aom_codec_err_t DefaultEncoderConfig(aom_codec_enc_cfg_t *cfg, - int usage) const { + unsigned int usage) const { #if CONFIG_AV1_ENCODER return aom_codec_enc_config_default(aom_codec_av1_cx(), cfg, usage); #else @@ -159,7 +162,7 @@ class AV1CodecFactory : public CodecFactory { const libaom_test::AV1CodecFactory kAV1; #define AV1_INSTANTIATE_TEST_CASE(test, ...) \ - INSTANTIATE_TEST_CASE_P( \ + INSTANTIATE_TEST_SUITE_P( \ AV1, test, \ ::testing::Combine( \ ::testing::Values(static_cast<const libaom_test::CodecFactory *>( \ diff --git a/media/libaom/src/test/coding_path_sync.cc b/media/libaom/src/test/coding_path_sync.cc index 6735236cc..4c613dc03 100644 --- a/media/libaom/src/test/coding_path_sync.cc +++ b/media/libaom/src/test/coding_path_sync.cc @@ -15,12 +15,13 @@ #include "config/aom_config.h" -#include "aom_ports/mem.h" // ROUND_POWER_OF_TWO #include "aom/aomcx.h" #include "aom/aomdx.h" #include "aom/aom_encoder.h" #include "aom/aom_decoder.h" +#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0])) + using libaom_test::ACMRandom; namespace { diff --git a/media/libaom/src/test/comp_avg_pred_test.cc b/media/libaom/src/test/comp_avg_pred_test.cc index 9ad8973f0..ac625a79d 100644 --- a/media/libaom/src/test/comp_avg_pred_test.cc +++ b/media/libaom/src/test/comp_avg_pred_test.cc @@ -11,62 +11,70 @@ #include "test/comp_avg_pred_test.h" -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; -using libaom_test::AV1JNTCOMPAVG::AV1HighBDJNTCOMPAVGTest; -using libaom_test::AV1JNTCOMPAVG::AV1HighBDJNTCOMPAVGUPSAMPLEDTest; -using libaom_test::AV1JNTCOMPAVG::AV1JNTCOMPAVGTest; -using libaom_test::AV1JNTCOMPAVG::AV1JNTCOMPAVGUPSAMPLEDTest; +using libaom_test::AV1DISTWTDCOMPAVG::AV1DISTWTDCOMPAVGTest; +using libaom_test::AV1DISTWTDCOMPAVG::AV1DISTWTDCOMPAVGUPSAMPLEDTest; +#if CONFIG_AV1_HIGHBITDEPTH +using libaom_test::AV1DISTWTDCOMPAVG::AV1HighBDDISTWTDCOMPAVGTest; +using libaom_test::AV1DISTWTDCOMPAVG::AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest; +#endif +using std::make_tuple; +using std::tuple; namespace { -TEST_P(AV1JNTCOMPAVGTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } +TEST_P(AV1DISTWTDCOMPAVGTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } -TEST_P(AV1JNTCOMPAVGTest, CheckOutput) { RunCheckOutput(GET_PARAM(0)); } +TEST_P(AV1DISTWTDCOMPAVGTest, CheckOutput) { RunCheckOutput(GET_PARAM(0)); } #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( - SSSE3, AV1JNTCOMPAVGTest, - libaom_test::AV1JNTCOMPAVG::BuildParams(aom_jnt_comp_avg_pred_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1DISTWTDCOMPAVGTest, + libaom_test::AV1DISTWTDCOMPAVG::BuildParams( + aom_dist_wtd_comp_avg_pred_ssse3)); #endif -TEST_P(AV1JNTCOMPAVGUPSAMPLEDTest, DISABLED_Speed) { +TEST_P(AV1DISTWTDCOMPAVGUPSAMPLEDTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } -TEST_P(AV1JNTCOMPAVGUPSAMPLEDTest, CheckOutput) { +TEST_P(AV1DISTWTDCOMPAVGUPSAMPLEDTest, CheckOutput) { RunCheckOutput(GET_PARAM(0)); } #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P(SSSE3, AV1JNTCOMPAVGUPSAMPLEDTest, - libaom_test::AV1JNTCOMPAVG::BuildParams( - aom_jnt_comp_avg_upsampled_pred_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1DISTWTDCOMPAVGUPSAMPLEDTest, + libaom_test::AV1DISTWTDCOMPAVG::BuildParams( + aom_dist_wtd_comp_avg_upsampled_pred_ssse3)); #endif -TEST_P(AV1HighBDJNTCOMPAVGTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(1)); } +#if CONFIG_AV1_HIGHBITDEPTH +TEST_P(AV1HighBDDISTWTDCOMPAVGTest, DISABLED_Speed) { + RunSpeedTest(GET_PARAM(1)); +} -TEST_P(AV1HighBDJNTCOMPAVGTest, CheckOutput) { RunCheckOutput(GET_PARAM(1)); } +TEST_P(AV1HighBDDISTWTDCOMPAVGTest, 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, 1)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1HighBDDISTWTDCOMPAVGTest, + libaom_test::AV1DISTWTDCOMPAVG::BuildParams( + aom_highbd_dist_wtd_comp_avg_pred_sse2, 1)); #endif -TEST_P(AV1HighBDJNTCOMPAVGUPSAMPLEDTest, DISABLED_Speed) { +TEST_P(AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(1)); } -TEST_P(AV1HighBDJNTCOMPAVGUPSAMPLEDTest, CheckOutput) { +TEST_P(AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest, CheckOutput) { RunCheckOutput(GET_PARAM(1)); } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, AV1HighBDJNTCOMPAVGUPSAMPLEDTest, - libaom_test::AV1JNTCOMPAVG::BuildParams( - aom_highbd_jnt_comp_avg_upsampled_pred_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest, + libaom_test::AV1DISTWTDCOMPAVG::BuildParams( + aom_highbd_dist_wtd_comp_avg_upsampled_pred_sse2)); #endif +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/comp_avg_pred_test.h b/media/libaom/src/test/comp_avg_pred_test.h index 9661dd9f5..7f73312c4 100644 --- a/media/libaom/src/test/comp_avg_pred_test.h +++ b/media/libaom/src/test/comp_avg_pred_test.h @@ -12,6 +12,8 @@ #ifndef AOM_TEST_COMP_AVG_PRED_TEST_H_ #define AOM_TEST_COMP_AVG_PRED_TEST_H_ +#include <tuple> + #include "config/aom_dsp_rtcd.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -25,72 +27,75 @@ namespace libaom_test { const int kMaxSize = 128 + 32; // padding -namespace AV1JNTCOMPAVG { +namespace AV1DISTWTDCOMPAVG { -typedef void (*jntcompavg_func)(uint8_t *comp_pred, const uint8_t *pred, - int width, int height, const uint8_t *ref, - int ref_stride, - const JNT_COMP_PARAMS *jcp_param); +typedef void (*distwtdcompavg_func)(uint8_t *comp_pred, const uint8_t *pred, + int width, int height, const uint8_t *ref, + int ref_stride, + const DIST_WTD_COMP_PARAMS *jcp_param); -typedef void (*jntcompavgupsampled_func)( +typedef void (*distwtdcompavgupsampled_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, int subpel_search); + int ref_stride, const DIST_WTD_COMP_PARAMS *jcp_param, int subpel_search); + +typedef std::tuple<distwtdcompavg_func, BLOCK_SIZE> DISTWTDCOMPAVGParam; + +typedef std::tuple<distwtdcompavgupsampled_func, BLOCK_SIZE> + DISTWTDCOMPAVGUPSAMPLEDParam; -typedef void (*highbdjntcompavgupsampled_func)( +#if CONFIG_AV1_HIGHBITDEPTH +typedef void (*highbddistwtdcompavgupsampled_func)( MACROBLOCKD *xd, const struct AV1Common *const cm, int mi_row, int mi_col, 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 DIST_WTD_COMP_PARAMS *jcp_param, int subpel_search); -typedef ::testing::tuple<jntcompavg_func, BLOCK_SIZE> JNTCOMPAVGParam; +typedef std::tuple<int, highbddistwtdcompavgupsampled_func, BLOCK_SIZE> + HighbdDISTWTDCOMPAVGUPSAMPLEDParam; -typedef ::testing::tuple<jntcompavgupsampled_func, BLOCK_SIZE> - JNTCOMPAVGUPSAMPLEDParam; +typedef std::tuple<int, distwtdcompavg_func, BLOCK_SIZE> + HighbdDISTWTDCOMPAVGParam; -typedef ::testing::tuple<int, jntcompavg_func, BLOCK_SIZE> - HighbdJNTCOMPAVGParam; - -typedef ::testing::tuple<int, highbdjntcompavgupsampled_func, BLOCK_SIZE> - HighbdJNTCOMPAVGUPSAMPLEDParam; - -::testing::internal::ParamGenerator<JNTCOMPAVGParam> BuildParams( - jntcompavg_func filter) { - return ::testing::Combine(::testing::Values(filter), +::testing::internal::ParamGenerator<HighbdDISTWTDCOMPAVGParam> BuildParams( + distwtdcompavg_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)); } -::testing::internal::ParamGenerator<JNTCOMPAVGUPSAMPLEDParam> BuildParams( - jntcompavgupsampled_func filter) { - return ::testing::Combine(::testing::Values(filter), +::testing::internal::ParamGenerator<HighbdDISTWTDCOMPAVGUPSAMPLEDParam> +BuildParams(highbddistwtdcompavgupsampled_func filter) { + return ::testing::Combine(::testing::Range(8, 13, 2), + ::testing::Values(filter), ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL)); } +#endif // CONFIG_AV1_HIGHBITDEPTH -::testing::internal::ParamGenerator<HighbdJNTCOMPAVGParam> BuildParams( - jntcompavg_func filter, int is_hbd) { - (void)is_hbd; - return ::testing::Combine(::testing::Range(8, 13, 2), - ::testing::Values(filter), +::testing::internal::ParamGenerator<DISTWTDCOMPAVGParam> BuildParams( + distwtdcompavg_func filter) { + return ::testing::Combine(::testing::Values(filter), ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL)); } -::testing::internal::ParamGenerator<HighbdJNTCOMPAVGUPSAMPLEDParam> BuildParams( - highbdjntcompavgupsampled_func filter) { - return ::testing::Combine(::testing::Range(8, 13, 2), - ::testing::Values(filter), +::testing::internal::ParamGenerator<DISTWTDCOMPAVGUPSAMPLEDParam> BuildParams( + distwtdcompavgupsampled_func filter) { + return ::testing::Combine(::testing::Values(filter), ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL)); } -class AV1JNTCOMPAVGTest : public ::testing::TestWithParam<JNTCOMPAVGParam> { +class AV1DISTWTDCOMPAVGTest + : public ::testing::TestWithParam<DISTWTDCOMPAVGParam> { public: - ~AV1JNTCOMPAVGTest() {} + ~AV1DISTWTDCOMPAVGTest() {} void SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } void TearDown() { libaom_test::ClearSystemState(); } protected: - void RunCheckOutput(jntcompavg_func test_impl) { + void RunCheckOutput(distwtdcompavg_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(1); @@ -107,27 +112,27 @@ class AV1JNTCOMPAVGTest : public ::testing::TestWithParam<JNTCOMPAVGParam> { const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; 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]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; + dist_wtd_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_pred_c(output, pred8 + offset_r * w + offset_c, in_w, - in_h, ref8 + offset_r * w + offset_c, in_w, - &jnt_comp_params); + aom_dist_wtd_comp_avg_pred_c(output, pred8 + offset_r * w + offset_c, + in_w, in_h, ref8 + offset_r * w + offset_c, + in_w, &dist_wtd_comp_params); test_impl(output2, pred8 + offset_r * w + offset_c, in_w, in_h, - ref8 + offset_r * w + offset_c, in_w, &jnt_comp_params); + ref8 + offset_r * w + offset_c, in_w, &dist_wtd_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 AV1JNTCOMPAVGTest\n" + << "Mismatch at unit tests for AV1DISTWTDCOMPAVGTest\n" << in_w << "x" << in_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << ")"; } @@ -135,7 +140,7 @@ class AV1JNTCOMPAVGTest : public ::testing::TestWithParam<JNTCOMPAVGParam> { } } } - void RunSpeedTest(jntcompavg_func test_impl) { + void RunSpeedTest(distwtdcompavg_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(1); @@ -152,49 +157,49 @@ class AV1JNTCOMPAVGTest : public ::testing::TestWithParam<JNTCOMPAVGParam> { const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; - jnt_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; - jnt_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; + dist_wtd_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; const int num_loops = 1000000000 / (in_w + in_h); aom_usec_timer timer; aom_usec_timer_start(&timer); for (int i = 0; i < num_loops; ++i) - aom_jnt_comp_avg_pred_c(output, pred8, in_w, in_h, ref8, in_w, - &jnt_comp_params); + aom_dist_wtd_comp_avg_pred_c(output, pred8, in_w, in_h, ref8, in_w, + &dist_wtd_comp_params); aom_usec_timer_mark(&timer); const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - printf("jntcompavg c_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("distwtdcompavg c_code %3dx%-3d: %7.2f us\n", in_w, in_h, 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(output2, pred8, in_w, in_h, ref8, in_w, &jnt_comp_params); + test_impl(output2, pred8, in_w, in_h, ref8, in_w, &dist_wtd_comp_params); aom_usec_timer_mark(&timer1); const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1)); - printf("jntcompavg test_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("distwtdcompavg test_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time1 / num_loops); } libaom_test::ACMRandom rnd_; -}; // class AV1JNTCOMPAVGTest +}; // class AV1DISTWTDCOMPAVGTest -class AV1JNTCOMPAVGUPSAMPLEDTest - : public ::testing::TestWithParam<JNTCOMPAVGUPSAMPLEDParam> { +class AV1DISTWTDCOMPAVGUPSAMPLEDTest + : public ::testing::TestWithParam<DISTWTDCOMPAVGUPSAMPLEDParam> { public: - ~AV1JNTCOMPAVGUPSAMPLEDTest() {} + ~AV1DISTWTDCOMPAVGUPSAMPLEDTest() {} void SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } void TearDown() { libaom_test::ClearSystemState(); } protected: - void RunCheckOutput(jntcompavgupsampled_func test_impl) { + void RunCheckOutput(distwtdcompavgupsampled_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(1); @@ -211,37 +216,40 @@ class AV1JNTCOMPAVGUPSAMPLEDTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; int sub_x_q3, sub_y_q3; int subpel_search; - for (subpel_search = 1; subpel_search <= 2; ++subpel_search) { + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++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]; + dist_wtd_comp_params.fwd_offset = + quant_dist_lookup_table[ii][jj][0]; + dist_wtd_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( + aom_dist_wtd_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); + &dist_wtd_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); + &dist_wtd_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" + "AV1DISTWTDCOMPAVGUPSAMPLEDTest\n" << in_w << "x" << in_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << "), sub pixel offset = (" << sub_y_q3 << ", " @@ -254,7 +262,7 @@ class AV1JNTCOMPAVGUPSAMPLEDTest } } } - void RunSpeedTest(jntcompavgupsampled_func test_impl) { + void RunSpeedTest(distwtdcompavgupsampled_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(1); @@ -271,11 +279,11 @@ class AV1JNTCOMPAVGUPSAMPLEDTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; - jnt_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; - jnt_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; + dist_wtd_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; int sub_x_q3 = 0; int sub_y_q3 = 0; @@ -283,16 +291,16 @@ 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. + int subpel_search = USE_8_TAPS; // set to USE_4_TAPS 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, subpel_search); + aom_dist_wtd_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, &dist_wtd_comp_params, subpel_search); aom_usec_timer_mark(&timer); const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - printf("jntcompavgupsampled c_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("distwtdcompavgupsampled c_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time / num_loops); aom_usec_timer timer1; @@ -300,27 +308,28 @@ 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, subpel_search); + sub_y_q3, ref8, in_w, &dist_wtd_comp_params, subpel_search); aom_usec_timer_mark(&timer1); const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1)); - printf("jntcompavgupsampled test_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("distwtdcompavgupsampled test_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time1 / num_loops); } libaom_test::ACMRandom rnd_; -}; // class AV1JNTCOMPAVGUPSAMPLEDTest +}; // class AV1DISTWTDCOMPAVGUPSAMPLEDTest -class AV1HighBDJNTCOMPAVGTest - : public ::testing::TestWithParam<HighbdJNTCOMPAVGParam> { +#if CONFIG_AV1_HIGHBITDEPTH +class AV1HighBDDISTWTDCOMPAVGTest + : public ::testing::TestWithParam<HighbdDISTWTDCOMPAVGParam> { public: - ~AV1HighBDJNTCOMPAVGTest() {} + ~AV1HighBDDISTWTDCOMPAVGTest() {} void SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } void TearDown() { libaom_test::ClearSystemState(); } protected: - void RunCheckOutput(jntcompavg_func test_impl) { + void RunCheckOutput(distwtdcompavg_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(2); const int bd = GET_PARAM(0); @@ -337,31 +346,31 @@ class AV1HighBDJNTCOMPAVGTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; 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]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; + dist_wtd_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_pred_c( + aom_highbd_dist_wtd_comp_avg_pred_c( 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); + &dist_wtd_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); + in_w, &dist_wtd_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 AV1HighBDJNTCOMPAVGTest\n" + << "Mismatch at unit tests for AV1HighBDDISTWTDCOMPAVGTest\n" << in_w << "x" << in_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << ")"; } @@ -369,7 +378,7 @@ class AV1HighBDJNTCOMPAVGTest } } } - void RunSpeedTest(jntcompavg_func test_impl) { + void RunSpeedTest(distwtdcompavg_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(2); const int bd = GET_PARAM(0); @@ -386,24 +395,24 @@ class AV1HighBDJNTCOMPAVGTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; - jnt_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; - jnt_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; + dist_wtd_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; const int num_loops = 1000000000 / (in_w + in_h); aom_usec_timer timer; aom_usec_timer_start(&timer); for (int i = 0; i < num_loops; ++i) - aom_highbd_jnt_comp_avg_pred_c( + aom_highbd_dist_wtd_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); + CONVERT_TO_BYTEPTR(ref8), in_w, &dist_wtd_comp_params); aom_usec_timer_mark(&timer); const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - printf("highbdjntcompavg c_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("highbddistwtdcompavg c_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time / num_loops); aom_usec_timer timer1; @@ -411,33 +420,33 @@ class AV1HighBDJNTCOMPAVGTest for (int i = 0; i < num_loops; ++i) test_impl(CONVERT_TO_BYTEPTR(output2), CONVERT_TO_BYTEPTR(pred8), in_w, - in_h, CONVERT_TO_BYTEPTR(ref8), in_w, &jnt_comp_params); + in_h, CONVERT_TO_BYTEPTR(ref8), in_w, &dist_wtd_comp_params); aom_usec_timer_mark(&timer1); const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1)); - printf("highbdjntcompavg test_code %3dx%-3d: %7.2f us\n", in_w, in_h, + printf("highbddistwtdcompavg test_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time1 / num_loops); } libaom_test::ACMRandom rnd_; -}; // class AV1HighBDJNTCOMPAVGTest +}; // class AV1HighBDDISTWTDCOMPAVGTest -class AV1HighBDJNTCOMPAVGUPSAMPLEDTest - : public ::testing::TestWithParam<HighbdJNTCOMPAVGUPSAMPLEDParam> { +class AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest + : public ::testing::TestWithParam<HighbdDISTWTDCOMPAVGUPSAMPLEDParam> { public: - ~AV1HighBDJNTCOMPAVGUPSAMPLEDTest() {} + ~AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest() {} void SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } void TearDown() { libaom_test::ClearSystemState(); } protected: - void RunCheckOutput(highbdjntcompavgupsampled_func test_impl) { + void RunCheckOutput(highbddistwtdcompavgupsampled_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(2); const int bd = GET_PARAM(0); uint16_t pred8[kMaxSize * kMaxSize]; uint16_t ref8[kMaxSize * kMaxSize]; - uint16_t output[kMaxSize * kMaxSize]; - uint16_t output2[kMaxSize * kMaxSize]; + DECLARE_ALIGNED(16, uint16_t, output[kMaxSize * kMaxSize]); + DECLARE_ALIGNED(16, uint16_t, output2[kMaxSize * kMaxSize]); for (int i = 0; i < h; ++i) for (int j = 0; j < w; ++j) { @@ -447,39 +456,42 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; int sub_x_q3, sub_y_q3; int subpel_search; - for (subpel_search = 1; subpel_search <= 2; ++subpel_search) { + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++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]; + dist_wtd_comp_params.fwd_offset = + quant_dist_lookup_table[ii][jj][0]; + dist_wtd_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( + aom_highbd_dist_wtd_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); + &dist_wtd_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); + in_w, bd, &dist_wtd_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" + "AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest\n" << in_w << "x" << in_h << " Pixel mismatch at index " << idx << " = (" << i << ", " << j << "), sub pixel offset = (" << sub_y_q3 << ", " @@ -492,14 +504,14 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest } } } - void RunSpeedTest(highbdjntcompavgupsampled_func test_impl) { + void RunSpeedTest(highbddistwtdcompavgupsampled_func test_impl) { const int w = kMaxSize, h = kMaxSize; const int block_idx = GET_PARAM(2); const int bd = GET_PARAM(0); uint16_t pred8[kMaxSize * kMaxSize]; uint16_t ref8[kMaxSize * kMaxSize]; - uint16_t output[kMaxSize * kMaxSize]; - uint16_t output2[kMaxSize * kMaxSize]; + DECLARE_ALIGNED(16, uint16_t, output[kMaxSize * kMaxSize]); + DECLARE_ALIGNED(16, uint16_t, output2[kMaxSize * kMaxSize]); for (int i = 0; i < h; ++i) for (int j = 0; j < w; ++j) { @@ -509,27 +521,28 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest const int in_w = block_size_wide[block_idx]; const int in_h = block_size_high[block_idx]; - JNT_COMP_PARAMS jnt_comp_params; - jnt_comp_params.use_jnt_comp_avg = 1; + DIST_WTD_COMP_PARAMS dist_wtd_comp_params; + dist_wtd_comp_params.use_dist_wtd_comp_avg = 1; - jnt_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; - jnt_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; + dist_wtd_comp_params.fwd_offset = quant_dist_lookup_table[0][0][0]; + dist_wtd_comp_params.bck_offset = quant_dist_lookup_table[0][0][1]; int sub_x_q3 = 0; int sub_y_q3 = 0; 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. + int subpel_search = USE_8_TAPS; // set to USE_4_TAPS to test 4-tap filter. for (int i = 0; i < num_loops; ++i) - aom_highbd_jnt_comp_avg_upsampled_pred_c( + aom_highbd_dist_wtd_comp_avg_upsampled_pred_c( 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); + CONVERT_TO_BYTEPTR(ref8), in_w, bd, &dist_wtd_comp_params, + subpel_search); aom_usec_timer_mark(&timer); const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - printf("highbdjntcompavgupsampled c_code %3dx%-3d: %7.2f us\n", in_w, in_h, - 1000.0 * elapsed_time / num_loops); + printf("highbddistwtdcompavgupsampled c_code %3dx%-3d: %7.2f us\n", in_w, + in_h, 1000.0 * elapsed_time / num_loops); aom_usec_timer timer1; aom_usec_timer_start(&timer1); @@ -537,19 +550,20 @@ class AV1HighBDJNTCOMPAVGUPSAMPLEDTest for (int i = 0; i < num_loops; ++i) 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, + CONVERT_TO_BYTEPTR(ref8), in_w, bd, &dist_wtd_comp_params, subpel_search); aom_usec_timer_mark(&timer1); const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1)); - printf("highbdjntcompavgupsampled test_code %3dx%-3d: %7.2f us\n", in_w, + printf("highbddistwtdcompavgupsampled test_code %3dx%-3d: %7.2f us\n", in_w, in_h, 1000.0 * elapsed_time1 / num_loops); } libaom_test::ACMRandom rnd_; -}; // class AV1HighBDJNTCOMPAVGUPSAMPLEDTest +}; // class AV1HighBDDISTWTDCOMPAVGUPSAMPLEDTest +#endif // CONFIG_AV1_HIGHBITDEPTH -} // namespace AV1JNTCOMPAVG +} // namespace AV1DISTWTDCOMPAVG } // namespace libaom_test #endif // AOM_TEST_COMP_AVG_PRED_TEST_H_ diff --git a/media/libaom/src/test/comp_mask_variance_test.cc b/media/libaom/src/test/comp_mask_variance_test.cc index 34be2aa6d..b666306a3 100644 --- a/media/libaom/src/test/comp_mask_variance_test.cc +++ b/media/libaom/src/test/comp_mask_variance_test.cc @@ -11,6 +11,7 @@ #include <cstdlib> #include <new> +#include <tuple> #include "config/aom_config.h" #include "config/aom_dsp_rtcd.h" @@ -34,13 +35,13 @@ typedef void (*comp_mask_pred_func)(uint8_t *comp_pred, const uint8_t *pred, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask); -#if HAVE_SSSE3 || HAVE_AV2 +#if HAVE_SSSE3 || HAVE_SSE2 || HAVE_AV2 const BLOCK_SIZE kValidBlockSize[] = { BLOCK_8X8, BLOCK_8X16, BLOCK_8X32, BLOCK_16X8, BLOCK_16X16, BLOCK_16X32, BLOCK_32X8, BLOCK_32X16, BLOCK_32X32, }; #endif -typedef ::testing::tuple<comp_mask_pred_func, BLOCK_SIZE> CompMaskPredParam; +typedef std::tuple<comp_mask_pred_func, BLOCK_SIZE> CompMaskPredParam; class AV1CompMaskVarianceTest : public ::testing::TestWithParam<CompMaskPredParam> { @@ -105,8 +106,7 @@ void AV1CompMaskVarianceTest::RunCheckOutput(comp_mask_pred_func test_impl, BLOCK_SIZE bsize, int inv) { const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); for (int wedge_index = 0; wedge_index < wedge_types; ++wedge_index) { const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize); @@ -123,8 +123,7 @@ void AV1CompMaskVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl, BLOCK_SIZE bsize) { const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); int wedge_index = wedge_types / 2; const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize); const int num_loops = 1000000000 / (w + h); @@ -158,14 +157,14 @@ TEST_P(AV1CompMaskVarianceTest, DISABLED_Speed) { } #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSSE3, AV1CompMaskVarianceTest, ::testing::Combine(::testing::Values(&aom_comp_mask_pred_ssse3), ::testing::ValuesIn(kValidBlockSize))); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1CompMaskVarianceTest, ::testing::Combine(::testing::Values(&aom_comp_mask_pred_avx2), ::testing::ValuesIn(kValidBlockSize))); @@ -189,9 +188,10 @@ void AV1CompMaskUpVarianceTest::RunCheckOutput(comp_mask_pred_func test_impl, BLOCK_SIZE bsize, int inv) { const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); int subpel_search; - for (subpel_search = 1; subpel_search <= 2; ++subpel_search) { + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++subpel_search) { // loop through subx and suby for (int sub = 0; sub < 8 * 8; ++sub) { int subx = sub & 0x7; @@ -223,15 +223,14 @@ void AV1CompMaskUpVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl, const int h = block_size_high[bsize]; const int subx = havSub ? 3 : 0; const int suby = havSub ? 4 : 0; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); int wedge_index = wedge_types / 2; const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize); 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. + int subpel_search = USE_8_TAPS; // set to USE_4_TAPS to test 4-tap filter. for (int i = 0; i < 2; ++i) { aom_usec_timer timer; aom_usec_timer_start(&timer); @@ -261,14 +260,14 @@ TEST_P(AV1CompMaskUpVarianceTest, DISABLED_Speed) { } #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSSE3, AV1CompMaskUpVarianceTest, ::testing::Combine(::testing::Values(&aom_comp_mask_pred_ssse3), ::testing::ValuesIn(kValidBlockSize))); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1CompMaskUpVarianceTest, ::testing::Combine(::testing::Values(&aom_comp_mask_pred_avx2), ::testing::ValuesIn(kValidBlockSize))); @@ -276,13 +275,14 @@ INSTANTIATE_TEST_CASE_P( #endif // ifndef aom_comp_mask_pred +#if CONFIG_AV1_HIGHBITDEPTH 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, int mask_stride, int invert_mask); -typedef ::testing::tuple<highbd_comp_mask_pred_func, BLOCK_SIZE, int> +typedef std::tuple<highbd_comp_mask_pred_func, BLOCK_SIZE, int> HighbdCompMaskPredParam; class AV1HighbdCompMaskVarianceTest @@ -346,11 +346,9 @@ void AV1HighbdCompMaskVarianceTest::TearDown() { void AV1HighbdCompMaskVarianceTest::RunCheckOutput( highbd_comp_mask_pred_func test_impl, BLOCK_SIZE bsize, int inv) { int bd_ = GET_PARAM(2); - const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); for (int i = 0; i < MAX_SB_SQUARE; ++i) { pred_[i] = rnd_.Rand16() & ((1 << bd_) - 1); @@ -380,8 +378,7 @@ void AV1HighbdCompMaskVarianceTest::RunSpeedTest( const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); int wedge_index = wedge_types / 2; for (int i = 0; i < MAX_SB_SQUARE; ++i) { @@ -425,7 +422,7 @@ TEST_P(AV1HighbdCompMaskVarianceTest, DISABLED_Speed) { } #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1HighbdCompMaskVarianceTest, ::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_avx2), ::testing::ValuesIn(kValidBlockSize), @@ -433,7 +430,7 @@ INSTANTIATE_TEST_CASE_P( #endif #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AV1HighbdCompMaskVarianceTest, ::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_sse2), ::testing::ValuesIn(kValidBlockSize), @@ -458,10 +455,11 @@ AV1HighbdCompMaskUpVarianceTest::~AV1HighbdCompMaskUpVarianceTest() { ; } void AV1HighbdCompMaskUpVarianceTest::RunCheckOutput( highbd_comp_mask_pred_func test_impl, BLOCK_SIZE bsize, int inv) { + (void)test_impl; int bd_ = GET_PARAM(2); const int w = block_size_wide[bsize]; const int h = block_size_high[bsize]; - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); for (int i = 0; i < MAX_SB_SQUARE; ++i) { pred_[i] = rnd_.Rand16() & ((1 << bd_) - 1); @@ -480,19 +478,24 @@ void AV1HighbdCompMaskUpVarianceTest::RunCheckOutput( 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); + // ref + aom_highbd_upsampled_pred_c( + NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(comp_pred1_), w, h, subx, + suby, CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, bd_, subpel_search); + + aom_highbd_comp_mask_pred_c( + CONVERT_TO_BYTEPTR(comp_pred1_), CONVERT_TO_BYTEPTR(pred_), w, h, + CONVERT_TO_BYTEPTR(comp_pred1_), w, mask, w, inv); + + // test + aom_highbd_upsampled_pred( + NULL, NULL, 0, 0, NULL, CONVERT_TO_BYTEPTR(comp_pred2_), w, h, subx, + suby, CONVERT_TO_BYTEPTR(ref_), MAX_SB_SIZE, bd_, subpel_search); + + aom_highbd_comp_mask_pred( + CONVERT_TO_BYTEPTR(comp_pred2_), CONVERT_TO_BYTEPTR(pred_), w, h, + CONVERT_TO_BYTEPTR(comp_pred2_), w, mask, w, inv); + ASSERT_EQ(CheckResult(w, h), true) << " wedge " << wedge_index << " inv " << inv << "sub (" << subx << "," << suby << ")"; @@ -508,8 +511,7 @@ void AV1HighbdCompMaskUpVarianceTest::RunSpeedTest( const int h = block_size_high[bsize]; const int subx = havSub ? 3 : 0; const int suby = havSub ? 4 : 0; - - int wedge_types = (1 << get_wedge_bits_lookup(bsize)); + const int wedge_types = get_wedge_types_lookup(bsize); int wedge_index = wedge_types / 2; const uint8_t *mask = av1_get_contiguous_soft_mask(wedge_index, 1, bsize); @@ -555,7 +557,7 @@ TEST_P(AV1HighbdCompMaskUpVarianceTest, DISABLED_Speed) { } #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1HighbdCompMaskUpVarianceTest, ::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_avx2), ::testing::ValuesIn(kValidBlockSize), @@ -563,7 +565,7 @@ INSTANTIATE_TEST_CASE_P( #endif #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AV1HighbdCompMaskUpVarianceTest, ::testing::Combine(::testing::Values(&aom_highbd_comp_mask_pred_sse2), ::testing::ValuesIn(kValidBlockSize), @@ -571,4 +573,5 @@ INSTANTIATE_TEST_CASE_P( #endif #endif // ifndef aom_highbd_comp_mask_pred +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace AV1CompMaskVariance diff --git a/media/libaom/src/test/convolve_round_test.cc b/media/libaom/src/test/convolve_round_test.cc index 2f801e7d4..4f17b5472 100644 --- a/media/libaom/src/test/convolve_round_test.cc +++ b/media/libaom/src/test/convolve_round_test.cc @@ -10,6 +10,7 @@ */ #include <assert.h> +#include <tuple> #include "config/av1_rtcd.h" @@ -52,7 +53,7 @@ void highbd_convolve_rounding_12(CONVOLVE_ROUNDING_PARAM) { typedef enum { LOWBITDEPTH_TEST, HIGHBITDEPTH_TEST } DataPathType; -using ::testing::tuple; +using std::tuple; typedef tuple<ConvolveRoundFunc, ConvolveRoundFunc, DataPathType> ConvolveRoundParam; @@ -162,7 +163,7 @@ class ConvolveRoundTest : public ::testing::TestWithParam<ConvolveRoundParam> { TEST_P(ConvolveRoundTest, BitExactCheck) { ConvolveRoundingRun(); } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_AVX2 const ConvolveRoundParam kConvRndParamArray[] = { make_tuple(&av1_convolve_rounding_c, &av1_convolve_rounding_avx2, @@ -177,7 +178,7 @@ const ConvolveRoundParam kConvRndParamArray[] = { &highbd_convolve_rounding_12<av1_highbd_convolve_rounding_avx2>, HIGHBITDEPTH_TEST) }; -INSTANTIATE_TEST_CASE_P(AVX2, ConvolveRoundTest, - ::testing::ValuesIn(kConvRndParamArray)); +INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveRoundTest, + ::testing::ValuesIn(kConvRndParamArray)); #endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/convolve_test.cc b/media/libaom/src/test/convolve_test.cc index de3f47628..0b1eea16a 100644 --- a/media/libaom/src/test/convolve_test.cc +++ b/media/libaom/src/test/convolve_test.cc @@ -10,6 +10,7 @@ */ #include <string.h> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -47,7 +48,7 @@ struct ConvolveFunctions { int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth. }; -typedef ::testing::tuple<int, int, const ConvolveFunctions *> ConvolveParam; +typedef std::tuple<int, int, const ConvolveFunctions *> ConvolveParam; #define ALL_SIZES_64(convolve_fn) \ make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \ @@ -273,6 +274,8 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> { input_ = reinterpret_cast<uint8_t *>( aom_memalign(kDataAlignment, kInputBufferSize + 1)) + 1; + ref8_ = reinterpret_cast<uint8_t *>( + aom_memalign(kDataAlignment, kOutputStride * kMaxDimension)); output_ = reinterpret_cast<uint8_t *>( aom_memalign(kDataAlignment, kOutputBufferSize)); output_ref_ = reinterpret_cast<uint8_t *>( @@ -280,6 +283,8 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> { input16_ = reinterpret_cast<uint16_t *>(aom_memalign( kDataAlignment, (kInputBufferSize + 1) * sizeof(uint16_t))) + 1; + ref16_ = reinterpret_cast<uint16_t *>(aom_memalign( + kDataAlignment, kOutputStride * kMaxDimension * sizeof(uint16_t))); output16_ = reinterpret_cast<uint16_t *>( aom_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t))); output16_ref_ = reinterpret_cast<uint16_t *>( @@ -291,12 +296,16 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> { static void TearDownTestCase() { aom_free(input_ - 1); input_ = NULL; + aom_free(ref8_); + ref8_ = NULL; aom_free(output_); output_ = NULL; aom_free(output_ref_); output_ref_ = NULL; aom_free(input16_ - 1); input16_ = NULL; + aom_free(ref16_); + ref16_ = NULL; aom_free(output16_); output16_ = NULL; aom_free(output16_ref_); @@ -449,18 +458,22 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> { const ConvolveFunctions *UUT_; static uint8_t *input_; + static uint8_t *ref8_; static uint8_t *output_; static uint8_t *output_ref_; static uint16_t *input16_; + static uint16_t *ref16_; static uint16_t *output16_; static uint16_t *output16_ref_; int mask_; }; uint8_t *ConvolveTest::input_ = NULL; +uint8_t *ConvolveTest::ref8_ = NULL; uint8_t *ConvolveTest::output_ = NULL; uint8_t *ConvolveTest::output_ref_ = NULL; uint16_t *ConvolveTest::input16_ = NULL; +uint16_t *ConvolveTest::ref16_ = NULL; uint16_t *ConvolveTest::output16_ = NULL; uint16_t *ConvolveTest::output16_ref_ = NULL; @@ -486,26 +499,28 @@ const int kNumFilterBanks = SWITCHABLE_FILTERS; const int kNumFilters = 16; TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) { - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpFilter filter = (InterpFilter)filter_bank; - const InterpKernel *filters = - (const InterpKernel *)av1_get_interp_filter_kernel(filter); - const InterpFilterParams *filter_params = - av1_get_interp_filter_params_with_block_size(filter, 8); - if (filter_params->taps != SUBPEL_TAPS) continue; - for (int i = 0; i < kNumFilters; i++) { - const int p0 = filters[i][0] + filters[i][1]; - const int p1 = filters[i][2] + filters[i][3]; - const int p2 = filters[i][4] + filters[i][5]; - const int p3 = filters[i][6] + filters[i][7]; - EXPECT_LE(p0, 128); - EXPECT_LE(p1, 128); - EXPECT_LE(p2, 128); - EXPECT_LE(p3, 128); - EXPECT_LE(p0 + p3, 128); - EXPECT_LE(p0 + p3 + p1, 128); - EXPECT_LE(p0 + p3 + p1 + p2, 128); - EXPECT_EQ(p0 + p1 + p2 + p3, 128); + int subpel_search; + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++subpel_search) { + for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { + const InterpFilter filter = (InterpFilter)filter_bank; + const InterpKernel *filters = + (const InterpKernel *)av1_get_interp_filter_kernel(filter, + subpel_search); + for (int i = 0; i < kNumFilters; i++) { + const int p0 = filters[i][0] + filters[i][1]; + const int p1 = filters[i][2] + filters[i][3]; + const int p2 = filters[i][4] + filters[i][5]; + const int p3 = filters[i][6] + filters[i][7]; + EXPECT_LE(p0, 128); + EXPECT_LE(p1, 128); + EXPECT_LE(p2, 128); + EXPECT_LE(p3, 128); + EXPECT_LE(p0 + p3, 128); + EXPECT_LE(p0 + p3 + p1, 128); + EXPECT_LE(p0 + p3 + p1 + p2, 128); + EXPECT_EQ(p0 + p1 + p2 + p3, 128); + } } } } @@ -515,53 +530,51 @@ const int16_t kInvalidFilter[8] = { 0 }; TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) { uint8_t *const in = input(); uint8_t *const out = output(); - uint8_t ref8[kOutputStride * kMaxDimension]; - uint16_t ref16[kOutputStride * kMaxDimension]; uint8_t *ref; if (UUT_->use_highbd_ == 0) { - ref = ref8; + ref = ref8_; } else { - ref = CONVERT_TO_BYTEPTR(ref16); - } - - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpFilter filter = (InterpFilter)filter_bank; - const InterpKernel *filters = - (const InterpKernel *)av1_get_interp_filter_kernel(filter); - const InterpFilterParams *filter_params = - av1_get_interp_filter_params_with_block_size(filter, 8); - if (filter_params->taps != SUBPEL_TAPS) continue; - - for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { - for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { - wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x], - filters[filter_y], ref, kOutputStride, - Width(), Height()); - - if (filter_x && filter_y) - continue; - else if (filter_y) - ASM_REGISTER_STATE_CHECK( - UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter, - 16, filters[filter_y], 16, Width(), Height())); - else if (filter_x) - ASM_REGISTER_STATE_CHECK( - UUT_->h8_(in, kInputStride, out, kOutputStride, filters[filter_x], - 16, kInvalidFilter, 16, Width(), Height())); - else - ASM_REGISTER_STATE_CHECK( - UUT_->copy_(in, kInputStride, out, kOutputStride, kInvalidFilter, - 0, kInvalidFilter, 0, Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(ref, y * kOutputStride + x), - lookup(out, y * kOutputStride + x)) - << "mismatch at (" << x << "," << y << "), " - << "filters (" << filter_bank << "," << filter_x << "," - << filter_y << ")"; + ref = CONVERT_TO_BYTEPTR(ref16_); + } + int subpel_search; + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++subpel_search) { + for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { + const InterpFilter filter = (InterpFilter)filter_bank; + const InterpKernel *filters = + (const InterpKernel *)av1_get_interp_filter_kernel(filter, + subpel_search); + for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { + for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { + wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x], + filters[filter_y], ref, kOutputStride, + Width(), Height()); + + if (filter_x && filter_y) + continue; + else if (filter_y) + ASM_REGISTER_STATE_CHECK( + UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter, + 16, filters[filter_y], 16, Width(), Height())); + else if (filter_x) + ASM_REGISTER_STATE_CHECK(UUT_->h8_( + in, kInputStride, out, kOutputStride, filters[filter_x], 16, + kInvalidFilter, 16, Width(), Height())); + else + ASM_REGISTER_STATE_CHECK(UUT_->copy_( + in, kInputStride, out, kOutputStride, kInvalidFilter, 0, + kInvalidFilter, 0, Width(), Height())); + + CheckGuardBlocks(); + + for (int y = 0; y < Height(); ++y) + for (int x = 0; x < Width(); ++x) + ASSERT_EQ(lookup(ref, y * kOutputStride + x), + lookup(out, y * kOutputStride + x)) + << "mismatch at (" << x << "," << y << "), " + << "filters (" << filter_bank << "," << filter_x << "," + << filter_y << ")"; + } } } } @@ -570,13 +583,11 @@ TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) { TEST_P(ConvolveTest, FilterExtremes) { uint8_t *const in = input(); uint8_t *const out = output(); - uint8_t ref8[kOutputStride * kMaxDimension]; - uint16_t ref16[kOutputStride * kMaxDimension]; uint8_t *ref; if (UUT_->use_highbd_ == 0) { - ref = ref8; + ref = ref8_; } else { - ref = CONVERT_TO_BYTEPTR(ref16); + ref = CONVERT_TO_BYTEPTR(ref16_); } // Populate ref and out with some random data @@ -609,41 +620,43 @@ TEST_P(ConvolveTest, FilterExtremes) { seed_val++; } if (axis) seed_val += 8; - - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpFilter filter = (InterpFilter)filter_bank; - const InterpKernel *filters = - (const InterpKernel *)av1_get_interp_filter_kernel(filter); - const InterpFilterParams *filter_params = - av1_get_interp_filter_params_with_block_size(filter, 8); - if (filter_params->taps != SUBPEL_TAPS) continue; - for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { - for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { - wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x], - filters[filter_y], ref, kOutputStride, - Width(), Height()); - if (filter_x && filter_y) - continue; - else if (filter_y) - ASM_REGISTER_STATE_CHECK(UUT_->v8_( - in, kInputStride, out, kOutputStride, kInvalidFilter, 16, - filters[filter_y], 16, Width(), Height())); - else if (filter_x) - ASM_REGISTER_STATE_CHECK(UUT_->h8_( - in, kInputStride, out, kOutputStride, filters[filter_x], 16, - kInvalidFilter, 16, Width(), Height())); - else - ASM_REGISTER_STATE_CHECK(UUT_->copy_( - in, kInputStride, out, kOutputStride, kInvalidFilter, 0, - kInvalidFilter, 0, Width(), Height())); - - for (int y = 0; y < Height(); ++y) - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(ref, y * kOutputStride + x), - lookup(out, y * kOutputStride + x)) - << "mismatch at (" << x << "," << y << "), " - << "filters (" << filter_bank << "," << filter_x << "," - << filter_y << ")"; + int subpel_search; + for (subpel_search = USE_4_TAPS; subpel_search <= USE_8_TAPS; + ++subpel_search) { + for (int filter_bank = 0; filter_bank < kNumFilterBanks; + ++filter_bank) { + const InterpFilter filter = (InterpFilter)filter_bank; + const InterpKernel *filters = + (const InterpKernel *)av1_get_interp_filter_kernel(filter, + subpel_search); + for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { + for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { + wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x], + filters[filter_y], ref, kOutputStride, + Width(), Height()); + if (filter_x && filter_y) + continue; + else if (filter_y) + ASM_REGISTER_STATE_CHECK(UUT_->v8_( + in, kInputStride, out, kOutputStride, kInvalidFilter, 16, + filters[filter_y], 16, Width(), Height())); + else if (filter_x) + ASM_REGISTER_STATE_CHECK(UUT_->h8_( + in, kInputStride, out, kOutputStride, filters[filter_x], 16, + kInvalidFilter, 16, Width(), Height())); + else + ASM_REGISTER_STATE_CHECK(UUT_->copy_( + in, kInputStride, out, kOutputStride, kInvalidFilter, 0, + kInvalidFilter, 0, Width(), Height())); + + for (int y = 0; y < Height(); ++y) + for (int x = 0; x < Width(); ++x) + ASSERT_EQ(lookup(ref, y * kOutputStride + x), + lookup(out, y * kOutputStride + x)) + << "mismatch at (" << x << "," << y << "), " + << "filters (" << filter_bank << "," << filter_x << "," + << filter_y << ")"; + } } } } @@ -674,13 +687,11 @@ TEST_P(ConvolveTest, DISABLED_Copy_Speed) { TEST_P(ConvolveTest, DISABLED_Speed) { uint8_t *const in = input(); uint8_t *const out = output(); - uint8_t ref8[kOutputStride * kMaxDimension]; - uint16_t ref16[kOutputStride * kMaxDimension]; uint8_t *ref; if (UUT_->use_highbd_ == 0) { - ref = ref8; + ref = ref8_; } else { - ref = CONVERT_TO_BYTEPTR(ref16); + ref = CONVERT_TO_BYTEPTR(ref16_); } // Populate ref and out with some random data @@ -700,7 +711,7 @@ TEST_P(ConvolveTest, DISABLED_Speed) { const InterpFilter filter = (InterpFilter)1; const InterpKernel *filters = - (const InterpKernel *)av1_get_interp_filter_kernel(filter); + (const InterpKernel *)av1_get_interp_filter_kernel(filter, USE_8_TAPS); wrapper_filter_average_block2d_8_c(in, kInputStride, filters[1], filters[1], out, kOutputStride, Width(), Height()); @@ -712,11 +723,8 @@ TEST_P(ConvolveTest, DISABLED_Speed) { for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { const InterpFilter filter = (InterpFilter)filter_bank; const InterpKernel *filters = - (const InterpKernel *)av1_get_interp_filter_kernel(filter); - const InterpFilterParams *filter_params = - av1_get_interp_filter_params_with_block_size(filter, 8); - if (filter_params->taps != SUBPEL_TAPS) continue; - + (const InterpKernel *)av1_get_interp_filter_kernel(filter, + USE_8_TAPS); for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { if (filter_x && filter_y) continue; @@ -741,8 +749,10 @@ TEST_P(ConvolveTest, DISABLED_Speed) { UUT_->use_highbd_, elapsed_time); } -using ::testing::make_tuple; +using std::make_tuple; +// WRAP macro is only used for high bitdepth build. +#if CONFIG_AV1_HIGHBITDEPTH #define WRAP(func, bd) \ static void wrap_##func##_##bd( \ const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ @@ -786,39 +796,54 @@ WRAP(convolve_copy_avx2, 12) WRAP(convolve8_horiz_avx2, 12) WRAP(convolve8_vert_avx2, 12) #endif // HAVE_AVX2 +#endif // CONFIG_AV1_HIGHBITDEPTH #undef WRAP -const ConvolveFunctions convolve8_c(wrap_convolve_copy_c_8, - wrap_convolve8_horiz_c_8, - wrap_convolve8_vert_c_8, 8); -const ConvolveFunctions convolve10_c(wrap_convolve_copy_c_10, - wrap_convolve8_horiz_c_10, - wrap_convolve8_vert_c_10, 10); -const ConvolveFunctions convolve12_c(wrap_convolve_copy_c_12, - wrap_convolve8_horiz_c_12, - wrap_convolve8_vert_c_12, 12); -const ConvolveParam kArrayConvolve_c[] = { - ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c) -}; +#if CONFIG_AV1_HIGHBITDEPTH +const ConvolveFunctions wrap_convolve8_c(wrap_convolve_copy_c_8, + wrap_convolve8_horiz_c_8, + wrap_convolve8_vert_c_8, 8); +const ConvolveFunctions wrap_convolve10_c(wrap_convolve_copy_c_10, + wrap_convolve8_horiz_c_10, + wrap_convolve8_vert_c_10, 10); +const ConvolveFunctions wrap_convolve12_c(wrap_convolve_copy_c_12, + wrap_convolve8_horiz_c_12, + wrap_convolve8_vert_c_12, 12); +const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(wrap_convolve8_c), + ALL_SIZES(wrap_convolve10_c), + ALL_SIZES(wrap_convolve12_c) }; +#else +const ConvolveFunctions convolve8_c(aom_convolve_copy_c, aom_convolve8_horiz_c, + aom_convolve8_vert_c, 0); +const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c) }; +#endif -INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::ValuesIn(kArrayConvolve_c)); +INSTANTIATE_TEST_SUITE_P(C, ConvolveTest, + ::testing::ValuesIn(kArrayConvolve_c)); #if HAVE_SSE2 && ARCH_X86_64 -const ConvolveFunctions convolve8_sse2(wrap_convolve_copy_sse2_8, - wrap_convolve8_horiz_sse2_8, - wrap_convolve8_vert_sse2_8, 8); -const ConvolveFunctions convolve10_sse2(wrap_convolve_copy_sse2_10, - wrap_convolve8_horiz_sse2_10, - wrap_convolve8_vert_sse2_10, 10); -const ConvolveFunctions convolve12_sse2(wrap_convolve_copy_sse2_12, - wrap_convolve8_horiz_sse2_12, - wrap_convolve8_vert_sse2_12, 12); -const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2), - ALL_SIZES(convolve10_sse2), - ALL_SIZES(convolve12_sse2) }; -INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_sse2)); +#if CONFIG_AV1_HIGHBITDEPTH +const ConvolveFunctions wrap_convolve8_sse2(wrap_convolve_copy_sse2_8, + wrap_convolve8_horiz_sse2_8, + wrap_convolve8_vert_sse2_8, 8); +const ConvolveFunctions wrap_convolve10_sse2(wrap_convolve_copy_sse2_10, + wrap_convolve8_horiz_sse2_10, + wrap_convolve8_vert_sse2_10, 10); +const ConvolveFunctions wrap_convolve12_sse2(wrap_convolve_copy_sse2_12, + wrap_convolve8_horiz_sse2_12, + wrap_convolve8_vert_sse2_12, 12); +const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(wrap_convolve8_sse2), + ALL_SIZES(wrap_convolve10_sse2), + ALL_SIZES(wrap_convolve12_sse2) }; +#else +const ConvolveFunctions convolve8_sse2(aom_convolve_copy_c, + aom_convolve8_horiz_sse2, + aom_convolve8_vert_sse2, 0); +const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2) }; +#endif +INSTANTIATE_TEST_SUITE_P(SSE2, ConvolveTest, + ::testing::ValuesIn(kArrayConvolve_sse2)); #endif #if HAVE_SSSE3 @@ -827,15 +852,12 @@ const ConvolveFunctions convolve8_ssse3(aom_convolve_copy_c, aom_convolve8_vert_ssse3, 0); const ConvolveParam kArrayConvolve8_ssse3[] = { ALL_SIZES(convolve8_ssse3) }; -INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, ConvolveTest, + ::testing::ValuesIn(kArrayConvolve8_ssse3)); #endif #if HAVE_AVX2 -const ConvolveFunctions convolve8_avx2(aom_convolve_copy_c, - aom_convolve8_horiz_avx2, - aom_convolve8_vert_avx2, 0); - +#if CONFIG_AV1_HIGHBITDEPTH const ConvolveFunctions wrap_convolve8_avx2(wrap_convolve_copy_avx2_8, wrap_convolve8_horiz_avx2_8, wrap_convolve8_vert_avx2_8, 8); @@ -847,10 +869,17 @@ const ConvolveFunctions wrap_convolve12_avx2(wrap_convolve_copy_avx2_12, wrap_convolve8_vert_avx2_12, 12); const ConvolveParam kArray_Convolve8_avx2[] = { ALL_SIZES_64(wrap_convolve8_avx2), ALL_SIZES_64(wrap_convolve10_avx2), - ALL_SIZES_64(wrap_convolve12_avx2), ALL_SIZES(convolve8_avx2) + ALL_SIZES_64(wrap_convolve12_avx2) }; -INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest, - ::testing::ValuesIn(kArray_Convolve8_avx2)); +#else +const ConvolveFunctions convolve8_avx2(aom_convolve_copy_c, + aom_convolve8_horiz_avx2, + aom_convolve8_vert_avx2, 0); +const ConvolveParam kArray_Convolve8_avx2[] = { ALL_SIZES(convolve8_avx2) }; +#endif + +INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveTest, + ::testing::ValuesIn(kArray_Convolve8_avx2)); #endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/corner_match_test.cc b/media/libaom/src/test/corner_match_test.cc index 58e3139c5..c685dca80 100644 --- a/media/libaom/src/test/corner_match_test.cc +++ b/media/libaom/src/test/corner_match_test.cc @@ -8,6 +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. */ +#include <tuple> + #include "config/av1_rtcd.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -24,9 +26,13 @@ namespace AV1CornerMatch { using libaom_test::ACMRandom; -using ::testing::make_tuple; -using ::testing::tuple; -typedef tuple<int> CornerMatchParam; +typedef double (*ComputeCrossCorrFunc)(unsigned char *im1, int stride1, int x1, + int y1, unsigned char *im2, int stride2, + int x2, int y2); + +using std::make_tuple; +using std::tuple; +typedef tuple<int, ComputeCrossCorrFunc> CornerMatchParam; class AV1CornerMatchTest : public ::testing::TestWithParam<CornerMatchParam> { public: @@ -36,19 +42,24 @@ class AV1CornerMatchTest : public ::testing::TestWithParam<CornerMatchParam> { virtual void TearDown(); protected: - void RunCheckOutput(); + void RunCheckOutput(int run_times); + ComputeCrossCorrFunc target_func; libaom_test::ACMRandom rnd_; }; AV1CornerMatchTest::~AV1CornerMatchTest() {} -void AV1CornerMatchTest::SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } +void AV1CornerMatchTest::SetUp() { + rnd_.Reset(ACMRandom::DeterministicSeed()); + target_func = GET_PARAM(1); +} void AV1CornerMatchTest::TearDown() { libaom_test::ClearSystemState(); } -void AV1CornerMatchTest::RunCheckOutput() { +void AV1CornerMatchTest::RunCheckOutput(int run_times) { const int w = 128, h = 128; const int num_iters = 10000; int i, j; + aom_usec_timer ref_timer, test_timer; uint8_t *input1 = new uint8_t[w * h]; uint8_t *input2 = new uint8_t[w * h]; @@ -79,22 +90,55 @@ void AV1CornerMatchTest::RunCheckOutput() { int y2 = MATCH_SZ_BY2 + rnd_.PseudoUniform(h - 2 * MATCH_SZ_BY2); double res_c = - compute_cross_correlation_c(input1, w, x1, y1, input2, w, x2, y2); - double res_sse4 = - compute_cross_correlation_sse4_1(input1, w, x1, y1, input2, w, x2, y2); + av1_compute_cross_correlation_c(input1, w, x1, y1, input2, w, x2, y2); + double res_simd = target_func(input1, w, x1, y1, input2, w, x2, y2); - ASSERT_EQ(res_sse4, res_c); - } + if (run_times > 1) { + aom_usec_timer_start(&ref_timer); + for (j = 0; j < run_times; j++) { + av1_compute_cross_correlation_c(input1, w, x1, y1, input2, w, x2, y2); + } + 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 (j = 0; j < run_times; j++) { + target_func(input1, w, x1, y1, input2, w, x2, y2); + } + 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)); + } else { + ASSERT_EQ(res_simd, res_c); + } + } delete[] input1; delete[] input2; } -TEST_P(AV1CornerMatchTest, CheckOutput) { RunCheckOutput(); } - -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1CornerMatchTest, - ::testing::Values(make_tuple(0), make_tuple(1))); - +TEST_P(AV1CornerMatchTest, CheckOutput) { RunCheckOutput(1); } +TEST_P(AV1CornerMatchTest, DISABLED_Speed) { RunCheckOutput(100000); } + +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P( + SSE4_1, AV1CornerMatchTest, + ::testing::Values(make_tuple(0, &av1_compute_cross_correlation_sse4_1), + make_tuple(1, &av1_compute_cross_correlation_sse4_1))); +#endif + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, AV1CornerMatchTest, + ::testing::Values(make_tuple(0, &av1_compute_cross_correlation_avx2), + make_tuple(1, &av1_compute_cross_correlation_avx2))); +#endif } // namespace AV1CornerMatch } // namespace test_libaom diff --git a/media/libaom/src/test/cpu_speed_test.cc b/media/libaom/src/test/cpu_speed_test.cc index 8ea3e6965..2a164974b 100644 --- a/media/libaom/src/test/cpu_speed_test.cc +++ b/media/libaom/src/test/cpu_speed_test.cc @@ -46,7 +46,7 @@ class CpuSpeedTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); encoder->Control(AV1E_SET_TUNE_CONTENT, tune_content_); if (encoding_mode_ != ::libaom_test::kRealTime) { diff --git a/media/libaom/src/test/datarate_test.cc b/media/libaom/src/test/datarate_test.cc index 1588d3cc1..053c05571 100644 --- a/media/libaom/src/test/datarate_test.cc +++ b/media/libaom/src/test/datarate_test.cc @@ -13,19 +13,26 @@ #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" +#include "test/datarate_test.h" #include "test/encode_test_driver.h" #include "test/i420_video_source.h" #include "test/util.h" #include "test/y4m_video_source.h" #include "aom/aom_codec.h" +namespace datarate_test { namespace { +// Params: test mode, speed, aq mode and index for bitrate array. class DatarateTestLarge - : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>, - public ::libaom_test::EncoderTest { + : public ::libaom_test::CodecTestWith4Params<libaom_test::TestMode, int, + unsigned int, int>, + public DatarateTest { public: - DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {} + DatarateTestLarge() : DatarateTest(GET_PARAM(0)) { + set_cpu_used_ = GET_PARAM(2); + aq_mode_ = GET_PARAM(3); + } protected: virtual ~DatarateTestLarge() {} @@ -33,135 +40,93 @@ class DatarateTestLarge virtual void SetUp() { InitializeConfig(); SetMode(GET_PARAM(1)); - set_cpu_used_ = GET_PARAM(2); ResetModel(); } - virtual void ResetModel() { - last_pts_ = 0; - bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; - frame_number_ = 0; - tot_frame_number_ = 0; - first_drop_ = 0; - num_drops_ = 0; - // Denoiser is off by default. - denoiser_on_ = 0; - bits_total_ = 0; - denoiser_offon_test_ = 0; - denoiser_offon_period_ = -1; - } - - virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, - ::libaom_test::Encoder *encoder) { - if (video->frame() == 0) encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); - - if (denoiser_offon_test_) { - ASSERT_GT(denoiser_offon_period_, 0) - << "denoiser_offon_period_ is not positive."; - if ((video->frame() + 1) % denoiser_offon_period_ == 0) { - // Flip denoiser_on_ periodically - denoiser_on_ ^= 1; - } - } - - encoder->Control(AV1E_SET_NOISE_SENSITIVITY, denoiser_on_); - - const aom_rational_t tb = video->timebase(); - timebase_ = static_cast<double>(tb.num) / tb.den; - duration_ = 0; - } - - virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { - // Time since last timestamp = duration. - aom_codec_pts_t duration = pkt->data.frame.pts - last_pts_; - - if (duration > 1) { - // If first drop not set and we have a drop set it to this time. - if (!first_drop_) first_drop_ = last_pts_ + 1; - // Update the number of frame drops. - num_drops_ += static_cast<int>(duration - 1); - // Update counter for total number of frames (#frames input to encoder). - // Needed for setting the proper layer_id below. - tot_frame_number_ += static_cast<int>(duration - 1); - } - - // Add to the buffer the bits we'd expect from a constant bitrate server. - bits_in_buffer_model_ += static_cast<int64_t>( - duration * timebase_ * cfg_.rc_target_bitrate * 1000); - - // Buffer should not go negative. - ASSERT_GE(bits_in_buffer_model_, 0) - << "Buffer Underrun at frame " << pkt->data.frame.pts; - - const size_t frame_size_in_bits = pkt->data.frame.sz * 8; - - // Update the total encoded bits. - bits_total_ += frame_size_in_bits; - - // Update the most recent pts. - last_pts_ = pkt->data.frame.pts; - ++frame_number_; - ++tot_frame_number_; + virtual void BasicRateTargetingVBRTest() { + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.g_error_resilient = 0; + cfg_.rc_end_usage = AOM_VBR; + cfg_.g_lag_in_frames = 0; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 140); + const int bitrate_array[2] = { 400, 800 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.7) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.3) + << " The datarate for the file is greater than target by too much!"; } - virtual void EndPassHook(void) { - duration_ = (last_pts_ + 1) * timebase_; - // Effective file datarate: - effective_datarate_ = (bits_total_ / 1000.0) / duration_; + virtual void BasicRateTargetingCBRTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 1; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 140); + const int bitrate_array[2] = { 150, 550 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15) + << " The datarate for the file is greater than target by too much!"; } - aom_codec_pts_t last_pts_; - double timebase_; - int frame_number_; // Counter for number of non-dropped/encoded frames. - int tot_frame_number_; // Counter for total number of input frames. - int64_t bits_total_; - double duration_; - double effective_datarate_; - int set_cpu_used_; - int64_t bits_in_buffer_model_; - aom_codec_pts_t first_drop_; - int num_drops_; - int denoiser_on_; - int denoiser_offon_test_; - int denoiser_offon_period_; -}; - -// Check basic rate targeting for VBR mode. -TEST_P(DatarateTestLarge, BasicRateTargetingVBR) { - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_error_resilient = 0; - cfg_.rc_end_usage = AOM_VBR; - cfg_.g_lag_in_frames = 0; - - ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 140); - for (int i = 400; i <= 800; i += 400) { - cfg_.rc_target_bitrate = i; + virtual void BasicRateTargetingCBRPeriodicKeyFrameTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 1; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + // Periodic keyframe + cfg_.kf_max_dist = 50; + + ::libaom_test::I420VideoSource video("pixel_capture_w320h240.yuv", 320, 240, + 30, 1, 0, 310); + const int bitrate_array[2] = { 150, 550 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; ResetModel(); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.75) + ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85) << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.25) + ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15) << " The datarate for the file is greater than target by too much!"; } -} -// Check basic rate targeting for CBR, -TEST_P(DatarateTestLarge, BasicRateTargeting) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = AOM_CBR; - cfg_.g_lag_in_frames = 0; - - ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 140); - for (int i = 150; i < 800; i += 400) { - cfg_.rc_target_bitrate = i; + virtual void BasicRateTargetingAQModeOnOffCBRTest() { + if (GET_PARAM(4) > 0) return; + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 2; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 0; + cfg_.g_pass = AOM_RC_ONE_PASS; + cfg_.g_usage = AOM_USAGE_REALTIME; + cfg_.kf_mode = AOM_KF_DISABLED; + + ::libaom_test::I420VideoSource video("pixel_capture_w320h240.yuv", 320, 240, + 30, 1, 0, 310); + const int bitrate_array[1] = { 60 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; ResetModel(); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85) @@ -169,25 +134,23 @@ TEST_P(DatarateTestLarge, BasicRateTargeting) { ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15) << " The datarate for the file is greater than target by too much!"; } -} -// Check basic rate targeting for CBR. -TEST_P(DatarateTestLarge, BasicRateTargeting444) { - ::libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140); - - cfg_.g_profile = 1; - cfg_.g_timebase = video.timebase(); - - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = AOM_CBR; - - for (int i = 250; i < 900; i += 400) { - cfg_.rc_target_bitrate = i; + virtual void BasicRateTargeting444CBRTest() { + ::libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140); + + cfg_.g_profile = 1; + cfg_.g_timebase = video.timebase(); + + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 1; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + + const int bitrate_array[2] = { 250, 650 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; ResetModel(); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate), @@ -198,58 +161,213 @@ TEST_P(DatarateTestLarge, BasicRateTargeting444) { << " The datarate for the file missed the target!" << cfg_.rc_target_bitrate << " " << effective_datarate_; } +}; + +// Params: test mode, speed, aq mode. +class DatarateTestFrameDropLarge + : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int, + unsigned int>, + public DatarateTest { + public: + DatarateTestFrameDropLarge() : DatarateTest(GET_PARAM(0)) { + set_cpu_used_ = GET_PARAM(2); + aq_mode_ = GET_PARAM(3); + } + + protected: + virtual ~DatarateTestFrameDropLarge() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + ResetModel(); + } + + virtual void ChangingDropFrameThreshTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_undershoot_pct = 20; + cfg_.rc_undershoot_pct = 20; + cfg_.rc_dropframe_thresh = 10; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 50; + cfg_.rc_end_usage = AOM_CBR; + cfg_.rc_target_bitrate = 200; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + // TODO(marpan): Investigate datarate target failures with a smaller + // keyframe interval (128). + cfg_.kf_max_dist = 9999; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 100); + + const int kDropFrameThreshTestStep = 30; + aom_codec_pts_t last_drop = 140; + int last_num_drops = 0; + for (int i = 40; i < 100; i += kDropFrameThreshTestStep) { + cfg_.rc_dropframe_thresh = i; + ResetModel(); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.17) + << " The datarate for the file is greater than target by too much!"; + if (last_drop > 0) { + ASSERT_LE(first_drop_, last_drop) + << " The first dropped frame for drop_thresh " << i + << " > first dropped frame for drop_thresh " + << i - kDropFrameThreshTestStep; + } + ASSERT_GE(num_drops_, last_num_drops * 0.7) + << " The number of dropped frames for drop_thresh " << i + << " < number of dropped frames for drop_thresh " + << i - kDropFrameThreshTestStep; + last_drop = first_drop_; + last_num_drops = num_drops_; + } + } +}; + +// Check basic rate targeting for VBR mode. +TEST_P(DatarateTestLarge, BasicRateTargetingVBR) { + BasicRateTargetingVBRTest(); +} + +// Check basic rate targeting for CBR. +TEST_P(DatarateTestLarge, BasicRateTargetingCBR) { + BasicRateTargetingCBRTest(); +} + +// Check basic rate targeting for periodic key frame. +TEST_P(DatarateTestLarge, PeriodicKeyFrameCBR) { + BasicRateTargetingCBRPeriodicKeyFrameTest(); +} + +// Check basic rate targeting for CBR. +TEST_P(DatarateTestLarge, BasicRateTargeting444CBR) { + BasicRateTargeting444CBRTest(); } // Check that (1) the first dropped frame gets earlier and earlier // as the drop frame threshold is increased, and (2) that the total number of // frame drops does not decrease as we increase frame drop threshold. // Use a lower qp-max to force some frame drops. -TEST_P(DatarateTestLarge, ChangingDropFrameThresh) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 50; - cfg_.rc_end_usage = AOM_CBR; - cfg_.rc_target_bitrate = 200; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - // TODO(marpan): Investigate datarate target failures with a smaller keyframe - // interval (128). - cfg_.kf_max_dist = 9999; - - ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - const int kDropFrameThreshTestStep = 30; - aom_codec_pts_t last_drop = 140; - int last_num_drops = 0; - for (int i = 40; i < 100; i += kDropFrameThreshTestStep) { - cfg_.rc_dropframe_thresh = i; +TEST_P(DatarateTestFrameDropLarge, ChangingDropFrameThresh) { + ChangingDropFrameThreshTest(); +} + +TEST_P(DatarateTestLarge, BasicRateTargetingAQModeOnOffCBR) { + BasicRateTargetingAQModeOnOffCBRTest(); +} + +class DatarateTestRealtime : public DatarateTestLarge {}; + +class DatarateTestFrameDropRealtime : public DatarateTestFrameDropLarge {}; + +// Params: aq mode. +class DatarateTestSpeedChangeRealtime + : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, + unsigned int>, + public DatarateTest { + public: + DatarateTestSpeedChangeRealtime() : DatarateTest(GET_PARAM(0)) { + aq_mode_ = GET_PARAM(1); + speed_change_test_ = true; + } + + protected: + virtual ~DatarateTestSpeedChangeRealtime() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + ResetModel(); + } + + virtual void ChangingSpeedTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_undershoot_pct = 20; + cfg_.rc_undershoot_pct = 20; + cfg_.rc_dropframe_thresh = 10; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 50; + cfg_.rc_end_usage = AOM_CBR; + cfg_.rc_target_bitrate = 200; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + // TODO(marpan): Investigate datarate target failures with a smaller + // keyframe interval (128). + cfg_.kf_max_dist = 9999; + cfg_.rc_dropframe_thresh = 0; + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 100); + ResetModel(); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85) + ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.83) << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15) + ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.20) << " The datarate for the file is greater than target by too much!"; - ASSERT_LE(first_drop_, last_drop) - << " The first dropped frame for drop_thresh " << i - << " > first dropped frame for drop_thresh " - << i - kDropFrameThreshTestStep; - ASSERT_GE(num_drops_, last_num_drops * 0.85) - << " The number of dropped frames for drop_thresh " << i - << " < number of dropped frames for drop_thresh " - << i - kDropFrameThreshTestStep; - last_drop = first_drop_; - last_num_drops = num_drops_; } +}; + +// Check basic rate targeting for VBR mode. +TEST_P(DatarateTestRealtime, BasicRateTargetingVBR) { + BasicRateTargetingVBRTest(); +} + +// Check basic rate targeting for CBR. +TEST_P(DatarateTestRealtime, BasicRateTargetingCBR) { + BasicRateTargetingCBRTest(); +} + +// Check basic rate targeting for periodic key frame. +TEST_P(DatarateTestRealtime, PeriodicKeyFrameCBR) { + BasicRateTargetingCBRPeriodicKeyFrameTest(); +} + +// Check basic rate targeting for CBR. +TEST_P(DatarateTestRealtime, BasicRateTargeting444CBR) { + BasicRateTargeting444CBRTest(); +} + +// Check that (1) the first dropped frame gets earlier and earlier +// as the drop frame threshold is increased, and (2) that the total number of +// frame drops does not decrease as we increase frame drop threshold. +// Use a lower qp-max to force some frame drops. +TEST_P(DatarateTestFrameDropRealtime, ChangingDropFrameThresh) { + ChangingDropFrameThreshTest(); +} + +TEST_P(DatarateTestSpeedChangeRealtime, ChangingSpeedTest) { + ChangingSpeedTest(); } AV1_INSTANTIATE_TEST_CASE(DatarateTestLarge, - ::testing::Values(::libaom_test::kOnePassGood, - ::libaom_test::kRealTime), - ::testing::Values(2, 5)); + ::testing::Values(::libaom_test::kRealTime), + ::testing::Range(5, 7), ::testing::Values(0, 3), + ::testing::Values(0, 1)); + +AV1_INSTANTIATE_TEST_CASE(DatarateTestFrameDropLarge, + ::testing::Values(::libaom_test::kRealTime), + ::testing::Range(5, 7), ::testing::Values(0, 3)); + +AV1_INSTANTIATE_TEST_CASE(DatarateTestRealtime, + ::testing::Values(::libaom_test::kRealTime), + ::testing::Range(7, 9), ::testing::Values(0, 3), + ::testing::Values(0, 1)); + +AV1_INSTANTIATE_TEST_CASE(DatarateTestFrameDropRealtime, + ::testing::Values(::libaom_test::kRealTime), + ::testing::Range(7, 9), ::testing::Values(0, 3)); + +AV1_INSTANTIATE_TEST_CASE(DatarateTestSpeedChangeRealtime, + ::testing::Values(::libaom_test::kRealTime), + ::testing::Values(0, 3)); + } // namespace +} // namespace datarate_test diff --git a/media/libaom/src/test/datarate_test.h b/media/libaom/src/test/datarate_test.h new file mode 100644 index 000000000..3c1573119 --- /dev/null +++ b/media/libaom/src/test/datarate_test.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include "config/aom_config.h" + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" +#include "test/y4m_video_source.h" +#include "aom/aom_codec.h" + +namespace datarate_test { +namespace { +class DatarateTest : public ::libaom_test::EncoderTest { + public: + explicit DatarateTest(const ::libaom_test::CodecFactory *codec) + : EncoderTest(codec), set_cpu_used_(0), aq_mode_(0), + speed_change_test_(false) {} + + protected: + virtual ~DatarateTest() {} + + virtual void SetUp() { + InitializeConfig(); + ResetModel(); + } + + virtual void ResetModel() { + last_pts_ = 0; + bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; + frame_number_ = 0; + tot_frame_number_ = 0; + first_drop_ = 0; + num_drops_ = 0; + // Denoiser is off by default. + denoiser_on_ = 0; + bits_total_ = 0; + denoiser_offon_test_ = 0; + denoiser_offon_period_ = -1; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); + encoder->Control(AV1E_SET_AQ_MODE, aq_mode_); + encoder->Control(AV1E_SET_TILE_COLUMNS, 0); + if (cfg_.g_usage == AOM_USAGE_REALTIME) { + encoder->Control(AV1E_SET_DELTAQ_MODE, 0); + encoder->Control(AV1E_SET_ENABLE_TPL_MODEL, 0); + encoder->Control(AV1E_SET_ENABLE_CDEF, 1); + encoder->Control(AV1E_SET_COEFF_COST_UPD_FREQ, 2); + encoder->Control(AV1E_SET_MODE_COST_UPD_FREQ, 2); + encoder->Control(AV1E_SET_MV_COST_UPD_FREQ, 2); + } + } + + if (speed_change_test_) { + if (video->frame() == 0) { + encoder->Control(AOME_SET_CPUUSED, 8); + } + if (video->frame() == 30) { + encoder->Control(AOME_SET_CPUUSED, 7); + } + if (video->frame() == 60) { + encoder->Control(AOME_SET_CPUUSED, 6); + } + if (video->frame() == 90) { + encoder->Control(AOME_SET_CPUUSED, 7); + } + } + + if (denoiser_offon_test_) { + ASSERT_GT(denoiser_offon_period_, 0) + << "denoiser_offon_period_ is not positive."; + if ((video->frame() + 1) % denoiser_offon_period_ == 0) { + // Flip denoiser_on_ periodically + denoiser_on_ ^= 1; + } + } + + encoder->Control(AV1E_SET_NOISE_SENSITIVITY, denoiser_on_); + + const aom_rational_t tb = video->timebase(); + timebase_ = static_cast<double>(tb.num) / tb.den; + duration_ = 0; + } + + virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { + // Time since last timestamp = duration. + aom_codec_pts_t duration = pkt->data.frame.pts - last_pts_; + + if (duration > 1) { + // If first drop not set and we have a drop set it to this time. + if (!first_drop_) first_drop_ = last_pts_ + 1; + // Update the number of frame drops. + num_drops_ += static_cast<int>(duration - 1); + // Update counter for total number of frames (#frames input to encoder). + // Needed for setting the proper layer_id below. + tot_frame_number_ += static_cast<int>(duration - 1); + } + + // Add to the buffer the bits we'd expect from a constant bitrate server. + bits_in_buffer_model_ += static_cast<int64_t>( + duration * timebase_ * cfg_.rc_target_bitrate * 1000); + + // Buffer should not go negative. + ASSERT_GE(bits_in_buffer_model_, 0) + << "Buffer Underrun at frame " << pkt->data.frame.pts; + + const size_t frame_size_in_bits = pkt->data.frame.sz * 8; + + // Update the total encoded bits. + bits_total_ += frame_size_in_bits; + + // Update the most recent pts. + last_pts_ = pkt->data.frame.pts; + ++frame_number_; + ++tot_frame_number_; + } + + virtual void EndPassHook(void) { + duration_ = (last_pts_ + 1) * timebase_; + // Effective file datarate: + effective_datarate_ = (bits_total_ / 1000.0) / duration_; + } + + aom_codec_pts_t last_pts_; + double timebase_; + int frame_number_; // Counter for number of non-dropped/encoded frames. + int tot_frame_number_; // Counter for total number of input frames. + int64_t bits_total_; + double duration_; + double effective_datarate_; + int set_cpu_used_; + int64_t bits_in_buffer_model_; + aom_codec_pts_t first_drop_; + int num_drops_; + int denoiser_on_; + int denoiser_offon_test_; + int denoiser_offon_period_; + unsigned int aq_mode_; + bool speed_change_test_; +}; + +} // namespace +} // namespace datarate_test diff --git a/media/libaom/src/test/decode_api_test.cc b/media/libaom/src/test/decode_api_test.cc index c1beacee1..910640df7 100644 --- a/media/libaom/src/test/decode_api_test.cc +++ b/media/libaom/src/test/decode_api_test.cc @@ -33,19 +33,19 @@ TEST(DecodeAPI, InvalidParams) { EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_decode(NULL, NULL, 0, NULL)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_decode(NULL, buf, 0, NULL)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_decode(NULL, buf, NELEMENTS(buf), NULL)); + aom_codec_decode(NULL, buf, sizeof(buf), NULL)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_decode(NULL, NULL, NELEMENTS(buf), NULL)); + aom_codec_decode(NULL, NULL, sizeof(buf), NULL)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_destroy(NULL)); EXPECT_TRUE(aom_codec_error(NULL) != NULL); - for (int i = 0; i < NELEMENTS(kCodecs); ++i) { + for (const aom_codec_iface_t *iface : kCodecs) { EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_dec_init(NULL, kCodecs[i], NULL, 0)); + aom_codec_dec_init(NULL, iface, NULL, 0)); - EXPECT_EQ(AOM_CODEC_OK, aom_codec_dec_init(&dec, kCodecs[i], NULL, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_dec_init(&dec, iface, NULL, 0)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_decode(&dec, NULL, NELEMENTS(buf), NULL)); + aom_codec_decode(&dec, NULL, sizeof(buf), NULL)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_decode(&dec, buf, 0, NULL)); EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&dec)); diff --git a/media/libaom/src/test/decode_multithreaded_test.cc b/media/libaom/src/test/decode_multithreaded_test.cc index cea1d144f..92253ede8 100644 --- a/media/libaom/src/test/decode_multithreaded_test.cc +++ b/media/libaom/src/test/decode_multithreaded_test.cc @@ -76,7 +76,7 @@ class AV1DecodeMultiThreadedTest virtual void PreEncodeFrameHook(libaom_test::VideoSource *video, libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_); encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_); encoder->Control(AV1E_SET_NUM_TG, n_tile_groups_); diff --git a/media/libaom/src/test/decode_perf_test.cc b/media/libaom/src/test/decode_perf_test.cc index bb7b00032..691337cd6 100644 --- a/media/libaom/src/test/decode_perf_test.cc +++ b/media/libaom/src/test/decode_perf_test.cc @@ -10,6 +10,7 @@ */ #include <string> +#include <tuple> #include "config/aom_version.h" @@ -24,7 +25,7 @@ #include "test/util.h" #include "test/webm_video_source.h" -using ::testing::make_tuple; +using std::make_tuple; namespace { @@ -37,7 +38,7 @@ const char kNewEncodeOutputFile[] = "new_encode.ivf"; /* DecodePerfTest takes a tuple of filename + number of threads to decode with */ -typedef ::testing::tuple<const char *, unsigned> DecodePerfParam; +typedef std::tuple<const char *, unsigned> DecodePerfParam; // TODO(jimbankoski): Add actual test vectors here when available. // const DecodePerfParam kAV1DecodePerfVectors[] = {}; @@ -91,7 +92,7 @@ TEST_P(DecodePerfTest, PerfTest) { } // TODO(jimbankoski): Enabled when we have actual AV1 Decode vectors. -// INSTANTIATE_TEST_CASE_P(AV1, DecodePerfTest, +// INSTANTIATE_TEST_SUITE_P(AV1, DecodePerfTest, // ::testing::ValuesIn(kAV1DecodePerfVectors)); class AV1NewEncodeDecodePerfTest @@ -122,7 +123,7 @@ class AV1NewEncodeDecodePerfTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, speed_); encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); encoder->Control(AV1E_SET_TILE_COLUMNS, 2); diff --git a/media/libaom/src/test/decode_test_driver.h b/media/libaom/src/test/decode_test_driver.h index d13e13ea1..64722f43a 100644 --- a/media/libaom/src/test/decode_test_driver.h +++ b/media/libaom/src/test/decode_test_driver.h @@ -67,13 +67,13 @@ class Decoder { void Control(int ctrl_id, const void *arg) { InitOnce(); - const aom_codec_err_t res = aom_codec_control_(&decoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg); ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError(); } void Control(int ctrl_id, int arg, aom_codec_err_t expected_value) { InitOnce(); - const aom_codec_err_t res = aom_codec_control_(&decoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg); ASSERT_EQ(expected_value, res) << DecodeError(); } diff --git a/media/libaom/src/test/divu_small_test.cc b/media/libaom/src/test/divu_small_test.cc index 064f8ee45..f4d0846cf 100644 --- a/media/libaom/src/test/divu_small_test.cc +++ b/media/libaom/src/test/divu_small_test.cc @@ -18,7 +18,7 @@ using libaom_test::ACMRandom; -TEST(Daala, TestDIVUuptoMAX) { +TEST(DivuSmallTest, TestDIVUuptoMAX) { for (int d = 1; d <= OD_DIVU_DMAX; d++) { for (uint32_t x = 1; x <= 1000000; x++) { GTEST_ASSERT_EQ(x / d, OD_DIVU_SMALL(x, d)) @@ -28,7 +28,7 @@ TEST(Daala, TestDIVUuptoMAX) { } } -TEST(Daala, TestDIVUrandI31) { +TEST(DivuSmallTest, TestDIVUrandI31) { ACMRandom rnd(ACMRandom::DeterministicSeed()); for (int d = 1; d < OD_DIVU_DMAX; d++) { for (int i = 0; i < 1000000; i++) { diff --git a/media/libaom/src/test/dr_prediction_test.cc b/media/libaom/src/test/dr_prediction_test.cc index ff2c1de4e..e8865c02a 100644 --- a/media/libaom/src/test/dr_prediction_test.cc +++ b/media/libaom/src/test/dr_prediction_test.cc @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -8,6 +8,9 @@ * 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 <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/aom_config.h" @@ -59,7 +62,9 @@ typedef void (*Z1_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh, template <Z1_Lbd fn> void z1_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh, const uint8_t *above, const uint8_t *left, int upsample_above, - int /*upsample_left*/, int dx, int dy, int /*bd*/) { + int upsample_left, int dx, int dy, int bd) { + (void)bd; + (void)upsample_left; fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy); } @@ -69,7 +74,9 @@ typedef void (*Z2_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh, template <Z2_Lbd fn> void z2_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh, const uint8_t *above, const uint8_t *left, int upsample_above, - int upsample_left, int dx, int dy, int /*bd*/) { + int upsample_left, int dx, int dy, int bd) { + (void)bd; + (void)upsample_left; fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy); } @@ -78,9 +85,10 @@ typedef void (*Z3_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh, int upsample_left, int dx, int dy); template <Z3_Lbd fn> void z3_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh, - const uint8_t *above, const uint8_t *left, - int /*upsample_above*/, int upsample_left, int dx, int dy, - int /*bd*/) { + const uint8_t *above, const uint8_t *left, int upsample_above, + int upsample_left, int dx, int dy, int bd) { + (void)bd; + (void)upsample_above; fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy); } @@ -90,8 +98,10 @@ typedef void (*Z1_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh, template <Z1_Hbd fn> void z1_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, - int upsample_above, int /*upsample_left*/, int dx, int dy, + int upsample_above, int upsample_left, int dx, int dy, int bd) { + (void)bd; + (void)upsample_left; fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy, bd); } @@ -104,6 +114,7 @@ void z2_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_above, int upsample_left, int dx, int dy, int bd) { + (void)bd; fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy, bd); } @@ -114,8 +125,10 @@ typedef void (*Z3_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh, template <Z3_Hbd fn> void z3_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, - int /*upsample_above*/, int upsample_left, int dx, int dy, + int upsample_above, int upsample_left, int dx, int dy, int bd) { + (void)bd; + (void)upsample_above; fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy, bd); } @@ -135,7 +148,7 @@ struct DrPredFunc { template <typename Pixel, typename FuncType> class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > { protected: - static const int kMaxNumTests = 100000; + static const int kMaxNumTests = 10000; static const int kIterations = 10; static const int kDstStride = 64; static const int kDstSize = kDstStride * kDstStride; @@ -162,6 +175,7 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > { for (int i = 0; i < kDstSize; ++i) { dst_ref_[i] = 0; + dst_tst_[i] = 0; } } @@ -170,6 +184,9 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > { void Predict(bool speedtest, int tx) { const int kNumTests = speedtest ? kMaxNumTests : 1; aom_usec_timer timer; + int tst_time = 0; + + bd_ = params_.bit_depth; aom_usec_timer_start(&timer); for (int k = 0; k < kNumTests; ++k) { @@ -179,32 +196,41 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > { aom_usec_timer_mark(&timer); const int ref_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - aom_usec_timer_start(&timer); if (params_.tst_fn) { + aom_usec_timer_start(&timer); for (int k = 0; k < kNumTests; ++k) { ASM_REGISTER_STATE_CHECK(params_.tst_fn(dst_tst_, dst_stride_, bw_, bh_, above_, left_, upsample_above_, upsample_left_, dx_, dy_, bd_)); } + aom_usec_timer_mark(&timer); + tst_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); + } else { + for (int i = 0; i < kDstSize; ++i) { + dst_ref_[i] = dst_tst_[i]; + } } - aom_usec_timer_mark(&timer); - const int tst_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); OutputTimes(kNumTests, ref_time, tst_time, tx); } - void RunTest(bool speedtest, int p_angle) { - for (int i = 0; i < kBufSize; ++i) { - above_data_[i] = left_data_[i] = (1 << bd_) - 1; - } + void RunTest(bool speedtest, bool needsaturation, int p_angle) { + bd_ = params_.bit_depth; + if (needsaturation) { + for (int i = 0; i < kBufSize; ++i) { + above_data_[i] = left_data_[i] = (1 << bd_) - 1; + } + } for (int tx = 0; tx < TX_SIZES_ALL; ++tx) { if (params_.tst_fn == NULL) { for (int i = 0; i < kDstSize; ++i) { dst_tst_[i] = (1 << bd_) - 1; + dst_ref_[i] = (1 << bd_) - 1; } } else { for (int i = 0; i < kDstSize; ++i) { + dst_ref_[i] = 0; dst_tst_[i] = 0; } } @@ -282,33 +308,18 @@ class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > { class LowbdDrPredTest : public DrPredTest<uint8_t, DrPred> {}; TEST_P(LowbdDrPredTest, SaturatedValues) { - for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { - enable_upsample_ = iter & 1; - for (int angle = start_angle_; angle < stop_angle_; ++angle) { - dx_ = av1_get_dx(angle); - dy_ = av1_get_dy(angle); - if (dx_ && dy_) RunTest(false, angle); - } - } -} - -TEST_P(LowbdDrPredTest, DISABLED_Speed) { - const int angles[] = { 3, 45, 87 }; for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { - for (int i = 0; i < 3; ++i) { - const int angle = angles[i] + start_angle_; + for (int angle = start_angle_; angle < stop_angle_; ++angle) { dx_ = av1_get_dx(angle); dy_ = av1_get_dy(angle); - printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n", - enable_upsample_, angle); - if (dx_ && dy_) RunTest(true, angle); + if (dx_ && dy_) RunTest(false, true, angle); } } } -using ::testing::make_tuple; +using std::make_tuple; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, LowbdDrPredTest, ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>, NULL, AOM_BITS_8, kZ1Start), @@ -317,34 +328,20 @@ INSTANTIATE_TEST_CASE_P( DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>, NULL, AOM_BITS_8, kZ3Start))); +#if CONFIG_AV1_HIGHBITDEPTH class HighbdDrPredTest : public DrPredTest<uint16_t, DrPred_Hbd> {}; TEST_P(HighbdDrPredTest, SaturatedValues) { - for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { - enable_upsample_ = iter & 1; - for (int angle = start_angle_; angle < stop_angle_; ++angle) { - dx_ = av1_get_dx(angle); - dy_ = av1_get_dy(angle); - if (dx_ && dy_) RunTest(false, angle); - } - } -} - -TEST_P(HighbdDrPredTest, DISABLED_Speed) { - const int angles[] = { 3, 45, 87 }; for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { - for (int i = 0; i < 3; ++i) { - const int angle = angles[i] + start_angle_; + for (int angle = start_angle_; angle < stop_angle_; ++angle) { dx_ = av1_get_dx(angle); dy_ = av1_get_dy(angle); - printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n", - enable_upsample_, angle); - if (dx_ && dy_) RunTest(true, angle); + if (dx_ && dy_) RunTest(false, true, angle); } } } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, HighbdDrPredTest, ::testing::Values( DrPredFunc<DrPred_Hbd>(&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>, @@ -365,5 +362,113 @@ INSTANTIATE_TEST_CASE_P( NULL, AOM_BITS_10, kZ3Start), DrPredFunc<DrPred_Hbd>(&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>, NULL, AOM_BITS_12, kZ3Start))); +#endif // CONFIG_AV1_HIGHBITDEPTH + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, LowbdDrPredTest, + ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>, + &z1_wrapper<av1_dr_prediction_z1_avx2>, + AOM_BITS_8, kZ1Start), + DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>, + &z2_wrapper<av1_dr_prediction_z2_avx2>, + AOM_BITS_8, kZ2Start), + DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>, + &z3_wrapper<av1_dr_prediction_z3_avx2>, + AOM_BITS_8, kZ3Start))); + +TEST_P(LowbdDrPredTest, DISABLED_Speed) { + const int angles[] = { 3, 45, 87 }; + for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { + for (int i = 0; i < 3; ++i) { + const int angle = angles[i] + start_angle_; + dx_ = av1_get_dx(angle); + dy_ = av1_get_dy(angle); + printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n", + enable_upsample_, angle); + if (dx_ && dy_) RunTest(true, false, angle); + } + } +} + +TEST_P(LowbdDrPredTest, OperationCheck) { + if (params_.tst_fn == NULL) return; + // const int angles[] = { 3, 45, 81, 87, 93, 100, 145, 187, 199, 260 }; + for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { + for (int angle = start_angle_; angle < stop_angle_; ++angle) { + dx_ = av1_get_dx(angle); + dy_ = av1_get_dy(angle); + if (dx_ && dy_) RunTest(false, false, angle); + } + } +} + +#if CONFIG_AV1_HIGHBITDEPTH +INSTANTIATE_TEST_SUITE_P( + AVX2, HighbdDrPredTest, + ::testing::Values(DrPredFunc<DrPred_Hbd>( + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>, + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>, + AOM_BITS_8, kZ1Start), + DrPredFunc<DrPred_Hbd>( + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>, + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>, + AOM_BITS_10, kZ1Start), + DrPredFunc<DrPred_Hbd>( + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>, + &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>, + AOM_BITS_12, kZ1Start), + DrPredFunc<DrPred_Hbd>( + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>, + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>, + AOM_BITS_8, kZ2Start), + DrPredFunc<DrPred_Hbd>( + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>, + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>, + AOM_BITS_10, kZ2Start), + DrPredFunc<DrPred_Hbd>( + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>, + &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>, + AOM_BITS_12, kZ2Start), + DrPredFunc<DrPred_Hbd>( + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>, + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>, + AOM_BITS_8, kZ3Start), + DrPredFunc<DrPred_Hbd>( + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>, + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>, + AOM_BITS_10, kZ3Start), + DrPredFunc<DrPred_Hbd>( + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>, + &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>, + AOM_BITS_12, kZ3Start))); + +TEST_P(HighbdDrPredTest, DISABLED_Speed) { + const int angles[] = { 3, 45, 87 }; + for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { + for (int i = 0; i < 3; ++i) { + int angle = angles[i] + start_angle_; + dx_ = av1_get_dx(angle); + dy_ = av1_get_dy(angle); + printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n", + enable_upsample_, angle); + if (dx_ && dy_) RunTest(true, false, angle); + } + } +} + +TEST_P(HighbdDrPredTest, OperationCheck) { + if (params_.tst_fn == NULL) return; + // const int angles[] = { 3, 45, 81, 87, 93, 100, 145, 187, 199, 260 }; + for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) { + for (int angle = start_angle_; angle < stop_angle_; angle++) { + dx_ = av1_get_dx(angle); + dy_ = av1_get_dy(angle); + if (dx_ && dy_) RunTest(false, false, angle); + } + } +} +#endif // CONFIG_AV1_HIGHBITDEPTH +#endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/ec_test.cc b/media/libaom/src/test/ec_test.cc index e6a5ea63b..853abcbc5 100644 --- a/media/libaom/src/test/ec_test.cc +++ b/media/libaom/src/test/ec_test.cc @@ -22,7 +22,6 @@ TEST(EC_TEST, random_ec_test) { int sz; int i; int ret; - unsigned int sym; unsigned int seed; unsigned char *ptr; uint32_t ptr_sz; @@ -90,6 +89,8 @@ TEST(EC_TEST, random_ec_test) { << " (Random seed: " << seed << ").\n"; for (j = 0; j < sz; j++) { int dec_method; + unsigned int sym = data[j] + 1; // Initialize sym to an invalid value. + if (CDF_SHIFT == 0) { dec_method = 3 + (rand() & 1); } else { diff --git a/media/libaom/src/test/edge_detect_test.cc b/media/libaom/src/test/edge_detect_test.cc new file mode 100644 index 000000000..33fbbc0bb --- /dev/null +++ b/media/libaom/src/test/edge_detect_test.cc @@ -0,0 +1,409 @@ +/* + * 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 <stdbool.h> +#include <memory> +#include <tuple> +#include "aom_mem/aom_mem.h" +#include "av1/encoder/rdopt.h" +#include "test/util.h" +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +namespace { + +using std::get; +using std::tuple; + +static int get_pix(uint8_t *buf, int i, bool high_bd) { + if (high_bd) { + return *CONVERT_TO_SHORTPTR(buf + i); + } else { + return buf[i]; + } +} + +/** Get the (i, j) value from the input; if i or j is outside of the width + * or height, the nearest pixel value is returned. + */ +static int get_nearest_pix(const int *buf, int w, int h, int i, int j) { + int offset = AOMMAX(AOMMIN(i, w - 1), 0) + w * AOMMAX(AOMMIN(j, h - 1), 0); + return buf[offset]; +} + +/** Given the image data, creates a new image with padded values, so an + * 8-tap filter can be convolved. The padded value is the same as the closest + * value in the image. Returns a pointer to the start of the image in the + * padded data. Must be freed with free_pad_8tap. The output will be either + * 8-bit or 16-bit, depending on the high bit-depth (high_bd) field. + */ +static uint8_t *pad_8tap_convolve(const int *data, int w, int h, bool high_bd) { + // SIMD optimizations require the width to be a multiple of 8 and the height + // to be multiples of 4. + assert(w % 8 == 0); + assert(h % 4 == 0); + // For an 8-tap filter, we need to pad with 3 lines on top and on the left, + // and 4 lines on the right and bottom, for 7 extra lines. + const int pad_w = w + 7; + const int pad_h = h + 7; + + uint8_t *dst; + if (high_bd) { + dst = + CONVERT_TO_BYTEPTR(aom_memalign(32, sizeof(uint16_t) * pad_w * pad_h)); + } else { + dst = (uint8_t *)aom_memalign(32, sizeof(uint8_t) * pad_w * pad_h); + } + if (dst == nullptr) { + EXPECT_NE(dst, nullptr); + return nullptr; + } + + for (int j = 0; j < pad_h; ++j) { + for (int i = 0; i < pad_w; ++i) { + const int v = get_nearest_pix(data, w, h, i - 3, j - 3); + if (high_bd) { + *CONVERT_TO_SHORTPTR(dst + i + j * pad_w) = v; + } else { + dst[i + j * pad_w] = static_cast<uint8_t>(v); + } + } + } + return dst + (w + 7) * 3 + 3; +} + +static int stride_8tap(int width) { return width + 7; } + +static void free_pad_8tap(uint8_t *padded, int width, bool high_bd) { + if (high_bd) { + aom_free(CONVERT_TO_SHORTPTR(padded - (width + 7) * 3 - 3)); + } else { + aom_free(padded - (width + 7) * 3 - 3); + } +} + +struct Pad8TapConvolveDeleter { + Pad8TapConvolveDeleter(const int width, const bool high_bd) + : width(width), high_bd(high_bd) {} + void operator()(uint8_t *p) { + if (p != nullptr) { + free_pad_8tap(p, width, high_bd); + } + } + const int width; + const bool high_bd; +}; + +static uint8_t *malloc_bd(int num_entries, bool high_bd) { + const int bytes_per_entry = high_bd ? sizeof(uint16_t) : sizeof(uint8_t); + + uint8_t *buf = (uint8_t *)aom_memalign(32, bytes_per_entry * num_entries); + if (high_bd) { + return CONVERT_TO_BYTEPTR(buf); + } else { + return buf; + } +} + +static void free_bd(uint8_t *p, bool high_bd) { + if (high_bd) { + aom_free(CONVERT_TO_SHORTPTR(p)); + } else { + aom_free(p); + } +} + +struct MallocBdDeleter { + explicit MallocBdDeleter(const bool high_bd) : high_bd(high_bd) {} + void operator()(uint8_t *p) { free_bd(p, high_bd); } + const bool high_bd; +}; + +class EdgeDetectBrightnessTest : + // Parameters are (brightness, width, height, high bit depth representation, + // bit depth). + public ::testing::TestWithParam<tuple<int, int, int, bool, int> > { + protected: + void SetUp() override { + // Allocate a (width by height) array of luma values in orig_. + // padded_ will be filled by the pad() call, which adds a border around + // the orig_. The output_ array has enough space for the computation. + const int brightness = GET_PARAM(0); + const int width = GET_PARAM(1); + const int height = GET_PARAM(2); + const bool high_bd = GET_PARAM(3); + + // Create the padded image of uniform brightness. + std::unique_ptr<int[]> orig(new int[width * height]); + ASSERT_NE(orig, nullptr); + for (int i = 0; i < width * height; ++i) { + orig[i] = brightness; + } + input_ = pad_8tap_convolve(orig.get(), width, height, high_bd); + ASSERT_NE(input_, nullptr); + output_ = malloc_bd(width * height, high_bd); + ASSERT_NE(output_, nullptr); + } + + void TearDown() override { + const int width = GET_PARAM(1); + const bool high_bd = GET_PARAM(3); + free_pad_8tap(input_, width, high_bd); + free_bd(output_, high_bd); + } + + // Skip the tests where brightness exceeds the bit-depth; we run into this + // issue because of gtest's limitation on valid combinations of test + // parameters. Also skip the tests where bit depth is greater than 8, but + // high bit depth representation is not set. + bool should_skip() const { + const int brightness = GET_PARAM(0); + const int bd = GET_PARAM(4); + if (brightness >= (1 << bd)) { + return true; + } + const bool high_bd = GET_PARAM(3); + if (bd > 8 && !high_bd) { + return true; + } + return false; + } + + uint8_t *input_; + uint8_t *output_; +}; + +TEST_P(EdgeDetectBrightnessTest, BlurUniformBrightness) { + // Some combination of parameters are non-sensical, due to limitations + // of the testing framework. Ignore these. + if (should_skip()) { + return; + } + + // For varying levels of brightness, the algorithm should + // produce the same output. + const int brightness = GET_PARAM(0); + const int width = GET_PARAM(1); + const int height = GET_PARAM(2); + const bool high_bd = GET_PARAM(3); + const int bd = GET_PARAM(4); + + av1_gaussian_blur(input_, stride_8tap(width), width, height, output_, high_bd, + bd); + for (int i = 0; i < width * height; ++i) { + ASSERT_EQ(brightness, get_pix(output_, i, high_bd)); + } +} + +// No edges on a uniformly bright image. +TEST_P(EdgeDetectBrightnessTest, DetectUniformBrightness) { + if (should_skip()) { + return; + } + const int width = GET_PARAM(1); + const int height = GET_PARAM(2); + const bool high_bd = GET_PARAM(3); + const int bd = GET_PARAM(4); + + ASSERT_EQ( + 0, av1_edge_exists(input_, stride_8tap(width), width, height, high_bd, bd) + .magnitude); +} + +#if CONFIG_AV1_HIGHBITDEPTH +INSTANTIATE_TEST_SUITE_P(ImageBrightnessTests, EdgeDetectBrightnessTest, + ::testing::Combine( + // Brightness + ::testing::Values(0, 1, 2, 127, 128, 129, 254, 255, + 256, 511, 512, 1023, 1024, 2048, + 4095), + // Width + ::testing::Values(8, 16, 32), + // Height + ::testing::Values(4, 8, 12, 32), + // High bit depth representation + ::testing::Bool(), + // Bit depth + ::testing::Values(8, 10, 12))); +#else +INSTANTIATE_TEST_SUITE_P(ImageBrightnessTests, EdgeDetectBrightnessTest, + ::testing::Combine( + // Brightness + ::testing::Values(0, 1, 2, 127, 128, 129, 254, 255, + 256, 511, 512, 1023, 1024, 2048, + 4095), + // Width + ::testing::Values(8, 16, 32), + // Height + ::testing::Values(4, 8, 12, 32), + // High bit depth representation + ::testing::Values(false), + // Bit depth + ::testing::Values(8))); +#endif + +class EdgeDetectImageTest : + // Parameters are (width, height, high bit depth representation, bit depth). + public ::testing::TestWithParam<tuple<int, int, bool, int> > { + protected: + // Skip the tests where bit depth is greater than 8, but high bit depth + // representation is not set (limitation of testing framework). + bool should_skip() const { + const bool high_bd = GET_PARAM(2); + const int bd = GET_PARAM(3); + return bd > 8 && !high_bd; + } +}; + +// Generate images with black on one side and white on the other. +TEST_P(EdgeDetectImageTest, BlackWhite) { + // Some combination of parameters are non-sensical, due to limitations + // of the testing framework. Ignore these. + if (should_skip()) { + return; + } + + const int width = GET_PARAM(0); + const int height = GET_PARAM(1); + const bool high_bd = GET_PARAM(2); + const int bd = GET_PARAM(3); + + const int white = (1 << bd) - 1; + std::unique_ptr<int[]> orig(new int[width * height]); + for (int j = 0; j < height; ++j) { + for (int i = 0; i < width; ++i) { + if (i < width / 2) { + orig[i + j * width] = 0; + } else { + orig[i + j * width] = white; + } + } + } + + std::unique_ptr<uint8_t[], Pad8TapConvolveDeleter> padded( + pad_8tap_convolve(orig.get(), width, height, high_bd), + Pad8TapConvolveDeleter(width, high_bd)); + ASSERT_NE(padded, nullptr); + // Value should be between 556 and 560. + ASSERT_LE(556, av1_edge_exists(padded.get(), stride_8tap(width), width, + height, high_bd, bd) + .magnitude); + ASSERT_GE(560, av1_edge_exists(padded.get(), stride_8tap(width), width, + height, high_bd, bd) + .magnitude); +} + +// Hardcoded blur tests. +static const int luma[32] = { 241, 147, 7, 90, 184, 103, 28, 186, + 2, 248, 49, 242, 114, 146, 127, 22, + 121, 228, 167, 108, 158, 174, 41, 168, + 214, 99, 184, 109, 114, 247, 117, 119 }; +static const uint8_t expected[] = { 161, 138, 119, 118, 123, 118, 113, 122, + 143, 140, 134, 133, 134, 126, 116, 114, + 147, 149, 145, 142, 143, 138, 126, 118, + 164, 156, 148, 144, 148, 148, 138, 126 }; + +static void hardcoded_blur_test_aux(const bool high_bd) { + const int w = 8; + const int h = 4; + for (int bd = 8; bd <= 12; bd += 2) { + // Skip the tests where bit depth is greater than 8, but high bit depth + // representation is not set. + if (bd > 8 && !high_bd) { + break; + } + std::unique_ptr<uint8_t[], MallocBdDeleter> output( + malloc_bd(w * h, high_bd), MallocBdDeleter(high_bd)); + ASSERT_NE(output, nullptr); + std::unique_ptr<uint8_t[], Pad8TapConvolveDeleter> padded( + pad_8tap_convolve(luma, w, h, high_bd), + Pad8TapConvolveDeleter(w, high_bd)); + ASSERT_NE(padded, nullptr); + av1_gaussian_blur(padded.get(), stride_8tap(w), w, h, output.get(), high_bd, + bd); + for (int i = 0; i < w * h; ++i) { + ASSERT_EQ(expected[i], get_pix(output.get(), i, high_bd)); + } + + // If we multiply the inputs by a constant factor, the output should not + // vary more than 0.5 * factor. + for (int c = 2; c < (1 << (bd - 8)); ++c) { + int scaled_luma[32]; + for (int i = 0; i < 32; ++i) { + scaled_luma[i] = luma[i] * c; + } + padded.reset(pad_8tap_convolve(scaled_luma, w, h, high_bd)); + ASSERT_NE(padded, nullptr); + av1_gaussian_blur(padded.get(), stride_8tap(w), w, h, output.get(), + high_bd, bd); + for (int i = 0; i < w * h; ++i) { + ASSERT_GE(c / 2, + abs(expected[i] * c - get_pix(output.get(), i, high_bd))); + } + } + } +} + +TEST(EdgeDetectImageTest, HardcodedBlurTest) { + hardcoded_blur_test_aux(false); +#if CONFIG_AV1_HIGHBITDEPTH + hardcoded_blur_test_aux(true); +#endif +} + +TEST(EdgeDetectImageTest, SobelTest) { + // Randomly generated 3x3. Compute Sobel for middle value. + const uint8_t buf[9] = { 241, 147, 7, 90, 184, 103, 28, 186, 2 }; + const int stride = 3; + bool high_bd = false; + sobel_xy result = av1_sobel(buf, stride, 1, 1, high_bd); + ASSERT_EQ(234, result.x); + ASSERT_EQ(140, result.y); + +#if CONFIG_AV1_HIGHBITDEPTH + // Verify it works for 8-bit values in a high bit-depth buffer. + const uint16_t buf8_16[9] = { 241, 147, 7, 90, 184, 103, 28, 186, 2 }; + high_bd = true; + result = av1_sobel(CONVERT_TO_BYTEPTR(buf8_16), stride, 1, 1, high_bd); + ASSERT_EQ(234, result.x); + ASSERT_EQ(140, result.y); + + // Verify it works for high bit-depth values as well. + const uint16_t buf16[9] = { 241, 147, 7, 90, 184, 2003, 1028, 186, 2 }; + result = av1_sobel(CONVERT_TO_BYTEPTR(buf16), stride, 1, 1, high_bd); + ASSERT_EQ(-2566, result.x); + ASSERT_EQ(-860, result.y); +#endif +} + +#if CONFIG_AV1_HIGHBITDEPTH +INSTANTIATE_TEST_SUITE_P(EdgeDetectImages, EdgeDetectImageTest, + ::testing::Combine( + // Width + ::testing::Values(8, 16, 32), + // Height + ::testing::Values(4, 8, 12, 32), + // High bit depth representation + ::testing::Bool(), + // Bit depth + ::testing::Values(8, 10, 12))); +#else +INSTANTIATE_TEST_SUITE_P(EdgeDetectImages, EdgeDetectImageTest, + ::testing::Combine( + // Width + ::testing::Values(8, 16, 32), + // Height + ::testing::Values(4, 8, 12, 32), + // High bit depth representation + ::testing::Values(false), + // Bit depth + ::testing::Values(8))); +#endif +} // namespace diff --git a/media/libaom/src/test/encode_api_test.cc b/media/libaom/src/test/encode_api_test.cc index c26f5720f..25bdb5c3f 100644 --- a/media/libaom/src/test/encode_api_test.cc +++ b/media/libaom/src/test/encode_api_test.cc @@ -43,17 +43,17 @@ TEST(EncodeAPI, InvalidParams) { aom_codec_enc_config_default(NULL, &cfg, 0)); EXPECT_TRUE(aom_codec_error(NULL) != NULL); - for (int i = 0; i < NELEMENTS(kCodecs); ++i) { - SCOPED_TRACE(aom_codec_iface_name(kCodecs[i])); + for (const aom_codec_iface_t *iface : kCodecs) { + SCOPED_TRACE(aom_codec_iface_name(iface)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_enc_init(NULL, kCodecs[i], NULL, 0)); + aom_codec_enc_init(NULL, iface, NULL, 0)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_enc_init(&enc, kCodecs[i], NULL, 0)); + aom_codec_enc_init(&enc, iface, NULL, 0)); EXPECT_EQ(AOM_CODEC_INVALID_PARAM, - aom_codec_enc_config_default(kCodecs[i], &cfg, 1)); + aom_codec_enc_config_default(iface, &cfg, 2)); - EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(kCodecs[i], &cfg, 0)); - EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, kCodecs[i], &cfg, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0)); EXPECT_EQ(NULL, aom_codec_get_global_headers(NULL)); diff --git a/media/libaom/src/test/encode_perf_test.cc b/media/libaom/src/test/encode_perf_test.cc index fe649b153..390a6e0e6 100644 --- a/media/libaom/src/test/encode_perf_test.cc +++ b/media/libaom/src/test/encode_perf_test.cc @@ -123,32 +123,29 @@ class AV1EncodePerfTest }; TEST_P(AV1EncodePerfTest, PerfTest) { - for (size_t i = 0; i < NELEMENTS(kAV1EncodePerfTestVectors); ++i) { - for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) { - for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) { - if (kAV1EncodePerfTestVectors[i].width < 512 && - kEncodePerfTestThreads[k] > 1) + for (const EncodePerfTestVideo &test_video : kAV1EncodePerfTestVectors) { + for (int speed : kEncodePerfTestSpeeds) { + for (int threads : kEncodePerfTestThreads) { + if (test_video.width < 512 && threads > 1) continue; - else if (kAV1EncodePerfTestVectors[i].width < 1024 && - kEncodePerfTestThreads[k] > 2) + else if (test_video.width < 1024 && threads > 2) continue; - set_threads(kEncodePerfTestThreads[k]); + set_threads(threads); SetUp(); const aom_rational timebase = { 33333333, 1000000000 }; cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = kAV1EncodePerfTestVectors[i].bitrate; + cfg_.rc_target_bitrate = test_video.bitrate; init_flags_ = AOM_CODEC_USE_PSNR; - const unsigned frames = kAV1EncodePerfTestVectors[i].frames; - const char *video_name = kAV1EncodePerfTestVectors[i].name; - libaom_test::I420VideoSource video( - video_name, kAV1EncodePerfTestVectors[i].width, - kAV1EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0, - kAV1EncodePerfTestVectors[i].frames); - set_speed(kEncodePerfTestSpeeds[j]); + const unsigned frames = test_video.frames; + const char *video_name = test_video.name; + libaom_test::I420VideoSource video(video_name, test_video.width, + test_video.height, timebase.den, + timebase.num, 0, test_video.frames); + set_speed(speed); aom_usec_timer t; aom_usec_timer_start(&t); @@ -160,10 +157,9 @@ TEST_P(AV1EncodePerfTest, PerfTest) { const double fps = frames / elapsed_secs; const double minimum_psnr = min_psnr(); std::string display_name(video_name); - if (kEncodePerfTestThreads[k] > 1) { + if (threads > 1) { char thread_count[32]; - snprintf(thread_count, sizeof(thread_count), "_t-%d", - kEncodePerfTestThreads[k]); + snprintf(thread_count, sizeof(thread_count), "_t-%d", threads); display_name += thread_count; } @@ -175,8 +171,8 @@ TEST_P(AV1EncodePerfTest, PerfTest) { printf("\t\"totalFrames\" : %u,\n", frames); printf("\t\"framesPerSecond\" : %f,\n", fps); printf("\t\"minPsnr\" : %f,\n", minimum_psnr); - printf("\t\"speed\" : %d,\n", kEncodePerfTestSpeeds[j]); - printf("\t\"threads\" : %d\n", kEncodePerfTestThreads[k]); + printf("\t\"speed\" : %d,\n", speed); + printf("\t\"threads\" : %d\n", threads); printf("}\n"); } } diff --git a/media/libaom/src/test/encode_test_driver.cc b/media/libaom/src/test/encode_test_driver.cc index f3d61dc36..01f8d501a 100644 --- a/media/libaom/src/test/encode_test_driver.cc +++ b/media/libaom/src/test/encode_test_driver.cc @@ -9,6 +9,7 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> #include <string> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -91,7 +92,11 @@ void EncoderTest::SetMode(TestMode mode) { switch (mode) { case kOnePassGood: case kTwoPassGood: break; - case kRealTime: cfg_.g_lag_in_frames = 0; break; + case kRealTime: { + cfg_.g_lag_in_frames = 0; + cfg_.g_usage = AOM_USAGE_REALTIME; + break; + } default: ASSERT_TRUE(false) << "Unexpected mode " << mode; } mode_ = mode; @@ -192,7 +197,7 @@ void EncoderTest::RunLoop(VideoSource *video) { cfg_.g_pass = AOM_RC_LAST_PASS; BeginPassHook(pass); - testing::internal::scoped_ptr<Encoder> encoder( + std::unique_ptr<Encoder> encoder( codec_->CreateEncoder(cfg_, init_flags_, &stats_)); ASSERT_TRUE(encoder.get() != NULL); @@ -205,7 +210,7 @@ void EncoderTest::RunLoop(VideoSource *video) { ASSERT_FALSE(::testing::Test::HasFatalFailure()); - testing::internal::scoped_ptr<Decoder> decoder( + std::unique_ptr<Decoder> decoder( codec_->CreateDecoder(dec_cfg, 0 /* flags */)); #if CONFIG_AV1_DECODER if (decoder->IsAV1()) { @@ -218,65 +223,69 @@ void EncoderTest::RunLoop(VideoSource *video) { } #endif + number_spatial_layers_ = GetNumSpatialLayers(); + bool again; for (again = true; again; video->Next()) { again = (video->img() != NULL); - PreEncodeFrameHook(video); - PreEncodeFrameHook(video, encoder.get()); - encoder->EncodeFrame(video, frame_flags_); - - CxDataIterator iter = encoder->GetCxData(); - - bool has_cxdata = false; - bool has_dxdata = false; - while (const aom_codec_cx_pkt_t *pkt = iter.Next()) { - pkt = MutateEncoderOutputHook(pkt); - again = true; - switch (pkt->kind) { - case AOM_CODEC_CX_FRAME_PKT: - has_cxdata = true; - if (decoder.get() != NULL && DoDecode()) { - aom_codec_err_t res_dec; - if (DoDecodeInvisible()) { - res_dec = decoder->DecodeFrame( - (const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz); - } else { - res_dec = decoder->DecodeFrame( - (const uint8_t *)pkt->data.frame.buf + - (pkt->data.frame.sz - pkt->data.frame.vis_frame_size), - pkt->data.frame.vis_frame_size); + for (int sl = 0; sl < number_spatial_layers_; sl++) { + PreEncodeFrameHook(video); + PreEncodeFrameHook(video, encoder.get()); + encoder->EncodeFrame(video, frame_flags_); + + CxDataIterator iter = encoder->GetCxData(); + + bool has_cxdata = false; + bool has_dxdata = false; + while (const aom_codec_cx_pkt_t *pkt = iter.Next()) { + pkt = MutateEncoderOutputHook(pkt); + again = true; + switch (pkt->kind) { + case AOM_CODEC_CX_FRAME_PKT: + has_cxdata = true; + if (decoder.get() != NULL && DoDecode()) { + aom_codec_err_t res_dec; + if (DoDecodeInvisible()) { + res_dec = decoder->DecodeFrame( + (const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz); + } else { + res_dec = decoder->DecodeFrame( + (const uint8_t *)pkt->data.frame.buf + + (pkt->data.frame.sz - pkt->data.frame.vis_frame_size), + pkt->data.frame.vis_frame_size); + } + + if (!HandleDecodeResult(res_dec, decoder.get())) break; + + has_dxdata = true; } + ASSERT_GE(pkt->data.frame.pts, last_pts_); + if (sl == number_spatial_layers_) last_pts_ = pkt->data.frame.pts; + FramePktHook(pkt); + break; - if (!HandleDecodeResult(res_dec, decoder.get())) break; - - has_dxdata = true; - } - ASSERT_GE(pkt->data.frame.pts, last_pts_); - last_pts_ = pkt->data.frame.pts; - FramePktHook(pkt); - break; - - case AOM_CODEC_PSNR_PKT: PSNRPktHook(pkt); break; + case AOM_CODEC_PSNR_PKT: PSNRPktHook(pkt); break; - default: break; + default: break; + } } - } - if (has_dxdata && has_cxdata) { - const aom_image_t *img_enc = encoder->GetPreviewFrame(); - DxDataIterator dec_iter = decoder->GetDxData(); - const aom_image_t *img_dec = dec_iter.Next(); - if (img_enc && img_dec) { - const bool res = - compare_img(img_enc, img_dec, NULL, NULL, NULL, NULL, NULL); - if (!res) { // Mismatch - MismatchHook(img_enc, img_dec); + if (has_dxdata && has_cxdata) { + const aom_image_t *img_enc = encoder->GetPreviewFrame(); + DxDataIterator dec_iter = decoder->GetDxData(); + const aom_image_t *img_dec = dec_iter.Next(); + if (img_enc && img_dec) { + const bool res = + compare_img(img_enc, img_dec, NULL, NULL, NULL, NULL, NULL); + if (!res) { // Mismatch + MismatchHook(img_enc, img_dec); + } } + if (img_dec) DecompressedFrameHook(*img_dec, video->pts()); } - if (img_dec) DecompressedFrameHook(*img_dec, video->pts()); - } - if (!Continue()) break; + if (!Continue()) break; + } // Loop over spatial layers } EndPassHook(); diff --git a/media/libaom/src/test/encode_test_driver.h b/media/libaom/src/test/encode_test_driver.h index 4f3f855cf..6319a5220 100644 --- a/media/libaom/src/test/encode_test_driver.h +++ b/media/libaom/src/test/encode_test_driver.h @@ -82,7 +82,7 @@ class TwopassStatsStore { // level of abstraction will be fleshed out as more tests are written. class Encoder { public: - Encoder(aom_codec_enc_cfg_t cfg, const uint32_t init_flags, + Encoder(aom_codec_enc_cfg_t cfg, const aom_codec_flags_t init_flags, TwopassStatsStore *stats) : cfg_(cfg), init_flags_(init_flags), stats_(stats) { memset(&encoder_, 0, sizeof(encoder_)); @@ -105,23 +105,38 @@ class Encoder { void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); } void Control(int ctrl_id, int arg) { - const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); } void Control(int ctrl_id, int *arg) { - const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); } void Control(int ctrl_id, struct aom_scaling_mode *arg) { - const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); + ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); + } + + void Control(int ctrl_id, struct aom_svc_layer_id *arg) { + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); + ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); + } + + void Control(int ctrl_id, struct aom_svc_ref_frame_config *arg) { + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); + ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); + } + + void Control(int ctrl_id, struct aom_svc_params *arg) { + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); } #if CONFIG_AV1_ENCODER void Control(int ctrl_id, aom_active_map_t *arg) { - const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg); + const aom_codec_err_t res = aom_codec_control(&encoder_, ctrl_id, arg); ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); } #endif @@ -149,7 +164,7 @@ class Encoder { aom_codec_ctx_t encoder_; aom_codec_enc_cfg_t cfg_; - unsigned long init_flags_; + aom_codec_flags_t init_flags_; TwopassStatsStore *stats_; }; @@ -164,7 +179,7 @@ class EncoderTest { protected: explicit EncoderTest(const CodecFactory *codec) : codec_(codec), abort_(false), init_flags_(0), frame_flags_(0), - last_pts_(0), mode_(kRealTime) { + last_pts_(0), mode_(kRealTime), number_spatial_layers_(1) { // Default to 1 thread. cfg_.g_threads = 1; } @@ -178,9 +193,7 @@ class EncoderTest { void SetMode(TestMode mode); // Set encoder flag. - void set_init_flags(unsigned long flag) { // NOLINT(runtime/int) - init_flags_ = flag; - } + void set_init_flags(aom_codec_flags_t flag) { init_flags_ = flag; } // Main loop virtual void RunLoop(VideoSource *video); @@ -227,6 +240,8 @@ class EncoderTest { return AOM_CODEC_OK == res_dec; } + virtual int GetNumSpatialLayers() { return 1; } + // Hook that can modify the encoder's output data virtual const aom_codec_cx_pkt_t *MutateEncoderOutputHook( const aom_codec_cx_pkt_t *pkt) { @@ -238,10 +253,11 @@ class EncoderTest { aom_codec_enc_cfg_t cfg_; unsigned int passes_; TwopassStatsStore stats_; - unsigned long init_flags_; + aom_codec_flags_t init_flags_; unsigned long frame_flags_; aom_codec_pts_t last_pts_; TestMode mode_; + int number_spatial_layers_; }; } // namespace libaom_test diff --git a/media/libaom/src/test/encodetxb_test.cc b/media/libaom/src/test/encodetxb_test.cc index 11cc07368..385d3f1a8 100644 --- a/media/libaom/src/test/encodetxb_test.cc +++ b/media/libaom/src/test/encodetxb_test.cc @@ -12,6 +12,7 @@ #include <stdint.h> #include <stdio.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -20,8 +21,8 @@ #include "aom_ports/aom_timer.h" #include "aom_ports/mem.h" +#include "av1/common/av1_common_int.h" #include "av1/common/idct.h" -#include "av1/common/onyxc_int.h" #include "av1/common/scan.h" #include "av1/common/txb_common.h" #include "test/acm_random.h" @@ -138,7 +139,7 @@ class EncodeTxbTest : public ::testing::TestWithParam<GetNzMapContextsFunc> { for (int c = 0; c < eob; ++c) { levels_[get_padded_idx(scan[c], bwl)] = static_cast<uint8_t>(clamp(rnd_.Rand8(), 0, INT8_MAX)); - coeff_contexts_[scan[c]] = rnd_.Rand16() >> 1; + coeff_contexts_[scan[c]] = static_cast<int8_t>(rnd_.Rand16() >> 1); } memcpy(coeff_contexts_ref_, coeff_contexts_, @@ -177,15 +178,15 @@ TEST_P(EncodeTxbTest, DISABLED_SpeedTestGetNzMapContexts) { } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, EncodeTxbTest, - ::testing::Values(av1_get_nz_map_contexts_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, EncodeTxbTest, + ::testing::Values(av1_get_nz_map_contexts_sse2)); #endif 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; +typedef std::tuple<av1_txb_init_levels_func, int> TxbInitLevelParam; class EncodeTxbInitLevelTest : public ::testing::TestWithParam<TxbInitLevelParam> { @@ -248,13 +249,13 @@ TEST_P(EncodeTxbInitLevelTest, DISABLED_Speed) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_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( +INSTANTIATE_TEST_SUITE_P( AVX2, EncodeTxbInitLevelTest, ::testing::Combine(::testing::Values(&av1_txb_init_levels_avx2), ::testing::Range(0, static_cast<int>(TX_SIZES_ALL), 1))); diff --git a/media/libaom/src/test/end_to_end_test.cc b/media/libaom/src/test/end_to_end_test.cc index 1ac0ae931..162a7c743 100644 --- a/media/libaom/src/test/end_to_end_test.cc +++ b/media/libaom/src/test/end_to_end_test.cc @@ -9,6 +9,9 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> +#include <ostream> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -51,16 +54,25 @@ typedef struct { unsigned int profile; } TestVideoParam; +std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) { + return os << "TestVideoParam { filename:" << test_arg.filename + << " input_bit_depth:" << test_arg.input_bit_depth + << " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth + << " profile:" << test_arg.profile << " }"; +} + const TestVideoParam kTestVectors[] = { { "park_joy_90p_8_420.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, { "park_joy_90p_8_422.y4m", 8, AOM_IMG_FMT_I422, AOM_BITS_8, 2 }, { "park_joy_90p_8_444.y4m", 8, AOM_IMG_FMT_I444, AOM_BITS_8, 1 }, +#if CONFIG_AV1_HIGHBITDEPTH { "park_joy_90p_10_420.y4m", 10, AOM_IMG_FMT_I42016, AOM_BITS_10, 0 }, { "park_joy_90p_10_422.y4m", 10, AOM_IMG_FMT_I42216, AOM_BITS_10, 2 }, { "park_joy_90p_10_444.y4m", 10, AOM_IMG_FMT_I44416, AOM_BITS_10, 1 }, { "park_joy_90p_12_420.y4m", 12, AOM_IMG_FMT_I42016, AOM_BITS_12, 2 }, { "park_joy_90p_12_422.y4m", 12, AOM_IMG_FMT_I42216, AOM_BITS_12, 2 }, { "park_joy_90p_12_444.y4m", 12, AOM_IMG_FMT_I44416, AOM_BITS_12, 2 }, +#endif }; // Encoding modes tested @@ -120,7 +132,7 @@ class EndToEndTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); encoder->Control(AV1E_SET_TILE_COLUMNS, 4); encoder->Control(AOME_SET_CPUUSED, cpu_used_); @@ -155,7 +167,7 @@ class EndToEndTest init_flags_ = AOM_CODEC_USE_PSNR; if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; - testing::internal::scoped_ptr<libaom_test::VideoSource> video; + std::unique_ptr<libaom_test::VideoSource> video; if (is_extension_y4m(test_video_param_.filename)) { video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, kFrames)); diff --git a/media/libaom/src/test/error_block_test.cc b/media/libaom/src/test/error_block_test.cc index 353947c3d..462661e61 100644 --- a/media/libaom/src/test/error_block_test.cc +++ b/media/libaom/src/test/error_block_test.cc @@ -12,6 +12,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -35,9 +36,21 @@ typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz, int bps); -typedef ::testing::tuple<ErrorBlockFunc, ErrorBlockFunc, aom_bit_depth_t> +typedef int64_t (*ErrorBlockFunc8Bits)(const tran_low_t *coeff, + const tran_low_t *dqcoeff, + intptr_t block_size, int64_t *ssz); + +typedef std::tuple<ErrorBlockFunc, ErrorBlockFunc, aom_bit_depth_t> ErrorBlockParam; +template <ErrorBlockFunc8Bits fn> +int64_t BlockError8BitWrapper(const tran_low_t *coeff, + const tran_low_t *dqcoeff, intptr_t block_size, + int64_t *ssz, int bps) { + EXPECT_EQ(bps, 8); + return fn(coeff, dqcoeff, block_size, ssz); +} + class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> { public: virtual ~ErrorBlockTest() {} @@ -156,16 +169,121 @@ TEST_P(ErrorBlockTest, ExtremeValues) { << "First failed at test case " << first_failure; } -#if (HAVE_SSE2 || HAVE_AVX) -using ::testing::make_tuple; - -INSTANTIATE_TEST_CASE_P( - SSE2, ErrorBlockTest, - ::testing::Values(make_tuple(&av1_highbd_block_error_sse2, - &av1_highbd_block_error_c, AOM_BITS_10), - make_tuple(&av1_highbd_block_error_sse2, - &av1_highbd_block_error_c, AOM_BITS_12), - make_tuple(&av1_highbd_block_error_sse2, - &av1_highbd_block_error_c, AOM_BITS_8))); +TEST_P(ErrorBlockTest, DISABLED_Speed) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + DECLARE_ALIGNED(16, tran_low_t, coeff[4096]); + DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]); + intptr_t block_size; + int64_t ssz; + int num_iters = 100000; + int64_t ref_ssz; + int k; + const int msb = bit_depth_ + 8 - 1; + for (int i = 0; i < 9; ++i) { + block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64 + for (k = 0; k < 9; k++) { + for (int j = 0; j < block_size; j++) { + if (k < 5) { + if (rnd(2)) { + // Positive number + coeff[j] = rnd(1 << msb); + dqcoeff[j] = rnd(1 << msb); + } else { + // Negative number + coeff[j] = -rnd(1 << msb); + dqcoeff[j] = -rnd(1 << msb); + } + } else { + if (rnd(2)) { + // Positive number + coeff[j] = rnd(1 << 14); + dqcoeff[j] = rnd(1 << 14); + } else { + // Negative number + coeff[j] = -rnd(1 << 14); + dqcoeff[j] = -rnd(1 << 14); + } + } + } + aom_usec_timer ref_timer, test_timer; + + aom_usec_timer_start(&ref_timer); + for (int i = 0; i < num_iters; ++i) { + ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_); + } + aom_usec_timer_mark(&ref_timer); + const int elapsed_time_c = + static_cast<int>(aom_usec_timer_elapsed(&ref_timer)); + + aom_usec_timer_start(&test_timer); + for (int i = 0; i < num_iters; ++i) { + error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_); + } + aom_usec_timer_mark(&test_timer); + + const int elapsed_time_simd = + static_cast<int>(aom_usec_timer_elapsed(&test_timer)); + + printf( + " c_time=%d \t simd_time=%d \t " + "gain=%d \n", + elapsed_time_c, elapsed_time_simd, + (elapsed_time_c / elapsed_time_simd)); + } + } +} + +using std::make_tuple; + +#if (HAVE_SSE2) +const ErrorBlockParam kErrorBlockTestParamsSse2[] = { +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(&av1_highbd_block_error_sse2, &av1_highbd_block_error_c, + AOM_BITS_10), + make_tuple(&av1_highbd_block_error_sse2, &av1_highbd_block_error_c, + AOM_BITS_12), + make_tuple(&av1_highbd_block_error_sse2, &av1_highbd_block_error_c, + AOM_BITS_8), +#endif + make_tuple(&BlockError8BitWrapper<av1_block_error_sse2>, + &BlockError8BitWrapper<av1_block_error_c>, AOM_BITS_8) +}; + +INSTANTIATE_TEST_SUITE_P(SSE2, ErrorBlockTest, + ::testing::ValuesIn(kErrorBlockTestParamsSse2)); #endif // HAVE_SSE2 + +#if (HAVE_AVX2) +const ErrorBlockParam kErrorBlockTestParamsAvx2[] = { +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(&av1_highbd_block_error_avx2, &av1_highbd_block_error_c, + AOM_BITS_10), + make_tuple(&av1_highbd_block_error_avx2, &av1_highbd_block_error_c, + AOM_BITS_12), + make_tuple(&av1_highbd_block_error_avx2, &av1_highbd_block_error_c, + AOM_BITS_8), +#endif + make_tuple(&BlockError8BitWrapper<av1_block_error_avx2>, + &BlockError8BitWrapper<av1_block_error_c>, AOM_BITS_8) +}; + +INSTANTIATE_TEST_SUITE_P(AVX2, ErrorBlockTest, + ::testing::ValuesIn(kErrorBlockTestParamsAvx2)); +#endif // HAVE_AVX2 + +#if (HAVE_MSA) +INSTANTIATE_TEST_SUITE_P( + MSA, ErrorBlockTest, + ::testing::Values(make_tuple(&BlockError8BitWrapper<av1_block_error_msa>, + &BlockError8BitWrapper<av1_block_error_c>, + AOM_BITS_8))); +#endif // HAVE_MSA + +#if (HAVE_NEON) +INSTANTIATE_TEST_SUITE_P( + NEON, ErrorBlockTest, + ::testing::Values(make_tuple(&BlockError8BitWrapper<av1_block_error_neon>, + &BlockError8BitWrapper<av1_block_error_c>, + AOM_BITS_8))); +#endif // HAVE_NEON } // namespace diff --git a/media/libaom/src/test/error_resilience_test.cc b/media/libaom/src/test/error_resilience_test.cc index 13ac0bf93..1d52bb24a 100644 --- a/media/libaom/src/test/error_resilience_test.cc +++ b/media/libaom/src/test/error_resilience_test.cc @@ -145,6 +145,27 @@ class ErrorResilienceTestLarge } } + virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { + // Check that the encode frame flags are correctly reflected + // in the output frame flags. + const int encode_flags = pkt->data.frame.flags >> 16; + if ((encode_flags & (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | + AOM_EFLAG_NO_UPD_ARF)) == + (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF)) { + ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_DROPPABLE, + static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_DROPPABLE)); + } + if (encode_flags & AOM_EFLAG_SET_S_FRAME) { + ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_SWITCH, + static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_SWITCH)); + } + if (encode_flags & AOM_EFLAG_ERROR_RESILIENT) { + ASSERT_EQ( + pkt->data.frame.flags & AOM_FRAME_IS_ERROR_RESILIENT, + static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_ERROR_RESILIENT)); + } + } + double GetAveragePsnr() const { if (nframes_) return psnr_ / nframes_; return 0.0; @@ -342,7 +363,7 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) { // Set an arbitrary set of error frames same as droppable frames. unsigned int num_droppable_frames = 3; - unsigned int droppable_frame_list[] = { 5, 10, 13 }; + unsigned int droppable_frame_list[] = { 5, 11, 13 }; SetDroppableFrames(num_droppable_frames, droppable_frame_list); SetErrorFrames(num_droppable_frames, droppable_frame_list); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); diff --git a/media/libaom/src/test/ethread_test.cc b/media/libaom/src/test/ethread_test.cc index d9ac78282..306cc2f3a 100644 --- a/media/libaom/src/test/ethread_test.cc +++ b/media/libaom/src/test/ethread_test.cc @@ -20,14 +20,15 @@ namespace { class AVxEncoderThreadTest - : public ::libaom_test::CodecTestWith4Params<libaom_test::TestMode, int, - int, int>, + : public ::libaom_test::CodecTestWith5Params<libaom_test::TestMode, int, + int, int, int>, public ::libaom_test::EncoderTest { protected: AVxEncoderThreadTest() : EncoderTest(GET_PARAM(0)), encoder_initialized_(false), encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)), - tile_cols_(GET_PARAM(3)), tile_rows_(GET_PARAM(4)) { + tile_cols_(GET_PARAM(3)), tile_rows_(GET_PARAM(4)), + row_mt_(GET_PARAM(5)) { init_flags_ = AOM_CODEC_USE_PSNR; aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); cfg.w = 1280; @@ -119,87 +120,87 @@ class AVxEncoderThreadTest "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)); - std::vector<size_t> single_thr_size_enc; - std::vector<std::string> single_thr_md5_enc; - std::vector<std::string> single_thr_md5_dec; - single_thr_size_enc = size_enc_; - single_thr_md5_enc = md5_enc_; - single_thr_md5_dec = md5_dec_; - size_enc_.clear(); - md5_enc_.clear(); - md5_dec_.clear(); + if (row_mt_ == 0) { + // Encode using single thread. + cfg_.g_threads = 1; + init_flags_ = AOM_CODEC_USE_PSNR; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + std::vector<size_t> single_thr_size_enc; + std::vector<std::string> single_thr_md5_enc; + std::vector<std::string> single_thr_md5_dec; + single_thr_size_enc = size_enc_; + single_thr_md5_enc = md5_enc_; + single_thr_md5_dec = md5_dec_; + size_enc_.clear(); + md5_enc_.clear(); + md5_dec_.clear(); - // Encode using multiple threads. - cfg_.g_threads = 4; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - std::vector<size_t> multi_thr_size_enc; - std::vector<std::string> multi_thr_md5_enc; - std::vector<std::string> multi_thr_md5_dec; - multi_thr_size_enc = size_enc_; - multi_thr_md5_enc = md5_enc_; - multi_thr_md5_dec = md5_dec_; - size_enc_.clear(); - md5_enc_.clear(); - md5_dec_.clear(); + // Encode using multiple threads. + cfg_.g_threads = 4; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + std::vector<size_t> multi_thr_size_enc; + std::vector<std::string> multi_thr_md5_enc; + std::vector<std::string> multi_thr_md5_dec; + multi_thr_size_enc = size_enc_; + multi_thr_md5_enc = md5_enc_; + multi_thr_md5_dec = md5_dec_; + size_enc_.clear(); + md5_enc_.clear(); + md5_dec_.clear(); - // Check that the vectors are equal. - 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); + // Check that the vectors are equal. + 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); + } else if (row_mt_ == 1) { + // Encode using multiple threads row-mt enabled. + 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(); - // 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); + // 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(); + 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); + // 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_; @@ -233,14 +234,15 @@ TEST_P(AVxEncoderThreadTestLarge, EncoderResultTest) { AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadTest, ::testing::Values(::libaom_test::kTwoPassGood), ::testing::Range(2, 4), ::testing::Values(0, 2), - ::testing::Values(0, 1)); + ::testing::Values(0, 1), ::testing::Values(0, 1)); // Test cpu_used 0 and 1. AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadTestLarge, ::testing::Values(::libaom_test::kTwoPassGood, ::libaom_test::kOnePassGood), ::testing::Range(0, 2), ::testing::Values(0, 1, 2, 6), - ::testing::Values(0, 1, 2, 6)); + ::testing::Values(0, 1, 2, 6), + ::testing::Values(0, 1)); class AVxEncoderThreadLSTest : public AVxEncoderThreadTest { virtual void SetTileSize(libaom_test::Encoder *encoder) { @@ -269,5 +271,5 @@ AV1_INSTANTIATE_TEST_CASE(AVxEncoderThreadLSTestLarge, ::testing::Values(::libaom_test::kTwoPassGood, ::libaom_test::kOnePassGood), ::testing::Range(0, 4), ::testing::Values(0, 6), - ::testing::Values(0, 6)); + ::testing::Values(0, 6), ::testing::Values(0, 1)); } // namespace diff --git a/media/libaom/src/test/external_frame_buffer_test.cc b/media/libaom/src/test/external_frame_buffer_test.cc index c2af059a4..1d726a4f1 100644 --- a/media/libaom/src/test/external_frame_buffer_test.cc +++ b/media/libaom/src/test/external_frame_buffer_test.cc @@ -8,8 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <memory> #include <string> - +#include "common/tools_common.h" #include "config/aom_config.h" #include "test/codec_factory.h" #include "test/decode_test_driver.h" @@ -57,7 +58,7 @@ class ExternalFrameBufferList { // 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 + // frame buffer is in use by libaom. 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); @@ -113,16 +114,14 @@ class ExternalFrameBufferList { 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); + // Checks that the aom_image_t data is contained within the external frame + // buffer private data passed back in the aom_image_t. + void CheckImageFrameBuffer(const aom_image_t *img) { + 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)); - } + 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_; } @@ -157,7 +156,7 @@ class ExternalFrameBufferList { #if CONFIG_WEBM_IO -// Callback used by libvpx to request the application to return a frame +// Callback used by libaom 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) { @@ -166,7 +165,7 @@ int get_aom_frame_buffer(void *user_priv, size_t min_size, return fb_list->GetFreeFrameBuffer(min_size, fb); } -// Callback used by libvpx to tell the application that |fb| is not needed +// Callback used by libaom 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 = @@ -217,7 +216,7 @@ class ExternalFrameBufferMD5Test const libaom_test::CompressedVideoSource &video, libaom_test::Decoder *decoder) { if (num_buffers_ > 0 && video.frame_number() == 0) { - // Have libvpx use frame buffers we create. + // Have libaom use frame buffers we create. ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_)); ASSERT_EQ(AOM_CODEC_OK, decoder->SetFrameBufferFunctions(GetAV1FrameBuffer, @@ -243,12 +242,34 @@ class ExternalFrameBufferMD5Test expected_md5[32] = '\0'; ::libaom_test::MD5 md5_res; - md5_res.Add(&img); +#if FORCE_HIGHBITDEPTH_DECODING + const aom_img_fmt_t shifted_fmt = + (aom_img_fmt)(img.fmt & ~AOM_IMG_FMT_HIGHBITDEPTH); + if (img.bit_depth == 8 && shifted_fmt != img.fmt) { + aom_image_t *img_shifted = + aom_img_alloc(NULL, shifted_fmt, img.d_w, img.d_h, 16); + img_shifted->bit_depth = img.bit_depth; + img_shifted->monochrome = img.monochrome; + aom_img_downshift(img_shifted, &img, 0); + md5_res.Add(img_shifted); + aom_img_free(img_shifted); + } else { +#endif + md5_res.Add(&img); +#if FORCE_HIGHBITDEPTH_DECODING + } +#endif 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; + + 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)); } // Callback to get a free external frame buffer. Return value < 0 is an @@ -279,21 +300,22 @@ class ExternalFrameBufferMD5Test }; #if CONFIG_WEBM_IO -const char kAV1TestFile[] = "av1-1-b8-01-size-226x226.ivf"; +const char kAV1TestFile[] = "av1-1-b8-03-sizeup.mkv"; const char kAV1NonRefTestFile[] = "av1-1-b8-01-size-226x226.ivf"; -// Class for testing passing in external frame buffers to libvpx. +// Class for testing passing in external frame buffers to libaom. class ExternalFrameBufferTest : public ::testing::Test { protected: ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {} virtual void SetUp() { - video_ = new libaom_test::IVFVideoSource(kAV1TestFile); + video_ = new libaom_test::WebMVideoSource(kAV1TestFile); ASSERT_TRUE(video_ != NULL); video_->Init(); video_->Begin(); aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); + cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING; decoder_ = new libaom_test::AV1Decoder(cfg, 0); ASSERT_TRUE(decoder_ != NULL); } @@ -305,7 +327,7 @@ class ExternalFrameBufferTest : public ::testing::Test { video_ = NULL; } - // Passes the external frame buffer information to libvpx. + // Passes the external frame buffer information to libaom. 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) { @@ -342,11 +364,11 @@ class ExternalFrameBufferTest : public ::testing::Test { // Get decompressed data while ((img = dec_iter.Next()) != NULL) { - fb_list_.CheckXImageFrameBuffer(img); + fb_list_.CheckImageFrameBuffer(img); } } - libaom_test::IVFVideoSource *video_; + libaom_test::CompressedVideoSource *video_; libaom_test::AV1Decoder *decoder_; int num_buffers_; ExternalFrameBufferList fb_list_; @@ -361,6 +383,7 @@ class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest { video_->Begin(); aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); + cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING; decoder_ = new libaom_test::AV1Decoder(cfg, 0); ASSERT_TRUE(decoder_ != NULL); } @@ -373,12 +396,13 @@ class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest { #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 +// Libaom 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) { +TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) { const std::string filename = GET_PARAM(kVideoNameParam); + aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); // Number of buffers equals #AOM_MAXIMUM_REF_BUFFERS + // #AOM_MAXIMUM_WORK_BUFFERS + four jitter buffers. @@ -388,7 +412,7 @@ TEST_P(ExternalFrameBufferMD5Test, DISABLED_ExtFBMD5Match) { set_num_buffers(num_buffers); // Open compressed video file. - testing::internal::scoped_ptr<libaom_test::CompressedVideoSource> video; + std::unique_ptr<libaom_test::CompressedVideoSource> video; if (filename.substr(filename.length() - 3, 3) == "ivf") { video.reset(new libaom_test::IVFVideoSource(filename)); } else { @@ -407,8 +431,12 @@ TEST_P(ExternalFrameBufferMD5Test, DISABLED_ExtFBMD5Match) { const std::string md5_filename = filename + ".md5"; OpenMD5File(md5_filename); + // Set decode config. + cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING; + set_cfg(cfg); + // Decode frame, and check the md5 matching. - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); + ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg)); } #if CONFIG_WEBM_IO @@ -434,7 +462,7 @@ TEST_F(ExternalFrameBufferTest, EightJitterBuffers) { ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames()); } -TEST_F(ExternalFrameBufferTest, DISABLED_NotEnoughBuffers) { +TEST_F(ExternalFrameBufferTest, 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. @@ -448,7 +476,7 @@ TEST_F(ExternalFrameBufferTest, DISABLED_NotEnoughBuffers) { ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeRemainingFrames()); } -TEST_F(ExternalFrameBufferTest, DISABLED_NoRelease) { +TEST_F(ExternalFrameBufferTest, 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, diff --git a/media/libaom/src/test/fdct4x4_test.cc b/media/libaom/src/test/fdct4x4_test.cc new file mode 100644 index 000000000..6600f2c46 --- /dev/null +++ b/media/libaom/src/test/fdct4x4_test.cc @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2020, 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 <stdlib.h> +#include <string.h> +#include <tuple> + +#include "aom_dsp/aom_dsp_common.h" +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/av1_rtcd.h" +#include "config/aom_dsp_rtcd.h" +#include "test/acm_random.h" +#include "test/clear_system_state.h" +#include "test/register_state_check.h" +#include "test/transform_test_base.h" +#include "test/util.h" +#include "av1/common/entropy.h" +#include "aom/aom_codec.h" +#include "aom/aom_integer.h" +#include "aom_ports/mem.h" + +using libaom_test::ACMRandom; + +namespace { + +template <typename OutputType> +using FdctFunc = void (*)(const int16_t *in, OutputType *out, int stride); + +template <typename OutputType> +using FhtFunc = void (*)(const int16_t *in, OutputType *out, int stride, + TxfmParam *txfm_param); + +template <typename OutputType> +using Fdct4x4Param = + std::tuple<FdctFunc<OutputType>, FhtFunc<OutputType>, aom_bit_depth_t, int>; + +#if HAVE_NEON || HAVE_SSE2 +void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride, + TxfmParam * /*txfm_param*/) { + aom_fdct4x4_c(in, out, stride); +} + +void fdct4x4_lp_ref(const int16_t *in, int16_t *out, int stride, + TxfmParam * /*txfm_param*/) { + aom_fdct4x4_lp_c(in, out, stride); +} +#endif + +template <typename OutputType> +class Trans4x4FDCT : public libaom_test::TransformTestBase<OutputType>, + public ::testing::TestWithParam<Fdct4x4Param<OutputType>> { + public: + virtual ~Trans4x4FDCT() {} + + using TxfmBaseOutType = libaom_test::TransformTestBase<OutputType>; + virtual void SetUp() { + fwd_txfm_ = std::get<0>(this->GetParam()); + TxfmBaseOutType::pitch_ = 4; + TxfmBaseOutType::height_ = 4; + TxfmBaseOutType::fwd_txfm_ref = std::get<1>(this->GetParam()); + TxfmBaseOutType::bit_depth_ = std::get<2>(this->GetParam()); + TxfmBaseOutType::mask_ = (1 << TxfmBaseOutType::bit_depth_) - 1; + TxfmBaseOutType::num_coeffs_ = std::get<3>(this->GetParam()); + } + virtual void TearDown() { libaom_test::ClearSystemState(); } + + protected: + void RunFwdTxfm(const int16_t *in, OutputType *out, int stride) { + fwd_txfm_(in, out, stride); + } + + void RunInvTxfm(const OutputType *out, uint8_t *dst, int stride) { + (void)out; + (void)dst; + (void)stride; + } + + FdctFunc<OutputType> fwd_txfm_; +}; + +using Trans4x4FDCTTranLow = Trans4x4FDCT<tran_low_t>; +TEST_P(Trans4x4FDCTTranLow, CoeffCheck) { RunCoeffCheck(); } +TEST_P(Trans4x4FDCTTranLow, MemCheck) { RunMemCheck(); } + +using Trans4x4FDCTInt16 = Trans4x4FDCT<int16_t>; +TEST_P(Trans4x4FDCTInt16, CoeffCheck) { RunCoeffCheck(); } +TEST_P(Trans4x4FDCTInt16, MemCheck) { RunMemCheck(); } + +using std::make_tuple; + +#if HAVE_NEON +INSTANTIATE_TEST_SUITE_P(NEON, Trans4x4FDCTTranLow, + ::testing::Values(make_tuple(&aom_fdct4x4_neon, + &fdct4x4_ref, AOM_BITS_8, + 16))); + +INSTANTIATE_TEST_SUITE_P(NEON, Trans4x4FDCTInt16, + ::testing::Values(make_tuple(&aom_fdct4x4_lp_neon, + &fdct4x4_lp_ref, + AOM_BITS_8, 16))); +#endif + +#if HAVE_SSE2 +INSTANTIATE_TEST_SUITE_P(SSE2, Trans4x4FDCTTranLow, + ::testing::Values(make_tuple(&aom_fdct4x4_sse2, + &fdct4x4_ref, AOM_BITS_8, + 16))); + +INSTANTIATE_TEST_SUITE_P(SSE2, Trans4x4FDCTInt16, + ::testing::Values(make_tuple(&aom_fdct4x4_lp_sse2, + &fdct4x4_lp_ref, + AOM_BITS_8, 16))); +#endif +} // namespace diff --git a/media/libaom/src/test/fft_test.cc b/media/libaom/src/test/fft_test.cc index e24e451a3..d23aa012c 100644 --- a/media/libaom/src/test/fft_test.cc +++ b/media/libaom/src/test/fft_test.cc @@ -13,6 +13,7 @@ #include <algorithm> #include <complex> +#include <ostream> #include <vector> #include "aom_dsp/fft_common.h" @@ -133,16 +134,16 @@ TEST_P(FFT2DTest, Benchmark) { } } -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))); +INSTANTIATE_TEST_SUITE_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( +INSTANTIATE_TEST_SUITE_P( SSE2, FFT2DTest, ::testing::Values(FFTTestArg(4, aom_fft4x4_float_sse2), FFTTestArg(8, aom_fft8x8_float_sse2), @@ -150,7 +151,7 @@ INSTANTIATE_TEST_CASE_P( FFTTestArg(32, aom_fft32x32_float_sse2))); #endif // HAVE_SSE2 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, FFT2DTest, ::testing::Values(FFTTestArg(8, aom_fft8x8_float_avx2), FFTTestArg(16, aom_fft16x16_float_avx2), @@ -227,7 +228,7 @@ TEST_P(IFFT2DTest, Benchmark) { input_[i % (n * n)] = 0; } } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, IFFT2DTest, ::testing::Values(IFFTTestArg(2, aom_ifft2x2_float_c), IFFTTestArg(4, aom_ifft4x4_float_c), @@ -236,7 +237,7 @@ INSTANTIATE_TEST_CASE_P( IFFTTestArg(32, aom_ifft32x32_float_c))); #if ARCH_X86 || ARCH_X86_64 #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, IFFT2DTest, ::testing::Values(IFFTTestArg(4, aom_ifft4x4_float_sse2), IFFTTestArg(8, aom_ifft8x8_float_sse2), @@ -245,7 +246,7 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_SSE2 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, IFFT2DTest, ::testing::Values(IFFTTestArg(8, aom_ifft8x8_float_avx2), IFFTTestArg(16, aom_ifft16x16_float_avx2), diff --git a/media/libaom/src/test/filterintra_test.cc b/media/libaom/src/test/filterintra_test.cc index 597134940..284353c69 100644 --- a/media/libaom/src/test/filterintra_test.cc +++ b/media/libaom/src/test/filterintra_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/av1_rtcd.h" @@ -21,8 +23,8 @@ namespace { -using ::testing::tuple; using libaom_test::ACMRandom; +using std::tuple; typedef void (*Predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode); @@ -43,9 +45,9 @@ class AV1FilterIntraPredTest : public ::testing::TestWithParam<PredParams> { virtual ~AV1FilterIntraPredTest() {} virtual void SetUp() { PredFuncMode funcMode = GET_PARAM(0); - predFuncRef_ = ::testing::get<0>(funcMode); - predFunc_ = ::testing::get<1>(funcMode); - mode_ = ::testing::get<2>(funcMode); + predFuncRef_ = std::get<0>(funcMode); + predFunc_ = std::get<1>(funcMode); + mode_ = std::get<2>(funcMode); txSize_ = GET_PARAM(1); alloc_ = new uint8_t[2 * MaxTxSize + 1]; @@ -108,7 +110,7 @@ class AV1FilterIntraPredTest : public ::testing::TestWithParam<PredParams> { TEST_P(AV1FilterIntraPredTest, BitExactCheck) { RunTest(); } -using ::testing::make_tuple; +using std::make_tuple; const PredFuncMode kPredFuncMdArray[] = { make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1, @@ -127,7 +129,7 @@ const TX_SIZE kTxSize[] = { TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_4X8, TX_8X4, TX_8X16, TX_16X8, TX_16X32, TX_32X16, TX_4X16, TX_16X4, TX_8X32, TX_32X8 }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AV1FilterIntraPredTest, ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray), ::testing::ValuesIn(kTxSize))); diff --git a/media/libaom/src/test/frame_error_test.cc b/media/libaom/src/test/frame_error_test.cc new file mode 100644 index 000000000..6d74a68f2 --- /dev/null +++ b/media/libaom/src/test/frame_error_test.cc @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <tuple> + +#include "config/av1_rtcd.h" + +#include "aom_mem/aom_mem.h" +#include "aom_ports/aom_timer.h" +#include "aom_ports/mem.h" +#include "test/acm_random.h" +#include "test/clear_system_state.h" +#include "test/util.h" +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +namespace { +typedef int64_t (*frame_error_func)(const uint8_t *const ref, int stride, + const uint8_t *const dst, int p_width, + int p_height, int p_stride); +#if HAVE_AVX2 || HAVE_SSE2 +const int kBlockWidth[] = { + 832, 834, 640, 1280, 1920, +}; +const int kBlockHeight[] = { + 480, 482, 360, 720, 1080, +}; +#endif +typedef std::tuple<frame_error_func, int, int> FrameErrorParam; + +class AV1FrameErrorTest : public ::testing::TestWithParam<FrameErrorParam> { + public: + virtual ~AV1FrameErrorTest() {} + virtual void SetUp() { + rnd_.Reset(libaom_test::ACMRandom::DeterministicSeed()); + } + virtual void TearDown() { libaom_test::ClearSystemState(); } + + protected: + void RandomValues(frame_error_func test_impl, int width, int height); + void ExtremeValues(frame_error_func test_impl, int width, int height); + void RunSpeedTest(frame_error_func test_impl, int width, int height); + libaom_test::ACMRandom rnd_; +}; + +void AV1FrameErrorTest::RandomValues(frame_error_func test_impl, int width, + int height) { + const int stride = (((width * 3) / 2) + 15) & ~15; + const int max_blk_size = stride * height; + uint8_t *const dst = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst))); + uint8_t *const ref = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref))); + ASSERT_TRUE(dst != NULL); + ASSERT_TRUE(ref != NULL); + for (int i = 0; i < max_blk_size; ++i) { + dst[i] = rnd_.Rand8(); + ref[i] = rnd_.Rand8(); + } + const int64_t ref_error = + av1_calc_frame_error_c(ref, stride, dst, width, height, stride); + const int64_t test_error = test_impl(ref, stride, dst, width, height, stride); + ASSERT_EQ(test_error, ref_error) << width << "x" << height; + aom_free(dst); + aom_free(ref); +} + +void AV1FrameErrorTest::ExtremeValues(frame_error_func test_impl, int width, + int height) { + const int stride = (((width * 3) / 2) + 15) & ~15; + const int max_blk_size = stride * height; + uint8_t *const dst = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst))); + uint8_t *const ref = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref))); + ASSERT_TRUE(dst != NULL); + ASSERT_TRUE(ref != NULL); + for (int r = 0; r < 2; r++) { + if (r == 0) { + memset(dst, 0, max_blk_size); + memset(ref, 255, max_blk_size); + } else if (r == 1) { + memset(dst, 255, max_blk_size); + memset(ref, 0, max_blk_size); + } + const int64_t ref_error = + av1_calc_frame_error_c(ref, stride, dst, width, height, stride); + const int64_t test_error = + test_impl(ref, stride, dst, width, height, stride); + ASSERT_EQ(test_error, ref_error) << width << "x" << height; + } + aom_free(dst); + aom_free(ref); +} + +void AV1FrameErrorTest::RunSpeedTest(frame_error_func test_impl, int width, + int height) { + const int stride = (((width * 3) / 2) + 15) & ~15; + const int max_blk_size = stride * height; + uint8_t *const dst = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*dst))); + uint8_t *const ref = + static_cast<uint8_t *>(aom_memalign(16, max_blk_size * sizeof(*ref))); + ASSERT_TRUE(dst != NULL); + ASSERT_TRUE(ref != NULL); + for (int i = 0; i < max_blk_size; ++i) { + dst[i] = ref[i] = rnd_.Rand8(); + } + const int num_loops = 10000000 / (width + height); + frame_error_func funcs[2] = { av1_calc_frame_error_c, test_impl }; + double elapsed_time[2] = { 0 }; + for (int i = 0; i < 2; ++i) { + aom_usec_timer timer; + aom_usec_timer_start(&timer); + frame_error_func func = funcs[i]; + for (int j = 0; j < num_loops; ++j) { + func(ref, stride, dst, width, height, stride); + } + aom_usec_timer_mark(&timer); + double time = static_cast<double>(aom_usec_timer_elapsed(&timer)); + elapsed_time[i] = 1000.0 * time / num_loops; + } + aom_free(dst); + aom_free(ref); + printf("av1_calc_frame_error %3dx%-3d: %7.2f/%7.2fns", width, height, + elapsed_time[0], elapsed_time[1]); + printf("(%3.2f)\n", elapsed_time[0] / elapsed_time[1]); +} + +TEST_P(AV1FrameErrorTest, CheckOutput) { + RandomValues(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2)); + ExtremeValues(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2)); +} + +TEST_P(AV1FrameErrorTest, DISABLED_Speed) { + RunSpeedTest(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2)); +} + +#if HAVE_SSE2 +INSTANTIATE_TEST_SUITE_P( + SSE2, AV1FrameErrorTest, + ::testing::Combine(::testing::Values(&av1_calc_frame_error_sse2), + ::testing::ValuesIn(kBlockWidth), + ::testing::ValuesIn(kBlockHeight))); +#endif + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, AV1FrameErrorTest, + ::testing::Combine(::testing::Values(&av1_calc_frame_error_avx2), + ::testing::ValuesIn(kBlockWidth), + ::testing::ValuesIn(kBlockHeight))); +#endif +} // namespace diff --git a/media/libaom/src/test/frame_size_tests.cc b/media/libaom/src/test/frame_size_tests.cc index eaf0b8370..1546012a3 100644 --- a/media/libaom/src/test/frame_size_tests.cc +++ b/media/libaom/src/test/frame_size_tests.cc @@ -35,7 +35,7 @@ class AV1FrameSizeTests : public ::testing::Test, virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, 7); encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); diff --git a/media/libaom/src/test/function_equivalence_test.h b/media/libaom/src/test/function_equivalence_test.h index f27068902..a299c48d4 100644 --- a/media/libaom/src/test/function_equivalence_test.h +++ b/media/libaom/src/test/function_equivalence_test.h @@ -12,6 +12,8 @@ #ifndef AOM_TEST_FUNCTION_EQUIVALENCE_TEST_H_ #define AOM_TEST_FUNCTION_EQUIVALENCE_TEST_H_ +#include <ostream> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/acm_random.h" #include "test/clear_system_state.h" diff --git a/media/libaom/src/test/fwd_kf_test.cc b/media/libaom/src/test/fwd_kf_test.cc new file mode 100644 index 000000000..50c2f36d8 --- /dev/null +++ b/media/libaom/src/test/fwd_kf_test.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <ostream> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" + +namespace { + +typedef struct { + const int max_kf_dist; + const double psnr_thresh; +} FwdKfTestParam; + +const FwdKfTestParam kTestParams[] = { + { 4, 33.4 }, { 6, 32.9 }, { 8, 32.6 }, + { 12, 32.4 }, { 16, 32.3 }, { 18, 32.1 } +}; + +std::ostream &operator<<(std::ostream &os, const FwdKfTestParam &test_arg) { + return os << "FwdKfTestParam { max_kf_dist:" << test_arg.max_kf_dist + << " psnr_thresh:" << test_arg.psnr_thresh << " }"; +} + +class ForwardKeyTest + : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, + FwdKfTestParam>, + public ::libaom_test::EncoderTest { + protected: + ForwardKeyTest() + : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), + kf_max_dist_param_(GET_PARAM(2)) {} + virtual ~ForwardKeyTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(encoding_mode_); + const aom_rational timebase = { 1, 30 }; + cfg_.g_timebase = timebase; + cpu_used_ = 2; + kf_max_dist_ = kf_max_dist_param_.max_kf_dist; + psnr_threshold_ = kf_max_dist_param_.psnr_thresh; + cfg_.rc_end_usage = AOM_VBR; + cfg_.rc_target_bitrate = 200; + cfg_.g_lag_in_frames = 10; + cfg_.fwd_kf_enabled = 1; + cfg_.kf_max_dist = kf_max_dist_; + cfg_.g_threads = 0; + init_flags_ = AOM_CODEC_USE_PSNR; + } + + virtual void BeginPassHook(unsigned int) { + psnr_ = 0.0; + nframes_ = 0; + } + + virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { + psnr_ += pkt->data.psnr.psnr[0]; + nframes_++; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AOME_SET_CPUUSED, cpu_used_); + if (encoding_mode_ != ::libaom_test::kRealTime) { + encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); + encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); + encoder->Control(AOME_SET_ARNR_STRENGTH, 5); + } + } + } + + double GetAveragePsnr() const { + if (nframes_) return psnr_ / nframes_; + return 0.0; + } + + double GetPsnrThreshold() { return psnr_threshold_; } + + ::libaom_test::TestMode encoding_mode_; + const FwdKfTestParam kf_max_dist_param_; + double psnr_threshold_; + int kf_max_dist_; + int cpu_used_; + int nframes_; + double psnr_; +}; + +TEST_P(ForwardKeyTest, ForwardKeyEncodeTest) { + libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + cfg_.g_timebase.den, cfg_.g_timebase.num, + 0, 20); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + // TODO(sarahparker) Add functionality to assert the minimum number of + // keyframes were placed. + EXPECT_GT(GetAveragePsnr(), GetPsnrThreshold()) + << "kf max dist = " << kf_max_dist_; +} + +AV1_INSTANTIATE_TEST_CASE(ForwardKeyTest, + ::testing::Values(::libaom_test::kTwoPassGood), + ::testing::ValuesIn(kTestParams)); +} // namespace diff --git a/media/libaom/src/test/fwht4x4_test.cc b/media/libaom/src/test/fwht4x4_test.cc index c8d98c519..d2f77b8d4 100644 --- a/media/libaom/src/test/fwht4x4_test.cc +++ b/media/libaom/src/test/fwht4x4_test.cc @@ -12,7 +12,9 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> +#include "aom_dsp/aom_dsp_common.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/av1_rtcd.h" @@ -35,7 +37,7 @@ typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); using libaom_test::FhtFunc; -typedef ::testing::tuple<FdctFunc, IdctFunc, TX_TYPE, aom_bit_depth_t, int> +typedef std::tuple<FdctFunc, IdctFunc, TX_TYPE, aom_bit_depth_t, int> Dct4x4Param; void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride, @@ -51,7 +53,7 @@ void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) { av1_highbd_iwht4x4_16_add_c(in, out, stride, 12); } -class Trans4x4WHT : public libaom_test::TransformTestBase, +class Trans4x4WHT : public libaom_test::TransformTestBase<tran_low_t>, public ::testing::TestWithParam<Dct4x4Param> { public: virtual ~Trans4x4WHT() {} @@ -87,9 +89,9 @@ TEST_P(Trans4x4WHT, CoeffCheck) { RunCoeffCheck(); } TEST_P(Trans4x4WHT, MemCheck) { RunMemCheck(); } TEST_P(Trans4x4WHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); } -using ::testing::make_tuple; +using std::make_tuple; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, Trans4x4WHT, ::testing::Values(make_tuple(&av1_highbd_fwht4x4_c, &iwht4x4_10, DCT_DCT, AOM_BITS_10, 16), diff --git a/media/libaom/src/test/gf_pyr_height_test.cc b/media/libaom/src/test/gf_pyr_height_test.cc new file mode 100644 index 000000000..b1ade67a6 --- /dev/null +++ b/media/libaom/src/test/gf_pyr_height_test.cc @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <ostream> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" + +namespace { + +static const struct GFPyrHeightTestParam { + int gf_min_pyr_height; + int gf_max_pyr_height; + double psnr_thresh; +} kTestParams[] = { + // gf_min_pyr_height = 0 + { 0, 0, 33.40 }, + { 0, 1, 34.00 }, + { 0, 2, 34.00 }, + { 0, 3, 34.20 }, + { 0, 4, 34.30 }, + { 0, 5, 34.40 }, + // gf_min_pyr_height = 1 + { 1, 1, 34.00 }, + { 1, 2, 34.00 }, + { 1, 3, 34.20 }, + { 1, 4, 34.30 }, + { 1, 5, 34.40 }, + // gf_min_pyr_height = 2 + { 2, 2, 34.00 }, + { 2, 3, 34.20 }, + { 2, 4, 34.30 }, + { 2, 5, 34.40 }, + // gf_min_pyr_height = 3 + { 3, 3, 34.20 }, + { 3, 4, 34.30 }, + { 3, 5, 34.40 }, + // gf_min_pyr_height = 4 + { 4, 4, 34.30 }, + { 4, 5, 34.40 }, + // gf_min_pyr_height = 5 + { 5, 5, 34.40 }, +}; + +// Compiler may decide to add some padding to the struct above for alignment, +// which the gtest may try to print (on error for example). This would cause +// valgrind to complain that the padding is uninitialized. To avoid that, we +// provide our own function to print the struct. +// This also makes '--gtest_list_tests' output more understandable. +std::ostream &operator<<(std::ostream &os, const GFPyrHeightTestParam &p) { + os << "GFPyrHeightTestParam { " + << "gf_min_pyr_height = " << p.gf_min_pyr_height << ", " + << "gf_max_pyr_height = " << p.gf_max_pyr_height << ", " + << "psnr_thresh = " << p.psnr_thresh << " }"; + return os; +} + +// Params: encoding mode, rate control mode and GFPyrHeightTestParam object. +class GFPyrHeightTest + : public ::libaom_test::CodecTestWith3Params< + libaom_test::TestMode, aom_rc_mode, GFPyrHeightTestParam>, + public ::libaom_test::EncoderTest { + protected: + GFPyrHeightTest() + : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), + rc_mode_(GET_PARAM(2)) { + gf_min_pyr_height_ = GET_PARAM(3).gf_min_pyr_height; + gf_max_pyr_height_ = GET_PARAM(3).gf_max_pyr_height; + psnr_threshold_ = GET_PARAM(3).psnr_thresh; + } + virtual ~GFPyrHeightTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(encoding_mode_); + const aom_rational timebase = { 1, 30 }; + cfg_.g_timebase = timebase; + cpu_used_ = 4; + cfg_.rc_end_usage = rc_mode_; + if (rc_mode_ == AOM_VBR) { + cfg_.rc_target_bitrate = 200; + } + cfg_.g_lag_in_frames = 19; + cfg_.g_threads = 0; + init_flags_ = AOM_CODEC_USE_PSNR; + } + + virtual void BeginPassHook(unsigned int) { + psnr_ = 0.0; + nframes_ = 0; + } + + virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { + psnr_ += pkt->data.psnr.psnr[0]; + nframes_++; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AOME_SET_CPUUSED, cpu_used_); + if (rc_mode_ == AOM_Q) { + encoder->Control(AOME_SET_CQ_LEVEL, 32); + } + if (encoding_mode_ != ::libaom_test::kRealTime) { + encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); + encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); + encoder->Control(AOME_SET_ARNR_STRENGTH, 5); + } + encoder->Control(AV1E_SET_GF_MIN_PYRAMID_HEIGHT, gf_min_pyr_height_); + encoder->Control(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, gf_max_pyr_height_); + } + } + + double GetAveragePsnr() const { + if (nframes_) return psnr_ / nframes_; + return 0.0; + } + + double GetPsnrThreshold() { return psnr_threshold_; } + + ::libaom_test::TestMode encoding_mode_; + aom_rc_mode rc_mode_; + double psnr_threshold_; + int gf_min_pyr_height_; + int gf_max_pyr_height_; + int cpu_used_; + int nframes_; + double psnr_; +}; + +TEST_P(GFPyrHeightTest, EncodeAndVerifyPSNR) { + libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + cfg_.g_timebase.den, cfg_.g_timebase.num, + 0, 32); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + EXPECT_GT(GetAveragePsnr(), GetPsnrThreshold()) + << "GF Min Pyramid Height = " << gf_min_pyr_height_ << ", " + << "GF Max Pyramid Height = " << gf_max_pyr_height_; +} + +AV1_INSTANTIATE_TEST_CASE(GFPyrHeightTest, NONREALTIME_TEST_MODES, + ::testing::Values(AOM_Q, AOM_VBR), + ::testing::ValuesIn(kTestParams)); +} // namespace diff --git a/media/libaom/src/test/hadamard_test.cc b/media/libaom/src/test/hadamard_test.cc new file mode 100644 index 000000000..7903259e7 --- /dev/null +++ b/media/libaom/src/test/hadamard_test.cc @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. 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 <algorithm> +#include <ostream> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/aom_dsp_rtcd.h" + +#include "test/acm_random.h" +#include "test/clear_system_state.h" +#include "test/register_state_check.h" +#include "test/util.h" + +namespace { + +using libaom_test::ACMRandom; + +typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride, + tran_low_t *b); + +void HadamardLoop(const tran_low_t *a, tran_low_t *out) { + tran_low_t b[8]; + for (int i = 0; i < 8; i += 2) { + b[i + 0] = a[i * 8] + a[(i + 1) * 8]; + b[i + 1] = a[i * 8] - a[(i + 1) * 8]; + } + tran_low_t c[8]; + for (int i = 0; i < 8; i += 4) { + c[i + 0] = b[i + 0] + b[i + 2]; + c[i + 1] = b[i + 1] + b[i + 3]; + c[i + 2] = b[i + 0] - b[i + 2]; + c[i + 3] = b[i + 1] - b[i + 3]; + } + out[0] = c[0] + c[4]; + out[7] = c[1] + c[5]; + out[3] = c[2] + c[6]; + out[4] = c[3] + c[7]; + out[2] = c[0] - c[4]; + out[6] = c[1] - c[5]; + out[1] = c[2] - c[6]; + out[5] = c[3] - c[7]; +} + +void ReferenceHadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) { + tran_low_t input[64]; + tran_low_t buf[64]; + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + input[i * 8 + j] = static_cast<tran_low_t>(a[i * a_stride + j]); + } + } + for (int i = 0; i < 8; ++i) HadamardLoop(input + i, buf + i * 8); + for (int i = 0; i < 8; ++i) HadamardLoop(buf + i, b + i * 8); +} + +void ReferenceHadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) { + /* The source is a 16x16 block. The destination is rearranged to 8x32. + * Input is 9 bit. */ + ReferenceHadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0); + ReferenceHadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64); + ReferenceHadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128); + ReferenceHadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192); + + /* Overlay the 8x8 blocks and combine. */ + for (int i = 0; i < 64; ++i) { + /* 8x8 steps the range up to 15 bits. */ + const tran_low_t a0 = b[0]; + const tran_low_t a1 = b[64]; + const tran_low_t a2 = b[128]; + const tran_low_t a3 = b[192]; + + /* Prevent the result from escaping int16_t. */ + const tran_low_t b0 = (a0 + a1) >> 1; + const tran_low_t b1 = (a0 - a1) >> 1; + const tran_low_t b2 = (a2 + a3) >> 1; + const tran_low_t b3 = (a2 - a3) >> 1; + + /* Store a 16 bit value. */ + b[0] = b0 + b2; + b[64] = b1 + b3; + b[128] = b0 - b2; + b[192] = b1 - b3; + + ++b; + } +} + +void ReferenceHadamard32x32(const int16_t *a, int a_stride, tran_low_t *b) { + ReferenceHadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0); + ReferenceHadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256); + ReferenceHadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512); + ReferenceHadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768); + + for (int i = 0; i < 256; ++i) { + const tran_low_t a0 = b[0]; + const tran_low_t a1 = b[256]; + const tran_low_t a2 = b[512]; + const tran_low_t a3 = b[768]; + + const tran_low_t b0 = (a0 + a1) >> 2; + const tran_low_t b1 = (a0 - a1) >> 2; + const tran_low_t b2 = (a2 + a3) >> 2; + const tran_low_t b3 = (a2 - a3) >> 2; + + b[0] = b0 + b2; + b[256] = b1 + b3; + b[512] = b0 - b2; + b[768] = b1 - b3; + + ++b; + } +} + +struct HadamardFuncWithSize { + HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {} + HadamardFunc func; + int block_size; +}; + +std::ostream &operator<<(std::ostream &os, const HadamardFuncWithSize &hfs) { + return os << "block size: " << hfs.block_size; +} + +class HadamardTestBase : public ::testing::TestWithParam<HadamardFuncWithSize> { + public: + virtual void SetUp() { + h_func_ = GetParam().func; + bwh_ = GetParam().block_size; + block_size_ = bwh_ * bwh_; + rnd_.Reset(ACMRandom::DeterministicSeed()); + } + + virtual int16_t Rand() = 0; + + void ReferenceHadamard(const int16_t *a, int a_stride, tran_low_t *b, + int bwh) { + if (bwh == 32) + ReferenceHadamard32x32(a, a_stride, b); + else if (bwh == 16) + ReferenceHadamard16x16(a, a_stride, b); + else + ReferenceHadamard8x8(a, a_stride, b); + } + + void CompareReferenceRandom() { + const int kMaxBlockSize = 32 * 32; + DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]); + DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]); + memset(a, 0, sizeof(a)); + memset(b, 0, sizeof(b)); + + tran_low_t b_ref[kMaxBlockSize]; + memset(b_ref, 0, sizeof(b_ref)); + + for (int i = 0; i < block_size_; ++i) a[i] = Rand(); + + ReferenceHadamard(a, bwh_, b_ref, bwh_); + ASM_REGISTER_STATE_CHECK(h_func_(a, bwh_, b)); + + // The order of the output is not important. Sort before checking. + std::sort(b, b + block_size_); + std::sort(b_ref, b_ref + block_size_); + EXPECT_EQ(memcmp(b, b_ref, sizeof(b)), 0); + } + + void VaryStride() { + const int kMaxBlockSize = 32 * 32; + DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]); + DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]); + memset(a, 0, sizeof(a)); + for (int i = 0; i < block_size_ * 8; ++i) a[i] = Rand(); + + tran_low_t b_ref[kMaxBlockSize]; + for (int i = 8; i < 64; i += 8) { + memset(b, 0, sizeof(b)); + memset(b_ref, 0, sizeof(b_ref)); + + ReferenceHadamard(a, i, b_ref, bwh_); + ASM_REGISTER_STATE_CHECK(h_func_(a, i, b)); + + // The order of the output is not important. Sort before checking. + std::sort(b, b + block_size_); + std::sort(b_ref, b_ref + block_size_); + EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b))); + } + } + + void SpeedTest(int times) { + const int kMaxBlockSize = 32 * 32; + DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]); + DECLARE_ALIGNED(16, tran_low_t, output[kMaxBlockSize]); + memset(input, 1, sizeof(input)); + memset(output, 0, sizeof(output)); + + aom_usec_timer timer; + aom_usec_timer_start(&timer); + for (int i = 0; i < times; ++i) { + h_func_(input, bwh_, output); + } + aom_usec_timer_mark(&timer); + + const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); + printf("Hadamard%dx%d[%12d runs]: %d us\n", bwh_, bwh_, times, + elapsed_time); + } + + ACMRandom rnd_; + + private: + int bwh_; + int block_size_; + HadamardFunc h_func_; +}; + +class HadamardLowbdTest : public HadamardTestBase { + public: + virtual int16_t Rand() { return rnd_.Rand9Signed(); } +}; + +TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); } + +TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); } + +INSTANTIATE_TEST_SUITE_P( + C, HadamardLowbdTest, + ::testing::Values(HadamardFuncWithSize(&aom_hadamard_8x8_c, 8), + HadamardFuncWithSize(&aom_hadamard_16x16_c, 16), + HadamardFuncWithSize(&aom_hadamard_32x32_c, 32))); + +#if HAVE_SSE2 +INSTANTIATE_TEST_SUITE_P( + SSE2, HadamardLowbdTest, + ::testing::Values(HadamardFuncWithSize(&aom_hadamard_8x8_sse2, 8), + HadamardFuncWithSize(&aom_hadamard_16x16_sse2, 16), + HadamardFuncWithSize(&aom_hadamard_32x32_sse2, 32))); +#endif // HAVE_SSE2 + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, HadamardLowbdTest, + ::testing::Values(HadamardFuncWithSize(&aom_hadamard_16x16_avx2, 16), + HadamardFuncWithSize(&aom_hadamard_32x32_avx2, 32))); +#endif // HAVE_AVX2 + +#if HAVE_NEON +INSTANTIATE_TEST_SUITE_P( + NEON, HadamardLowbdTest, + ::testing::Values(HadamardFuncWithSize(&aom_hadamard_8x8_neon, 8), + HadamardFuncWithSize(&aom_hadamard_16x16_neon, 16))); +#endif // HAVE_NEON + +} // namespace diff --git a/media/libaom/src/test/hash_test.cc b/media/libaom/src/test/hash_test.cc index e9f7f63c9..eb964ac5f 100644 --- a/media/libaom/src/test/hash_test.cc +++ b/media/libaom/src/test/hash_test.cc @@ -11,6 +11,7 @@ #include <cstdlib> #include <new> +#include <tuple> #include "config/aom_config.h" #include "config/av1_rtcd.h" @@ -24,9 +25,9 @@ namespace { typedef uint32_t (*get_crc32c_value_func)(void *calculator, uint8_t *p, - int length); + size_t length); -typedef ::testing::tuple<get_crc32c_value_func, int> HashParam; +typedef std::tuple<get_crc32c_value_func, int> HashParam; class AV1Crc32cHashTest : public ::testing::TestWithParam<HashParam> { public: @@ -45,7 +46,7 @@ class AV1Crc32cHashTest : public ::testing::TestWithParam<HashParam> { CRC32C calc_; uint8_t *buffer_; int bsize_; - int length_; + size_t length_; }; AV1Crc32cHashTest::~AV1Crc32cHashTest() { ; } @@ -58,7 +59,7 @@ void AV1Crc32cHashTest::SetUp() { length_ = bsize_ * bsize_ * sizeof(uint16_t); buffer_ = new uint8_t[length_]; ASSERT_TRUE(buffer_ != NULL); - for (int i = 0; i < length_; ++i) { + for (size_t i = 0; i < length_; ++i) { buffer_[i] = rnd_.Rand8(); } } @@ -118,13 +119,13 @@ TEST_P(AV1Crc32cHashTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0)); } const int kValidBlockSize[] = { 64, 32, 8, 4 }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AV1Crc32cHashTest, ::testing::Combine(::testing::Values(&av1_get_crc32c_value_c), ::testing::ValuesIn(kValidBlockSize))); #if HAVE_SSE4_2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_2, AV1Crc32cHashTest, ::testing::Combine(::testing::Values(&av1_get_crc32c_value_sse4_2), ::testing::ValuesIn(kValidBlockSize))); diff --git a/media/libaom/src/test/hbd_metrics_test.cc b/media/libaom/src/test/hbd_metrics_test.cc index 09df9bde4..5b03beee7 100644 --- a/media/libaom/src/test/hbd_metrics_test.cc +++ b/media/libaom/src/test/hbd_metrics_test.cc @@ -12,6 +12,7 @@ #include <math.h> #include <stdlib.h> #include <new> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/acm_random.h" @@ -173,7 +174,7 @@ class HBDMetricsTestBase { HBDMetricFunc hbd_metric_; }; -typedef ::testing::tuple<LBDMetricFunc, HBDMetricFunc, int, int, double> +typedef std::tuple<LBDMetricFunc, HBDMetricFunc, int, int, double> MetricTestTParam; class HBDMetricsTest : public HBDMetricsTestBase, public ::testing::TestWithParam<MetricTestTParam> { @@ -197,7 +198,7 @@ static const double kFSsim_thresh = 0.03; // Allow some extra variation due to rounding error accumulated in dct. static const double kPhvs_thresh = 0.3; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AOMSSIM, HBDMetricsTest, ::testing::Values(MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim, 8, 10, kSsim_thresh), @@ -207,7 +208,7 @@ INSTANTIATE_TEST_CASE_P( 8, 12, kSsim_thresh), MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim, 12, 12, kPhvs_thresh))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( FASTSSIM, HBDMetricsTest, ::testing::Values(MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 8, 10, kFSsim_thresh), @@ -217,7 +218,7 @@ INSTANTIATE_TEST_CASE_P( 8, 12, kFSsim_thresh), MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 12, 12, kFSsim_thresh))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( PSNRHVS, HBDMetricsTest, ::testing::Values(MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 8, 10, kPhvs_thresh), @@ -227,7 +228,7 @@ INSTANTIATE_TEST_CASE_P( 8, 12, kPhvs_thresh), MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 12, 12, kPhvs_thresh))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( PSNR, HBDMetricsTest, ::testing::Values( MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 10, kPhvs_thresh), diff --git a/media/libaom/src/test/hiprec_convolve_test.cc b/media/libaom/src/test/hiprec_convolve_test.cc index f94a0730c..59d28e883 100644 --- a/media/libaom/src/test/hiprec_convolve_test.cc +++ b/media/libaom/src/test/hiprec_convolve_test.cc @@ -9,14 +9,18 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/hiprec_convolve_test_util.h" -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; +#if CONFIG_AV1_HIGHBITDEPTH using libaom_test::AV1HighbdHiprecConvolve::AV1HighbdHiprecConvolveTest; +#endif using libaom_test::AV1HiprecConvolve::AV1HiprecConvolveTest; +using std::make_tuple; +using std::tuple; namespace { @@ -25,21 +29,22 @@ TEST_P(AV1HiprecConvolveTest, DISABLED_SpeedTest) { RunSpeedTest(GET_PARAM(3)); } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, AV1HiprecConvolveTest, - libaom_test::AV1HiprecConvolve::BuildParams( - av1_wiener_convolve_add_src_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1HiprecConvolveTest, + libaom_test::AV1HiprecConvolve::BuildParams( + av1_wiener_convolve_add_src_sse2)); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AV1HiprecConvolveTest, - libaom_test::AV1HiprecConvolve::BuildParams( - av1_wiener_convolve_add_src_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HiprecConvolveTest, + libaom_test::AV1HiprecConvolve::BuildParams( + av1_wiener_convolve_add_src_avx2)); #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON, AV1HiprecConvolveTest, - libaom_test::AV1HiprecConvolve::BuildParams( - av1_wiener_convolve_add_src_neon)); +INSTANTIATE_TEST_SUITE_P(NEON, AV1HiprecConvolveTest, + libaom_test::AV1HiprecConvolve::BuildParams( + av1_wiener_convolve_add_src_neon)); #endif +#if CONFIG_AV1_HIGHBITDEPTH #if HAVE_SSSE3 || HAVE_AVX2 TEST_P(AV1HighbdHiprecConvolveTest, CheckOutput) { RunCheckOutput(GET_PARAM(4)); @@ -48,15 +53,16 @@ TEST_P(AV1HighbdHiprecConvolveTest, DISABLED_SpeedTest) { RunSpeedTest(GET_PARAM(4)); } #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P(SSSE3, AV1HighbdHiprecConvolveTest, - libaom_test::AV1HighbdHiprecConvolve::BuildParams( - av1_highbd_wiener_convolve_add_src_ssse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, AV1HighbdHiprecConvolveTest, + libaom_test::AV1HighbdHiprecConvolve::BuildParams( + av1_highbd_wiener_convolve_add_src_ssse3)); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AV1HighbdHiprecConvolveTest, - libaom_test::AV1HighbdHiprecConvolve::BuildParams( - av1_highbd_wiener_convolve_add_src_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AV1HighbdHiprecConvolveTest, + libaom_test::AV1HighbdHiprecConvolve::BuildParams( + av1_highbd_wiener_convolve_add_src_avx2)); #endif #endif +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/hiprec_convolve_test_util.cc b/media/libaom/src/test/hiprec_convolve_test_util.cc index 2672bcec3..956af7fc8 100644 --- a/media/libaom/src/test/hiprec_convolve_test_util.cc +++ b/media/libaom/src/test/hiprec_convolve_test_util.cc @@ -13,38 +13,55 @@ #include "av1/common/restoration.h" -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; namespace libaom_test { // Generate a random pair of filter kernels, using the ranges // of possible values from the loop-restoration experiment static void generate_kernels(ACMRandom *rnd, InterpKernel hkernel, - InterpKernel vkernel) { - hkernel[0] = hkernel[6] = - WIENER_FILT_TAP0_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP0_MAXV + 1 - WIENER_FILT_TAP0_MINV); - hkernel[1] = hkernel[5] = - WIENER_FILT_TAP1_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP1_MAXV + 1 - WIENER_FILT_TAP1_MINV); - hkernel[2] = hkernel[4] = - WIENER_FILT_TAP2_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 1 - WIENER_FILT_TAP2_MINV); - hkernel[3] = -(hkernel[0] + hkernel[1] + hkernel[2]); - hkernel[7] = 0; - - vkernel[0] = vkernel[6] = - WIENER_FILT_TAP0_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP0_MAXV + 1 - WIENER_FILT_TAP0_MINV); - vkernel[1] = vkernel[5] = - WIENER_FILT_TAP1_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP1_MAXV + 1 - WIENER_FILT_TAP1_MINV); - vkernel[2] = vkernel[4] = - WIENER_FILT_TAP2_MINV + - rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 1 - WIENER_FILT_TAP2_MINV); - vkernel[3] = -(vkernel[0] + vkernel[1] + vkernel[2]); - vkernel[7] = 0; + InterpKernel vkernel, int kernel_type = 2) { + if (kernel_type == 0) { + // Low possible values for filter coefficients + hkernel[0] = hkernel[6] = vkernel[0] = vkernel[6] = WIENER_FILT_TAP0_MINV; + hkernel[1] = hkernel[5] = vkernel[1] = vkernel[5] = WIENER_FILT_TAP1_MINV; + hkernel[2] = hkernel[4] = vkernel[2] = vkernel[4] = WIENER_FILT_TAP2_MINV; + hkernel[3] = vkernel[3] = -2 * (hkernel[0] + hkernel[1] + hkernel[2]); + hkernel[7] = vkernel[7] = 0; + } else if (kernel_type == 1) { + // Max possible values for filter coefficients + hkernel[0] = hkernel[6] = vkernel[0] = vkernel[6] = WIENER_FILT_TAP0_MAXV; + hkernel[1] = hkernel[5] = vkernel[1] = vkernel[5] = WIENER_FILT_TAP1_MAXV; + hkernel[2] = hkernel[4] = vkernel[2] = vkernel[4] = WIENER_FILT_TAP2_MAXV; + hkernel[3] = vkernel[3] = -2 * (hkernel[0] + hkernel[1] + hkernel[2]); + hkernel[7] = vkernel[7] = 0; + } else { + // Randomly generated values for filter coefficients + hkernel[0] = hkernel[6] = + WIENER_FILT_TAP0_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP0_MAXV + 1 - WIENER_FILT_TAP0_MINV); + hkernel[1] = hkernel[5] = + WIENER_FILT_TAP1_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP1_MAXV + 1 - WIENER_FILT_TAP1_MINV); + hkernel[2] = hkernel[4] = + WIENER_FILT_TAP2_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 1 - WIENER_FILT_TAP2_MINV); + hkernel[3] = -2 * (hkernel[0] + hkernel[1] + hkernel[2]); + hkernel[7] = 0; + + vkernel[0] = vkernel[6] = + WIENER_FILT_TAP0_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP0_MAXV + 2 - WIENER_FILT_TAP0_MINV); + vkernel[1] = vkernel[5] = + WIENER_FILT_TAP1_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP1_MAXV + 2 - WIENER_FILT_TAP1_MINV); + vkernel[2] = vkernel[4] = + WIENER_FILT_TAP2_MINV + + rnd->PseudoUniform(WIENER_FILT_TAP2_MAXV + 2 - WIENER_FILT_TAP2_MINV); + vkernel[3] = -2 * (vkernel[0] + vkernel[1] + vkernel[2]); + vkernel[7] = 0; + } } namespace AV1HiprecConvolve { @@ -74,7 +91,7 @@ void AV1HiprecConvolveTest::RunCheckOutput(hiprec_convolve_func test_impl) { const int w = 128, h = 128; const int out_w = GET_PARAM(0), out_h = GET_PARAM(1); const int num_iters = GET_PARAM(2); - int i, j; + int i, j, k, m; const ConvolveParams conv_params = get_conv_params_wiener(8); uint8_t *input_ = new uint8_t[h * w]; @@ -91,25 +108,25 @@ void AV1HiprecConvolveTest::RunCheckOutput(hiprec_convolve_func test_impl) { DECLARE_ALIGNED(16, InterpKernel, hkernel); DECLARE_ALIGNED(16, InterpKernel, vkernel); - generate_kernels(&rnd_, hkernel, vkernel); - - for (i = 0; i < h; ++i) - for (j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8(); - - for (i = 0; i < num_iters; ++i) { - // Choose random locations within the source block - int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); - int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_wiener_convolve_add_src_c(input + offset_r * w + offset_c, w, output, - out_w, hkernel, 16, vkernel, 16, out_w, out_h, - &conv_params); - test_impl(input + offset_r * w + offset_c, w, output2, out_w, hkernel, 16, - vkernel, 16, out_w, out_h, &conv_params); - - for (j = 0; j < out_w * out_h; ++j) - ASSERT_EQ(output[j], output2[j]) - << "Pixel mismatch at index " << j << " = (" << (j % out_w) << ", " - << (j / out_w) << ") on iteration " << i; + for (int kernel_type = 0; kernel_type < 3; kernel_type++) { + generate_kernels(&rnd_, hkernel, vkernel, kernel_type); + for (i = 0; i < num_iters; ++i) { + for (k = 0; k < h; ++k) + for (m = 0; m < w; ++m) input[k * w + m] = rnd_.Rand8(); + // Choose random locations within the source block + int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); + int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); + av1_wiener_convolve_add_src_c(input + offset_r * w + offset_c, w, output, + out_w, hkernel, 16, vkernel, 16, out_w, + out_h, &conv_params); + test_impl(input + offset_r * w + offset_c, w, output2, out_w, hkernel, 16, + vkernel, 16, out_w, out_h, &conv_params); + + for (j = 0; j < out_w * out_h; ++j) + ASSERT_EQ(output[j], output2[j]) + << "Pixel mismatch at index " << j << " = (" << (j % out_w) << ", " + << (j / out_w) << ") on iteration " << i; + } } delete[] input_; delete[] output; @@ -183,6 +200,7 @@ void AV1HiprecConvolveTest::RunSpeedTest(hiprec_convolve_func test_impl) { } } // namespace AV1HiprecConvolve +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdHiprecConvolve { ::testing::internal::ParamGenerator<HighbdHiprecConvolveParam> BuildParams( @@ -228,29 +246,29 @@ void AV1HighbdHiprecConvolveTest::RunCheckOutput( DECLARE_ALIGNED(16, InterpKernel, hkernel); DECLARE_ALIGNED(16, InterpKernel, vkernel); - generate_kernels(&rnd_, hkernel, vkernel); - for (i = 0; i < h; ++i) for (j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1); uint8_t *input_ptr = CONVERT_TO_BYTEPTR(input); uint8_t *output_ptr = CONVERT_TO_BYTEPTR(output); uint8_t *output2_ptr = CONVERT_TO_BYTEPTR(output2); - - for (i = 0; i < num_iters; ++i) { - // Choose random locations within the source block - int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); - int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); - av1_highbd_wiener_convolve_add_src_c( - input_ptr + offset_r * w + offset_c, w, output_ptr, out_w, hkernel, 16, - vkernel, 16, out_w, out_h, &conv_params, bd); - test_impl(input_ptr + offset_r * w + offset_c, w, output2_ptr, out_w, - hkernel, 16, vkernel, 16, out_w, out_h, &conv_params, bd); - - for (j = 0; j < out_w * out_h; ++j) - ASSERT_EQ(output[j], output2[j]) - << "Pixel mismatch at index " << j << " = (" << (j % out_w) << ", " - << (j / out_w) << ") on iteration " << i; + for (int kernel_type = 0; kernel_type < 3; kernel_type++) { + generate_kernels(&rnd_, hkernel, vkernel, kernel_type); + for (i = 0; i < num_iters; ++i) { + // Choose random locations within the source block + int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); + int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); + av1_highbd_wiener_convolve_add_src_c( + input_ptr + offset_r * w + offset_c, w, output_ptr, out_w, hkernel, + 16, vkernel, 16, out_w, out_h, &conv_params, bd); + test_impl(input_ptr + offset_r * w + offset_c, w, output2_ptr, out_w, + hkernel, 16, vkernel, 16, out_w, out_h, &conv_params, bd); + + for (j = 0; j < out_w * out_h; ++j) + ASSERT_EQ(output[j], output2[j]) + << "Pixel mismatch at index " << j << " = (" << (j % out_w) << ", " + << (j / out_w) << ") on iteration " << i; + } } delete[] input; delete[] output; @@ -328,4 +346,5 @@ void AV1HighbdHiprecConvolveTest::RunSpeedTest( delete[] output2; } } // namespace AV1HighbdHiprecConvolve +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test diff --git a/media/libaom/src/test/hiprec_convolve_test_util.h b/media/libaom/src/test/hiprec_convolve_test_util.h index 2abe24b57..6b6da4ee8 100644 --- a/media/libaom/src/test/hiprec_convolve_test_util.h +++ b/media/libaom/src/test/hiprec_convolve_test_util.h @@ -12,6 +12,8 @@ #ifndef AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_ #define AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_ +#include <tuple> + #include "config/av1_rtcd.h" #include "test/acm_random.h" @@ -35,8 +37,7 @@ typedef void (*hiprec_convolve_func)(const uint8_t *src, ptrdiff_t src_stride, int w, int h, const ConvolveParams *conv_params); -typedef ::testing::tuple<int, int, int, hiprec_convolve_func> - HiprecConvolveParam; +typedef std::tuple<int, int, int, hiprec_convolve_func> HiprecConvolveParam; ::testing::internal::ParamGenerator<HiprecConvolveParam> BuildParams( hiprec_convolve_func filter); @@ -58,6 +59,7 @@ class AV1HiprecConvolveTest } // namespace AV1HiprecConvolve +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdHiprecConvolve { typedef void (*highbd_hiprec_convolve_func)( const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, @@ -65,7 +67,7 @@ typedef void (*highbd_hiprec_convolve_func)( const int16_t *filter_y, int y_step_q4, int w, int h, const ConvolveParams *conv_params, int bps); -typedef ::testing::tuple<int, int, int, int, highbd_hiprec_convolve_func> +typedef std::tuple<int, int, int, int, highbd_hiprec_convolve_func> HighbdHiprecConvolveParam; ::testing::internal::ParamGenerator<HighbdHiprecConvolveParam> BuildParams( @@ -87,7 +89,7 @@ class AV1HighbdHiprecConvolveTest }; } // namespace AV1HighbdHiprecConvolve - +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test #endif // AOM_TEST_HIPREC_CONVOLVE_TEST_UTIL_H_ diff --git a/media/libaom/src/test/horver_correlation_test.cc b/media/libaom/src/test/horver_correlation_test.cc new file mode 100644 index 000000000..ccb8eddd0 --- /dev/null +++ b/media/libaom/src/test/horver_correlation_test.cc @@ -0,0 +1,148 @@ +/* + * 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 <tuple> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "test/acm_random.h" +#include "test/register_state_check.h" +#include "test/util.h" + +#include "config/aom_config.h" +#include "config/aom_dsp_rtcd.h" +#include "config/av1_rtcd.h" + +#include "aom/aom_integer.h" + +using libaom_test::ACMRandom; + +namespace { +typedef void (*HorverFunc)(const int16_t *diff, int stride, int w, int h, + float *hcorr, float *vcorr); + +typedef std::tuple<const HorverFunc> HorverTestParam; + +class HorverTest : public ::testing::TestWithParam<HorverTestParam> { + public: + virtual void SetUp() { + data_buf_ = (int16_t *)aom_malloc(MAX_SB_SQUARE * sizeof(int16_t)); + ASSERT_NE(data_buf_, nullptr); + target_func_ = GET_PARAM(0); + } + virtual void TearDown() { aom_free(data_buf_); } + void RunHorverTest(void); + void RunHorverTest_ExtremeValues(void); + void RunHorverSpeedTest(int run_times); + + private: + HorverFunc target_func_; + ACMRandom rng_; + int16_t *data_buf_; +}; + +void HorverTest::RunHorverTest(void) { + for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) { + const int w = block_size_wide[block_size]; + const int h = block_size_high[block_size]; + for (int iter = 0; iter < 1000 && !HasFatalFailure(); ++iter) { + float hcorr_ref = 0.0, vcorr_ref = 0.0; + float hcorr_test = 0.0, vcorr_test = 0.0; + + for (int i = 0; i < MAX_SB_SQUARE; ++i) { + data_buf_[i] = (rng_.Rand16() % (1 << 12)) - (1 << 11); + } + + av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h, + &hcorr_ref, &vcorr_ref); + + target_func_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test); + + ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6) + << "hcorr incorrect (" << w << "x" << h << ")"; + ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6) + << "vcorr incorrect (" << w << "x" << h << ")"; + } + // printf("(%3dx%-3d) passed\n", w, h); + } +} + +void HorverTest::RunHorverSpeedTest(int run_times) { + for (int i = 0; i < MAX_SB_SQUARE; ++i) { + data_buf_[i] = rng_.Rand16() % (1 << 12); + } + + for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) { + const int w = block_size_wide[block_size]; + const int h = block_size_high[block_size]; + float hcorr_ref = 0.0, vcorr_ref = 0.0; + float hcorr_test = 0.0, vcorr_test = 0.0; + + aom_usec_timer timer; + aom_usec_timer_start(&timer); + for (int i = 0; i < run_times; ++i) { + av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h, + &hcorr_ref, &vcorr_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_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test); + } + aom_usec_timer_mark(&timer); + const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer)); + + printf("%3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", w, h, time1, time2, + time1 / time2); + } +} + +void HorverTest::RunHorverTest_ExtremeValues(void) { + for (int i = 0; i < MAX_SB_SQUARE; ++i) { + // Most of get_horver_test is squaring and summing, so simply saturating + // the whole buffer is mostly likely to cause an overflow. + data_buf_[i] = (1 << 12) - 1; + } + + for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) { + const int w = block_size_wide[block_size]; + const int h = block_size_high[block_size]; + float hcorr_ref = 0.0, vcorr_ref = 0.0; + float hcorr_test = 0.0, vcorr_test = 0.0; + + av1_get_horver_correlation_full_c(data_buf_, MAX_SB_SIZE, w, h, &hcorr_ref, + &vcorr_ref); + target_func_(data_buf_, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test); + + ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6) << "hcorr incorrect"; + ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6) << "vcorr incorrect"; + } +} + +TEST_P(HorverTest, RandomValues) { RunHorverTest(); } + +TEST_P(HorverTest, ExtremeValues) { RunHorverTest_ExtremeValues(); } + +TEST_P(HorverTest, DISABLED_Speed) { RunHorverSpeedTest(100000); } + +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P( + SSE4_1, HorverTest, + ::testing::Values(av1_get_horver_correlation_full_sse4_1)); +#endif // HAVE_SSE4_1 + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, HorverTest, ::testing::Values(av1_get_horver_correlation_full_avx2)); +#endif // HAVE_AVX2 + +} // namespace diff --git a/media/libaom/src/test/horz_superres_test.cc b/media/libaom/src/test/horz_superres_test.cc index 973f55b66..938b0b15a 100644 --- a/media/libaom/src/test/horz_superres_test.cc +++ b/media/libaom/src/test/horz_superres_test.cc @@ -9,6 +9,10 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> +#include <ostream> +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "av1/encoder/encoder.h" @@ -21,18 +25,13 @@ namespace { -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; /* TESTING PARAMETERS */ -#define NUM_TEST_VIDEOS 3 - const int kBitrate = 40; -// PSNR thresholds found by experiment -const double kPSNRThresholds[] = { 26.0, 28.0, 20.0 }; - typedef struct { const char *filename; aom_img_fmt fmt; @@ -40,18 +39,30 @@ typedef struct { unsigned int profile; unsigned int limit; unsigned int screen_content; + double psnr_threshold; } TestVideoParam; +std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) { + return os << "TestVideoParam { filename:" << test_arg.filename + << " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth + << " profile:" << test_arg.profile << " limit:" << test_arg.limit + << " screen_content:" << test_arg.screen_content + << " psnr_threshold:" << test_arg.psnr_threshold << " }"; +} + const TestVideoParam kTestVideoVectors[] = { - { "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0 }, - { "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0 }, - { "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1 }, + { "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0, 25.5 }, +#if CONFIG_AV1_HIGHBITDEPTH + { "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0, 28.0 }, +#endif + { "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1, 20.0 }, + // Image coding (single frame). + { "niklas_1280_720_30.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 1, 0, 32.0 }, }; -// Superres modes tested -// SUPERRES_QTHRESH is not included, as it has its own test -const SUPERRES_MODE kSuperresModesNotQThresh[] = { SUPERRES_FIXED, - SUPERRES_RANDOM }; +// Modes with extra params have their own tests. +const SUPERRES_MODE kSuperresModesWithoutParams[] = { SUPERRES_RANDOM, + SUPERRES_AUTO }; // Superres denominators and superres kf denominators to be tested typedef tuple<int, int> SuperresDenominatorPair; @@ -72,10 +83,8 @@ const SuperresQThresholdPair kSuperresQThresholds[] = { /* END (TESTING PARAMETERS) */ // Test parameter list: -// <[needed for EncoderTest], test_video_idx_, superres_mode_, -// tuple(superres_denom_, superres_kf_denom_)> -typedef tuple<const libaom_test::CodecFactory *, int, SUPERRES_MODE, - SuperresDenominatorPair> +// <[needed for EncoderTest], test_video_param_, superres_mode_> +typedef tuple<const libaom_test::CodecFactory *, TestVideoParam, SUPERRES_MODE> HorzSuperresTestParam; class HorzSuperresEndToEndTest @@ -83,16 +92,113 @@ class HorzSuperresEndToEndTest public ::libaom_test::EncoderTest { protected: HorzSuperresEndToEndTest() - : EncoderTest(GET_PARAM(0)), test_video_idx_(GET_PARAM(1)), - superres_mode_(GET_PARAM(2)), psnr_(0.0), frame_count_(0) { - test_video_param_ = kTestVideoVectors[test_video_idx_]; + : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), + superres_mode_(GET_PARAM(2)), psnr_(0.0), frame_count_(0) {} + + virtual ~HorzSuperresEndToEndTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(::libaom_test::kTwoPassGood); + cfg_.g_lag_in_frames = 5; + cfg_.rc_end_usage = AOM_Q; + cfg_.rc_target_bitrate = kBitrate; + cfg_.g_error_resilient = 0; + cfg_.g_profile = test_video_param_.profile; + cfg_.g_input_bit_depth = (unsigned int)test_video_param_.bit_depth; + cfg_.g_bit_depth = test_video_param_.bit_depth; + init_flags_ = AOM_CODEC_USE_PSNR; + if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; - SuperresDenominatorPair denoms = GET_PARAM(3); - superres_denom_ = ::testing::get<0>(denoms); - superres_kf_denom_ = ::testing::get<1>(denoms); + // Set superres parameters + cfg_.rc_superres_mode = superres_mode_; } - virtual ~HorzSuperresEndToEndTest() {} + virtual void BeginPassHook(unsigned int) { + psnr_ = 0.0; + frame_count_ = 0; + } + + virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { + psnr_ += pkt->data.psnr.psnr[0]; + frame_count_++; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); + encoder->Control(AV1E_SET_TILE_COLUMNS, 4); + + // Set cpu-used = 8 for speed + encoder->Control(AOME_SET_CPUUSED, 8); + + // Test screen coding tools + if (test_video_param_.screen_content) + encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); + else + encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); + + encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); + encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); + encoder->Control(AOME_SET_ARNR_STRENGTH, 5); + } + } + + double GetAveragePsnr() const { + if (frame_count_) return psnr_ / frame_count_; + return 0.0; + } + + void DoTest() { + std::unique_ptr<libaom_test::VideoSource> video; + video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, + test_video_param_.limit)); + ASSERT_TRUE(video.get() != NULL); + + ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); + const double psnr = GetAveragePsnr(); + EXPECT_GT(psnr, test_video_param_.psnr_threshold) + << "superres_mode_ = " << superres_mode_; + + EXPECT_EQ(test_video_param_.limit, frame_count_) + << "superres_mode_ = " << superres_mode_; + } + + TestVideoParam test_video_param_; + SUPERRES_MODE superres_mode_; + + private: + double psnr_; + unsigned int frame_count_; +}; + +TEST_P(HorzSuperresEndToEndTest, HorzSuperresEndToEndPSNRTest) { DoTest(); } + +AV1_INSTANTIATE_TEST_CASE(HorzSuperresEndToEndTest, + ::testing::ValuesIn(kTestVideoVectors), + ::testing::ValuesIn(kSuperresModesWithoutParams)); + +// Test parameter list: +// <[needed for EncoderTest], test_video_param_, tuple(superres_denom_, +// superres_kf_denom_)> +typedef tuple<const libaom_test::CodecFactory *, TestVideoParam, + SuperresDenominatorPair> + HorzSuperresFixedTestParam; + +class HorzSuperresFixedEndToEndTest + : public ::testing::TestWithParam<HorzSuperresFixedTestParam>, + public ::libaom_test::EncoderTest { + protected: + HorzSuperresFixedEndToEndTest() + : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), + superres_mode_(SUPERRES_FIXED), psnr_(0.0), frame_count_(0) { + SuperresDenominatorPair denoms = GET_PARAM(2); + superres_denom_ = std::get<0>(denoms); + superres_kf_denom_ = std::get<1>(denoms); + } + + virtual ~HorzSuperresFixedEndToEndTest() {} virtual void SetUp() { InitializeConfig(); @@ -125,7 +231,7 @@ class HorzSuperresEndToEndTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); encoder->Control(AV1E_SET_TILE_COLUMNS, 4); @@ -149,17 +255,15 @@ class HorzSuperresEndToEndTest return 0.0; } - double GetPsnrThreshold() { return kPSNRThresholds[test_video_idx_]; } - void DoTest() { - testing::internal::scoped_ptr<libaom_test::VideoSource> video; + std::unique_ptr<libaom_test::VideoSource> video; video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, test_video_param_.limit)); ASSERT_TRUE(video.get() != NULL); ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); const double psnr = GetAveragePsnr(); - EXPECT_GT(psnr, GetPsnrThreshold()) + EXPECT_GT(psnr, test_video_param_.psnr_threshold) << "superres_mode_ = " << superres_mode_ << ", superres_denom_ = " << superres_denom_ << ", superres_kf_denom_ = " << superres_kf_denom_; @@ -170,7 +274,6 @@ class HorzSuperresEndToEndTest << ", superres_kf_denom_ = " << superres_kf_denom_; } - int test_video_idx_; TestVideoParam test_video_param_; SUPERRES_MODE superres_mode_; int superres_denom_; @@ -181,17 +284,16 @@ class HorzSuperresEndToEndTest unsigned int frame_count_; }; -TEST_P(HorzSuperresEndToEndTest, HorzSuperresEndToEndPSNRTest) { DoTest(); } +TEST_P(HorzSuperresFixedEndToEndTest, HorzSuperresFixedTestParam) { DoTest(); } -AV1_INSTANTIATE_TEST_CASE(HorzSuperresEndToEndTest, - ::testing::Range(0, NUM_TEST_VIDEOS), - ::testing::ValuesIn(kSuperresModesNotQThresh), +AV1_INSTANTIATE_TEST_CASE(HorzSuperresFixedEndToEndTest, + ::testing::ValuesIn(kTestVideoVectors), ::testing::ValuesIn(kSuperresDenominators)); // Test parameter list: -// <[needed for EncoderTest], test_video_idx_, tuple(superres_denom_, -// superres_kf_denom_), tuple(superres_qthresh_,superres_kf_qthresh_)> -typedef tuple<const libaom_test::CodecFactory *, int, SuperresDenominatorPair, +// <[needed for EncoderTest], test_video_param_, +// tuple(superres_qthresh_,superres_kf_qthresh_)> +typedef tuple<const libaom_test::CodecFactory *, TestVideoParam, SuperresQThresholdPair> HorzSuperresQThreshTestParam; @@ -200,17 +302,11 @@ class HorzSuperresQThreshEndToEndTest public ::libaom_test::EncoderTest { protected: HorzSuperresQThreshEndToEndTest() - : EncoderTest(GET_PARAM(0)), test_video_idx_(GET_PARAM(1)), + : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), superres_mode_(SUPERRES_QTHRESH), psnr_(0.0), frame_count_(0) { - test_video_param_ = kTestVideoVectors[test_video_idx_]; - - SuperresDenominatorPair denoms = GET_PARAM(2); - superres_denom_ = ::testing::get<0>(denoms); - superres_kf_denom_ = ::testing::get<1>(denoms); - - SuperresQThresholdPair qthresholds = GET_PARAM(3); - superres_qthresh_ = ::testing::get<0>(qthresholds); - superres_kf_qthresh_ = ::testing::get<1>(qthresholds); + SuperresQThresholdPair qthresholds = GET_PARAM(2); + superres_qthresh_ = std::get<0>(qthresholds); + superres_kf_qthresh_ = std::get<1>(qthresholds); } virtual ~HorzSuperresQThreshEndToEndTest() {} @@ -230,8 +326,6 @@ class HorzSuperresQThreshEndToEndTest // Set superres parameters cfg_.rc_superres_mode = superres_mode_; - cfg_.rc_superres_denominator = superres_denom_; - cfg_.rc_superres_kf_denominator = superres_kf_denom_; cfg_.rc_superres_qthresh = superres_qthresh_; cfg_.rc_superres_kf_qthresh = superres_kf_qthresh_; } @@ -248,7 +342,7 @@ class HorzSuperresQThreshEndToEndTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); encoder->Control(AV1E_SET_TILE_COLUMNS, 0); @@ -272,36 +366,27 @@ class HorzSuperresQThreshEndToEndTest return 0.0; } - double GetPsnrThreshold() { return kPSNRThresholds[test_video_idx_]; } - void DoTest() { - testing::internal::scoped_ptr<libaom_test::VideoSource> video; + std::unique_ptr<libaom_test::VideoSource> video; video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, test_video_param_.limit)); ASSERT_TRUE(video.get() != NULL); ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); const double psnr = GetAveragePsnr(); - EXPECT_GT(psnr, GetPsnrThreshold()) + EXPECT_GT(psnr, test_video_param_.psnr_threshold) << "superres_mode_ = " << superres_mode_ - << ", superres_denom_ = " << superres_denom_ - << ", superres_kf_denom_ = " << superres_kf_denom_ << ", superres_qthresh_ = " << superres_qthresh_ << ", superres_kf_qthresh_ = " << superres_kf_qthresh_; EXPECT_EQ(test_video_param_.limit, frame_count_) << "superres_mode_ = " << superres_mode_ - << ", superres_denom_ = " << superres_denom_ - << ", superres_kf_denom_ = " << superres_kf_denom_ << ", superres_qthresh_ = " << superres_qthresh_ << ", superres_kf_qthresh_ = " << superres_kf_qthresh_; } - int test_video_idx_; TestVideoParam test_video_param_; SUPERRES_MODE superres_mode_; - int superres_denom_; - int superres_kf_denom_; int superres_qthresh_; int superres_kf_qthresh_; @@ -315,8 +400,7 @@ TEST_P(HorzSuperresQThreshEndToEndTest, HorzSuperresQThreshEndToEndPSNRTest) { } AV1_INSTANTIATE_TEST_CASE(HorzSuperresQThreshEndToEndTest, - ::testing::Range(0, NUM_TEST_VIDEOS), - ::testing::ValuesIn(kSuperresDenominators), + ::testing::ValuesIn(kTestVideoVectors), ::testing::ValuesIn(kSuperresQThresholds)); } // namespace diff --git a/media/libaom/src/test/intra_edge_test.cc b/media/libaom/src/test/intra_edge_test.cc index ce61402ac..f7702c952 100644 --- a/media/libaom/src/test/intra_edge_test.cc +++ b/media/libaom/src/test/intra_edge_test.cc @@ -100,7 +100,7 @@ TEST_P(UpsampleTest8B, RandomValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, UpsampleTest8B, ::testing::Values(TestFuncs(av1_upsample_intra_edge_c, av1_upsample_intra_edge_sse4_1))); @@ -152,7 +152,7 @@ TEST_P(UpsampleTestHB, RandomValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, UpsampleTestHB, ::testing::Values(TestFuncsHBD(av1_upsample_intra_edge_high_c, av1_upsample_intra_edge_high_sse4_1))); @@ -223,7 +223,7 @@ TEST_P(FilterEdgeTest8B, RandomValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, FilterEdgeTest8B, ::testing::Values(FilterEdgeTestFuncs(av1_filter_intra_edge_c, av1_filter_intra_edge_sse4_1))); @@ -268,10 +268,10 @@ TEST_P(FilterEdgeTestHB, RandomValues) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1, FilterEdgeTestHB, - ::testing::Values(FilterEdgeTestFuncsHBD( - av1_filter_intra_edge_high_c, - av1_filter_intra_edge_high_sse4_1))); +INSTANTIATE_TEST_SUITE_P(SSE4_1, FilterEdgeTestHB, + ::testing::Values(FilterEdgeTestFuncsHBD( + av1_filter_intra_edge_high_c, + av1_filter_intra_edge_high_sse4_1))); #endif // HAVE_SSE4_1 // Speed tests diff --git a/media/libaom/src/test/intrabc_test.cc b/media/libaom/src/test/intrabc_test.cc index 3ea421708..b57eb6fab 100644 --- a/media/libaom/src/test/intrabc_test.cc +++ b/media/libaom/src/test/intrabc_test.cc @@ -13,11 +13,11 @@ #include "config/aom_config.h" +#include "av1/common/av1_common_int.h" #include "av1/common/blockd.h" #include "av1/common/enums.h" #include "av1/common/mv.h" #include "av1/common/mvref_common.h" -#include "av1/common/onyxc_int.h" #include "av1/common/tile_common.h" namespace { @@ -156,13 +156,15 @@ TEST(IntrabcTest, DvValidation) { AV1_COMMON cm; memset(&cm, 0, sizeof(cm)); - for (int i = 0; i < static_cast<int>(GTEST_ARRAY_SIZE_(kDvCases)); ++i) { - EXPECT_EQ(static_cast<int>(kDvCases[i].valid), - av1_is_dv_valid(kDvCases[i].dv, &cm, &xd, - xd.tile.mi_row_start + kDvCases[i].mi_row_offset, - xd.tile.mi_col_start + kDvCases[i].mi_col_offset, - kDvCases[i].bsize, MAX_MIB_SIZE_LOG2)) - << "DvCases[" << i << "]"; + for (const DvTestCase &dv_case : kDvCases) { + const int mi_row = xd.tile.mi_row_start + dv_case.mi_row_offset; + const int mi_col = xd.tile.mi_col_start + dv_case.mi_col_offset; + xd.is_chroma_ref = is_chroma_reference(mi_row, mi_col, dv_case.bsize, + xd.plane[1].subsampling_x, + xd.plane[1].subsampling_y); + EXPECT_EQ(static_cast<int>(dv_case.valid), + av1_is_dv_valid(dv_case.dv, &cm, &xd, mi_row, mi_col, + dv_case.bsize, MAX_MIB_SIZE_LOG2)); } } } // namespace diff --git a/media/libaom/src/test/intrapred_test.cc b/media/libaom/src/test/intrapred_test.cc index 1a1c0fc42..779cf9a5d 100644 --- a/media/libaom/src/test/intrapred_test.cc +++ b/media/libaom/src/test/intrapred_test.cc @@ -133,6 +133,7 @@ class AV1IntraPredTest IntraPredFunc<FuncType> params_; }; +#if CONFIG_AV1_HIGHBITDEPTH class HighbdIntraPredTest : public AV1IntraPredTest<HighbdIntraPred, uint16_t> { protected: void Predict() { @@ -142,6 +143,7 @@ class HighbdIntraPredTest : public AV1IntraPredTest<HighbdIntraPred, uint16_t> { params_.pred_fn(dst_, stride_, above_row_, left_col_, bit_depth)); } }; +#endif class LowbdIntraPredTest : public AV1IntraPredTest<IntraPred, uint8_t> { protected: @@ -152,6 +154,7 @@ class LowbdIntraPredTest : public AV1IntraPredTest<IntraPred, uint8_t> { } }; +#if CONFIG_AV1_HIGHBITDEPTH // Suppress an unitialized warning. Once there are implementations to test then // this can be restored. TEST_P(HighbdIntraPredTest, Bitexact) { @@ -164,6 +167,7 @@ TEST_P(HighbdIntraPredTest, Bitexact) { av1_zero(above_data); RunTest(left_col, above_data, dst, ref_dst); } +#endif // Same issue as above but for arm. #if !HAVE_NEON @@ -179,6 +183,7 @@ TEST_P(LowbdIntraPredTest, Bitexact) { } #endif // !HAVE_NEON +#if CONFIG_AV1_HIGHBITDEPTH // ----------------------------------------------------------------------------- // High Bit Depth Tests #define highbd_entry(type, width, height, opt, bd) \ @@ -196,9 +201,9 @@ TEST_P(LowbdIntraPredTest, Bitexact) { highbd_entry(type, 16, 32, opt, bd), \ highbd_entry(type, 32, 16, opt, bd), highbd_entry(type, 32, 32, opt, bd) #endif - - // --------------------------------------------------------------------------- - // Low Bit Depth Tests +#endif // CONFIG_AV1_HIGHBITDEPTH +// --------------------------------------------------------------------------- +// Low Bit Depth Tests #define lowbd_entry(type, width, height, opt) \ IntraPredFunc<IntraPred>(&aom_##type##_predictor_##width##x##height##_##opt, \ @@ -219,8 +224,8 @@ const IntraPredFunc<IntraPred> LowbdIntraPredTestVector[] = { lowbd_intrapred(v, sse2), lowbd_intrapred(h, sse2), }; -INSTANTIATE_TEST_CASE_P(SSE2, LowbdIntraPredTest, - ::testing::ValuesIn(LowbdIntraPredTestVector)); +INSTANTIATE_TEST_SUITE_P(SSE2, LowbdIntraPredTest, + ::testing::ValuesIn(LowbdIntraPredTestVector)); #endif // HAVE_SSE2 @@ -230,8 +235,8 @@ const IntraPredFunc<IntraPred> LowbdIntraPredTestVectorSsse3[] = { lowbd_intrapred(smooth, ssse3), }; -INSTANTIATE_TEST_CASE_P(SSSE3, LowbdIntraPredTest, - ::testing::ValuesIn(LowbdIntraPredTestVectorSsse3)); +INSTANTIATE_TEST_SUITE_P(SSSE3, LowbdIntraPredTest, + ::testing::ValuesIn(LowbdIntraPredTestVectorSsse3)); #endif // HAVE_SSSE3 @@ -247,11 +252,12 @@ const IntraPredFunc<IntraPred> LowbdIntraPredTestVectorAvx2[] = { lowbd_entry(paeth, 32, 16, avx2), lowbd_entry(paeth, 32, 32, avx2), }; -INSTANTIATE_TEST_CASE_P(AVX2, LowbdIntraPredTest, - ::testing::ValuesIn(LowbdIntraPredTestVectorAvx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, LowbdIntraPredTest, + ::testing::ValuesIn(LowbdIntraPredTestVectorAvx2)); #endif // HAVE_AVX2 +#if CONFIG_AV1_HIGHBITDEPTH #if HAVE_NEON const IntraPredFunc<HighbdIntraPred> HighbdIntraPredTestVectorNeon[] = { highbd_entry(dc, 4, 4, neon, 8), highbd_entry(dc, 8, 8, neon, 8), @@ -259,8 +265,9 @@ const IntraPredFunc<HighbdIntraPred> HighbdIntraPredTestVectorNeon[] = { highbd_entry(dc, 64, 64, neon, 8), }; -INSTANTIATE_TEST_CASE_P(NEON, HighbdIntraPredTest, - ::testing::ValuesIn(HighbdIntraPredTestVectorNeon)); +INSTANTIATE_TEST_SUITE_P(NEON, HighbdIntraPredTest, + ::testing::ValuesIn(HighbdIntraPredTestVectorNeon)); #endif // HAVE_NEON +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/invalid_file_test.cc b/media/libaom/src/test/invalid_file_test.cc index 5b4f5a6c3..dd0956d0c 100644 --- a/media/libaom/src/test/invalid_file_test.cc +++ b/media/libaom/src/test/invalid_file_test.cc @@ -10,6 +10,7 @@ */ #include <cstdio> +#include <ostream> #include <string> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -23,10 +24,20 @@ namespace { struct DecodeParam { int threads; const char *filename; + const char *res_filename; // If NULL, the result filename is + // filename + ".res". }; +// Constructs result file name. +std::string GetResFilename(const DecodeParam ¶m) { + if (param.res_filename != NULL) return param.res_filename; + const std::string filename = param.filename; + return filename + ".res"; +} + std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) { - return os << "threads: " << dp.threads << " file: " << dp.filename; + return os << "threads: " << dp.threads << " file: " << dp.filename + << " result file: " << GetResFilename(dp); } class InvalidFileTest : public ::libaom_test::DecoderTest, @@ -44,6 +55,11 @@ class InvalidFileTest : public ::libaom_test::DecoderTest, << "Result file open failed. Filename: " << res_file_name; } + virtual void DecompressedFrameHook(const aom_image_t &img, + const unsigned int /*frame_number*/) { + EXPECT_NE(img.fb_priv, nullptr); + } + virtual bool HandleDecodeResult( const aom_codec_err_t res_dec, const libaom_test::CompressedVideoSource &video, @@ -85,16 +101,16 @@ class InvalidFileTest : public ::libaom_test::DecoderTest, void RunTest() { const DecodeParam input = GET_PARAM(1); - aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH, { 1 } }; + aom_codec_dec_cfg_t cfg = { 0, 0, 0, !FORCE_HIGHBITDEPTH_DECODING }; cfg.threads = input.threads; const std::string filename = input.filename; libaom_test::IVFVideoSource decode_video(filename); decode_video.Init(); - // Construct result file name. The file holds a list of expected integer - // results, one for each decoded frame. Any result that doesn't match - // the files list will cause a test failure. - const std::string res_filename = filename + ".res"; + // The result file holds a list of expected integer results, one for each + // decoded frame. Any result that doesn't match the file's list will + // cause a test failure. + const std::string res_filename = GetResFilename(input); OpenResFile(res_filename); ASSERT_NO_FATAL_FAILURE(RunLoop(&decode_video, cfg)); @@ -106,14 +122,35 @@ class InvalidFileTest : public ::libaom_test::DecoderTest, TEST_P(InvalidFileTest, ReturnCode) { RunTest(); } +// If res_filename (the third field) is NULL, then the result filename is +// filename + ".res" by default. Set res_filename to a string if the result +// filename differs from the default. 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" }, + // { threads, filename, res_filename } + { 1, "invalid-bug-1814.ivf", NULL }, + { 1, "invalid-chromium-906381.ivf", NULL }, + { 1, "invalid-google-142530197.ivf", NULL }, + { 1, "invalid-google-142530197-1.ivf", NULL }, + { 4, "invalid-oss-fuzz-9463.ivf", "invalid-oss-fuzz-9463.ivf.res.2" }, + { 1, "invalid-oss-fuzz-9720.ivf", NULL }, + { 1, "invalid-oss-fuzz-10389.ivf", "invalid-oss-fuzz-10389.ivf.res.2" }, + { 1, "invalid-oss-fuzz-11523.ivf", "invalid-oss-fuzz-11523.ivf.res.2" }, + { 4, "invalid-oss-fuzz-15363.ivf", NULL }, + { 1, "invalid-oss-fuzz-16437.ivf", NULL }, +#if CONFIG_AV1_HIGHBITDEPTH + // These test vectors contain 10-bit or 12-bit video. + { 1, "invalid-oss-fuzz-9288.ivf", NULL }, + { 1, "invalid-oss-fuzz-9482.ivf", NULL }, + { 1, "invalid-oss-fuzz-10061.ivf", NULL }, + { 1, "invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf", NULL }, + { 1, "invalid-oss-fuzz-10227.ivf", NULL }, + { 4, "invalid-oss-fuzz-10555.ivf", NULL }, + { 1, "invalid-oss-fuzz-10705.ivf", NULL }, + { 1, "invalid-oss-fuzz-10723.ivf", "invalid-oss-fuzz-10723.ivf.res.2" }, + { 1, "invalid-oss-fuzz-10779.ivf", NULL }, + { 1, "invalid-oss-fuzz-11477.ivf", NULL }, + { 1, "invalid-oss-fuzz-11479.ivf", "invalid-oss-fuzz-11479.ivf.res.2" }, +#endif }; AV1_INSTANTIATE_TEST_CASE(InvalidFileTest, diff --git a/media/libaom/src/test/level_test.cc b/media/libaom/src/test/level_test.cc new file mode 100644 index 000000000..a9613c5f7 --- /dev/null +++ b/media/libaom/src/test/level_test.cc @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ +#include <memory> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" +#include "test/y4m_video_source.h" +#include "test/yuv_video_source.h" + +namespace { +const int kLevelMin = 0; +const int kLevelMax = 31; +const int kLevelKeepStats = 24; +// Speed settings tested +static const int kCpuUsedVectors[] = { + 1, + 2, + 3, + 4, +}; + +class LevelTest + : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>, + public ::libaom_test::EncoderTest { + protected: + LevelTest() + : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), + cpu_used_(GET_PARAM(2)), target_level_(31) {} + + virtual ~LevelTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(encoding_mode_); + if (encoding_mode_ != ::libaom_test::kRealTime) { + cfg_.g_lag_in_frames = 5; + cfg_.rc_end_usage = AOM_VBR; + } else { + cfg_.g_lag_in_frames = 0; + cfg_.rc_end_usage = AOM_CBR; + cfg_.rc_buf_sz = 1000; + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 600; + } + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AOME_SET_CPUUSED, cpu_used_); + encoder->Control(AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level_); + if (encoding_mode_ != ::libaom_test::kRealTime) { + encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); + encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); + encoder->Control(AOME_SET_ARNR_STRENGTH, 5); + } + } + + encoder->Control(AV1E_GET_SEQ_LEVEL_IDX, level_); + ASSERT_LE(level_[0], kLevelMax); + ASSERT_GE(level_[0], kLevelMin); + } + + libaom_test::TestMode encoding_mode_; + int cpu_used_; + int target_level_; + int level_[32]; +}; + +TEST_P(LevelTest, TestTargetLevelApi) { + static const aom_codec_iface_t *codec = &aom_codec_av1_cx_algo; + aom_codec_ctx_t enc; + aom_codec_enc_cfg_t cfg; + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(codec, &cfg, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, codec, &cfg, 0)); + for (int operating_point = 0; operating_point <= 32; ++operating_point) { + for (int level = 0; level <= 32; ++level) { + const int target_level = operating_point * 100 + level; + if ((level <= 24 && level != 2 && level != 3 && level != 6 && + level != 7 && level != 10 && level != 11 && level != 20 && + level != 21 && level != 22 && level != 23) || + level == 31 || operating_point > 31) { + EXPECT_EQ(AOM_CODEC_OK, + AOM_CODEC_CONTROL_TYPECHECKED( + &enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level)); + } else { + EXPECT_EQ(AOM_CODEC_INVALID_PARAM, + AOM_CODEC_CONTROL_TYPECHECKED( + &enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level)); + } + } + } + EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc)); +} + +TEST_P(LevelTest, TestTargetLevel19) { + std::unique_ptr<libaom_test::VideoSource> video; + video.reset(new libaom_test::Y4mVideoSource("park_joy_90p_8_420.y4m", 0, 10)); + ASSERT_TRUE(video.get() != NULL); + // Level index 19 corresponding to level 6.3. + target_level_ = 19; + ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); +} + +TEST_P(LevelTest, TestLevelMonitoringLowBitrate) { + // To save run time, we only test speed 4. + if (cpu_used_ == 4) { + libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 40); + target_level_ = kLevelKeepStats; + cfg_.rc_target_bitrate = 1000; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_EQ(level_[0], 0); + } +} + +TEST_P(LevelTest, TestLevelMonitoringHighBitrate) { + // To save run time, we only test speed 4. + if (cpu_used_ == 4) { + libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 40); + target_level_ = kLevelKeepStats; + cfg_.rc_target_bitrate = 4000; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_EQ(level_[0], 1); + } +} + +TEST_P(LevelTest, TestTargetLevel0) { + // To save run time, we only test speed 4. + if (cpu_used_ == 4) { + libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 50); + const int target_level = 0; + target_level_ = target_level; + cfg_.rc_target_bitrate = 4000; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_EQ(level_[0], target_level); + } +} + +AV1_INSTANTIATE_TEST_CASE(LevelTest, + ::testing::Values(::libaom_test::kTwoPassGood), + ::testing::ValuesIn(kCpuUsedVectors)); +} // namespace diff --git a/media/libaom/src/test/lightfield_test.sh b/media/libaom/src/test/lightfield_test.sh index b957a6b79..3de88af87 100644 --- a/media/libaom/src/test/lightfield_test.sh +++ b/media/libaom/src/test/lightfield_test.sh @@ -46,17 +46,34 @@ lightfield_test() { [ -e "${lf_file}" ] || return 1 + # Check to ensure all camera frames have the identical frame header. If not identical, this test fails. + for i in ./fh*; do + diff ./fh004 $i > /dev/null + if [ $? -eq 1 ]; then + return 1 + fi + done + + # Check to ensure all camera frames use the identical frame context. If not identical, this test fails. + for i in ./fc*; do + diff ./fc004 $i > /dev/null + if [ $? -eq 1 ]; then + return 1 + fi + done + # Parse lightfield bitstream to construct and output a new bitstream that can # be decoded by an AV1 decoder. local bs_decoder="${LIBAOM_BIN_PATH}/lightfield_bitstream_parsing${AOM_TEST_EXE_SUFFIX}" local tl_file="${AOM_TEST_OUTPUT_DIR}/vase_tile_list.ivf" + local tl_text_file="${LIBAOM_TEST_DATA_PATH}/vase10x10_tiles.txt" if [ ! -x "${bs_decoder}" ]; then elog "${bs_decoder} does not exist or is not executable." return 1 fi eval "${AOM_TEST_PREFIX}" "${bs_decoder}" "${lf_file}" "${tl_file}" \ - "${num_references}" ${devnull} + "${num_references}" "${tl_text_file}" ${devnull} [ -e "${tl_file}" ] || return 1 @@ -82,7 +99,7 @@ lightfield_test() { fi eval "${AOM_TEST_PREFIX}" "${ref_decoder}" "${lf_file}" "${tl_reffile}" \ - "${num_references}" ${devnull} + "${num_references}" "${tl_text_file}" ${devnull} [ -e "${tl_reffile}" ] || return 1 diff --git a/media/libaom/src/test/lossless_test.cc b/media/libaom/src/test/lossless_test.cc index 3f8e89c81..71ae5e72b 100644 --- a/media/libaom/src/test/lossless_test.cc +++ b/media/libaom/src/test/lossless_test.cc @@ -40,7 +40,7 @@ class LosslessTestLarge virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { // Only call Control if quantizer > 0 to verify that using quantizer // alone will activate lossless if (cfg_.rc_max_quantizer > 0 || cfg_.rc_min_quantizer > 0) { diff --git a/media/libaom/src/test/lpf_test.cc b/media/libaom/src/test/lpf_test.cc index 451bffd2a..e8eeceb7c 100644 --- a/media/libaom/src/test/lpf_test.cc +++ b/media/libaom/src/test/lpf_test.cc @@ -12,6 +12,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -50,11 +51,11 @@ typedef void (*dual_loop_op_t)(uint8_t *s, DUAL_LOOP_PARAM); typedef void (*hbdloop_op_t)(uint16_t *s, LOOP_PARAM, int bd); typedef void (*hbddual_loop_op_t)(uint16_t *s, DUAL_LOOP_PARAM, int bd); -typedef ::testing::tuple<hbdloop_op_t, hbdloop_op_t, int> hbdloop_param_t; -typedef ::testing::tuple<hbddual_loop_op_t, hbddual_loop_op_t, int> +typedef std::tuple<hbdloop_op_t, hbdloop_op_t, int> hbdloop_param_t; +typedef std::tuple<hbddual_loop_op_t, hbddual_loop_op_t, int> hbddual_loop_param_t; -typedef ::testing::tuple<loop_op_t, loop_op_t, int> loop_param_t; -typedef ::testing::tuple<dual_loop_op_t, dual_loop_op_t, int> dual_loop_param_t; +typedef std::tuple<loop_op_t, loop_op_t, int> loop_param_t; +typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dual_loop_param_t; template <typename Pixel_t, int PIXEL_WIDTH_t> void InitInput(Pixel_t *s, Pixel_t *ref_s, ACMRandom *rnd, const uint8_t limit, @@ -72,9 +73,9 @@ void InitInput(Pixel_t *s, Pixel_t *ref_s, ACMRandom *rnd, const uint8_t limit, if (j < 1) { tmp_s[j] = rnd->Rand16(); } else if (val & 0x20) { // Increment by a value within the limit. - tmp_s[j] = tmp_s[j - 1] + (limit - 1); + tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] + (limit - 1)); } else { // Decrement by a value within the limit. - tmp_s[j] = tmp_s[j - 1] - (limit - 1); + tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] - (limit - 1)); } j++; } @@ -91,11 +92,11 @@ void InitInput(Pixel_t *s, Pixel_t *ref_s, ACMRandom *rnd, const uint8_t limit, if (j < 1) { tmp_s[j] = rnd->Rand16(); } else if (val & 0x20) { // Increment by a value within the limit. - tmp_s[(j % 32) * 32 + j / 32] = - tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1); + tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>( + tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1)); } else { // Decrement by a value within the limit. - tmp_s[(j % 32) * 32 + j / 32] = - tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1); + tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>( + tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1)); } j++; } @@ -129,9 +130,9 @@ class LoopTestParam : public ::testing::TestWithParam<params_t> { public: virtual ~LoopTestParam() {} virtual void SetUp() { - loopfilter_op_ = ::testing::get<0>(this->GetParam()); - ref_loopfilter_op_ = ::testing::get<1>(this->GetParam()); - bit_depth_ = ::testing::get<2>(this->GetParam()); + loopfilter_op_ = std::get<0>(this->GetParam()); + ref_loopfilter_op_ = std::get<1>(this->GetParam()); + bit_depth_ = std::get<2>(this->GetParam()); mask_ = (1 << bit_depth_) - 1; } @@ -144,26 +145,30 @@ class LoopTestParam : public ::testing::TestWithParam<params_t> { func_type_t ref_loopfilter_op_; }; +#if CONFIG_AV1_HIGHBITDEPTH void call_filter(uint16_t *s, LOOP_PARAM, int bd, hbdloop_op_t op) { op(s, p, blimit, limit, thresh, bd); } -void call_filter(uint8_t *s, LOOP_PARAM, int bd, loop_op_t op) { - (void)bd; - op(s, p, blimit, limit, thresh); -} void call_dualfilter(uint16_t *s, DUAL_LOOP_PARAM, int bd, hbddual_loop_op_t op) { op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1, bd); } +#endif +void call_filter(uint8_t *s, LOOP_PARAM, int bd, loop_op_t op) { + (void)bd; + op(s, p, blimit, limit, thresh); +} void call_dualfilter(uint8_t *s, DUAL_LOOP_PARAM, int bd, dual_loop_op_t op) { (void)bd; op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1); }; +#if CONFIG_AV1_HIGHBITDEPTH typedef LoopTestParam<hbdloop_op_t, hbdloop_param_t> Loop8Test6Param_hbd; -typedef LoopTestParam<loop_op_t, loop_param_t> Loop8Test6Param_lbd; typedef LoopTestParam<hbddual_loop_op_t, hbddual_loop_param_t> Loop8Test9Param_hbd; +#endif +typedef LoopTestParam<loop_op_t, loop_param_t> Loop8Test6Param_lbd; typedef LoopTestParam<dual_loop_op_t, dual_loop_param_t> Loop8Test9Param_lbd; #define OPCHECK(a, b) \ @@ -206,7 +211,9 @@ typedef LoopTestParam<dual_loop_op_t, dual_loop_param_t> Loop8Test9Param_lbd; "loopfilter output. " \ << "First failed at test case " << first_failure; +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test6Param_hbd, OperationCheck) { OPCHECK(uint16_t, 16); } +#endif TEST_P(Loop8Test6Param_lbd, OperationCheck) { OPCHECK(uint8_t, 8); } #define VALCHECK(a, b) \ @@ -252,7 +259,9 @@ TEST_P(Loop8Test6Param_lbd, OperationCheck) { OPCHECK(uint8_t, 8); } "loopfilter output. " \ << "First failed at test case " << first_failure; +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test6Param_hbd, ValueCheck) { VALCHECK(uint16_t, 16); } +#endif TEST_P(Loop8Test6Param_lbd, ValueCheck) { VALCHECK(uint8_t, 8); } #define SPEEDCHECK(a, b) \ @@ -280,7 +289,9 @@ TEST_P(Loop8Test6Param_lbd, ValueCheck) { VALCHECK(uint8_t, 8); } call_filter(s + 8 + p * 8, p, blimit, limit, thresh, bd, loopfilter_op_); \ } +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test6Param_hbd, DISABLED_Speed) { SPEEDCHECK(uint16_t, 16); } +#endif TEST_P(Loop8Test6Param_lbd, DISABLED_Speed) { SPEEDCHECK(uint8_t, 8); } #define OPCHECKd(a, b) \ @@ -337,7 +348,9 @@ TEST_P(Loop8Test6Param_lbd, DISABLED_Speed) { SPEEDCHECK(uint8_t, 8); } "loopfilter output. " \ << "First failed at test case " << first_failure; +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test9Param_hbd, OperationCheck) { OPCHECKd(uint16_t, 16); } +#endif TEST_P(Loop8Test9Param_lbd, OperationCheck) { OPCHECKd(uint8_t, 8); } #define VALCHECKd(a, b) \ @@ -396,7 +409,9 @@ TEST_P(Loop8Test9Param_lbd, OperationCheck) { OPCHECKd(uint8_t, 8); } "loopfilter output. " \ << "First failed at test case " << first_failure; +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test9Param_hbd, ValueCheck) { VALCHECKd(uint16_t, 16); } +#endif TEST_P(Loop8Test9Param_lbd, ValueCheck) { VALCHECKd(uint8_t, 8); } #define SPEEDCHECKd(a, b) \ @@ -436,13 +451,15 @@ TEST_P(Loop8Test9Param_lbd, ValueCheck) { VALCHECKd(uint8_t, 8); } limit1, thresh1, bit_depth_, loopfilter_op_); \ } +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(Loop8Test9Param_hbd, DISABLED_Speed) { SPEEDCHECKd(uint16_t, 16); } +#endif TEST_P(Loop8Test9Param_lbd, DISABLED_Speed) { SPEEDCHECKd(uint8_t, 8); } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSE2 - +#if CONFIG_AV1_HIGHBITDEPTH const hbdloop_param_t kHbdLoop8Test6[] = { make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c, 8), @@ -486,8 +503,9 @@ const hbdloop_param_t kHbdLoop8Test6[] = { make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 12) }; -INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test6Param_hbd, - ::testing::ValuesIn(kHbdLoop8Test6)); +INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test6Param_hbd, + ::testing::ValuesIn(kHbdLoop8Test6)); +#endif // CONFIG_AV1_HIGHBITDEPTH const loop_param_t kLoop8Test6[] = { make_tuple(&aom_lpf_horizontal_4_sse2, &aom_lpf_horizontal_4_c, 8), @@ -500,8 +518,8 @@ const loop_param_t kLoop8Test6[] = { make_tuple(&aom_lpf_vertical_14_sse2, &aom_lpf_vertical_14_c, 8), }; -INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test6Param_lbd, - ::testing::ValuesIn(kLoop8Test6)); +INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test6Param_lbd, + ::testing::ValuesIn(kLoop8Test6)); const dual_loop_param_t kLoop8Test9[] = { make_tuple(&aom_lpf_horizontal_4_dual_sse2, &aom_lpf_horizontal_4_dual_c, 8), @@ -515,12 +533,12 @@ const dual_loop_param_t kLoop8Test9[] = { make_tuple(&aom_lpf_vertical_14_dual_sse2, &aom_lpf_vertical_14_dual_c, 8) }; -INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test9Param_lbd, - ::testing::ValuesIn(kLoop8Test9)); +INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test9Param_lbd, + ::testing::ValuesIn(kLoop8Test9)); #endif // HAVE_SSE2 -#if HAVE_SSE2 +#if HAVE_SSE2 && CONFIG_AV1_HIGHBITDEPTH const hbddual_loop_param_t kHbdLoop8Test9[] = { make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2, &aom_highbd_lpf_horizontal_4_dual_c, 8), @@ -572,10 +590,10 @@ const hbddual_loop_param_t kHbdLoop8Test9[] = { &aom_highbd_lpf_vertical_14_dual_c, 12), }; -INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test9Param_hbd, - ::testing::ValuesIn(kHbdLoop8Test9)); +INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test9Param_hbd, + ::testing::ValuesIn(kHbdLoop8Test9)); -#endif // HAVE_SSE2 +#endif // HAVE_SSE2 && CONFIG_AV1_HIGHBITDEPTH #if HAVE_NEON const loop_param_t kLoop8Test6[] = { @@ -589,11 +607,11 @@ const loop_param_t kLoop8Test6[] = { make_tuple(&aom_lpf_horizontal_4_neon, &aom_lpf_horizontal_4_c, 8) }; -INSTANTIATE_TEST_CASE_P(NEON, Loop8Test6Param_lbd, - ::testing::ValuesIn(kLoop8Test6)); +INSTANTIATE_TEST_SUITE_P(NEON, Loop8Test6Param_lbd, + ::testing::ValuesIn(kLoop8Test6)); #endif // HAVE_NEON -#if HAVE_AVX2 +#if HAVE_AVX2 && CONFIG_AV1_HIGHBITDEPTH const hbddual_loop_param_t kHbdLoop8Test9Avx2[] = { make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2, &aom_highbd_lpf_horizontal_4_dual_c, 8), @@ -621,7 +639,7 @@ const hbddual_loop_param_t kHbdLoop8Test9Avx2[] = { &aom_highbd_lpf_vertical_8_dual_c, 12), }; -INSTANTIATE_TEST_CASE_P(AVX2, Loop8Test9Param_hbd, - ::testing::ValuesIn(kHbdLoop8Test9Avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, Loop8Test9Param_hbd, + ::testing::ValuesIn(kHbdLoop8Test9Avx2)); #endif } // namespace diff --git a/media/libaom/src/test/masked_sad_test.cc b/media/libaom/src/test/masked_sad_test.cc index 311f1877d..aa4dd8341 100644 --- a/media/libaom/src/test/masked_sad_test.cc +++ b/media/libaom/src/test/masked_sad_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/acm_random.h" @@ -33,9 +34,37 @@ typedef unsigned int (*MaskedSADFunc)(const uint8_t *src, int src_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask); -typedef ::testing::tuple<MaskedSADFunc, MaskedSADFunc> MaskedSADParam; +typedef std::tuple<MaskedSADFunc, MaskedSADFunc> MaskedSADParam; -class MaskedSADTest : public ::testing::TestWithParam<MaskedSADParam> { +typedef void (*MaskedSADx4Func)(const uint8_t *src, int src_stride, + const uint8_t *ref[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int invert_mask, + unsigned sads[]); + +typedef std::tuple<MaskedSADx4Func, MaskedSADx4Func> MaskedSADx4Param; + +class MaskedSADTestBase : public ::testing::Test { + public: + virtual ~MaskedSADTestBase() {} + virtual void SetUp() = 0; + virtual void runRef(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], + int times) = 0; + virtual void runTest(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], + int times) = 0; + + virtual void TearDown() { libaom_test::ClearSystemState(); } + void runMaskedSADTest(int run_times); +}; + +class MaskedSADTest : public MaskedSADTestBase, + public ::testing::WithParamInterface<MaskedSADParam> { public: virtual ~MaskedSADTest() {} virtual void SetUp() { @@ -43,20 +72,113 @@ class MaskedSADTest : public ::testing::TestWithParam<MaskedSADParam> { ref_maskedSAD_op_ = GET_PARAM(1); } - virtual void TearDown() { libaom_test::ClearSystemState(); } - void runMaskedSADTest(int run_times); + virtual void runRef(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], int times); + virtual void runTest(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], + int times); protected: MaskedSADFunc maskedSAD_op_; MaskedSADFunc ref_maskedSAD_op_; }; -void MaskedSADTest::runMaskedSADTest(int run_times) { - unsigned int ref_ret = 0, ret = 1; + +class MaskedSADx4Test : public MaskedSADTestBase, + public ::testing::WithParamInterface<MaskedSADx4Param> { + public: + virtual ~MaskedSADx4Test() {} + virtual void SetUp() { + maskedSAD_op_ = GET_PARAM(0); + ref_maskedSAD_op_ = GET_PARAM(1); + } + virtual void runRef(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], int times); + virtual void runTest(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int inv_mask, unsigned sads[], + int times); + + protected: + MaskedSADx4Func maskedSAD_op_; + MaskedSADx4Func ref_maskedSAD_op_; +}; + +void MaskedSADTest::runRef(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int invert_mask, unsigned sads[], + int times) { + for (int repeat = 0; repeat < times; ++repeat) { + sads[0] = ref_maskedSAD_op_(src_ptr, src_stride, ref_ptr[0], ref_stride, + second_pred, msk, msk_stride, invert_mask); + } +} + +void MaskedSADTest::runTest(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int invert_mask, unsigned sads[], + int times) { + if (times == 1) { + sads[0] = maskedSAD_op_(src_ptr, src_stride, ref_ptr[0], ref_stride, + second_pred, msk, msk_stride, invert_mask); + } else { + for (int repeat = 0; repeat < times; ++repeat) { + ASM_REGISTER_STATE_CHECK( + sads[0] = maskedSAD_op_(src_ptr, src_stride, ref_ptr[0], ref_stride, + second_pred, msk, msk_stride, invert_mask)); + } + } +} + +void MaskedSADx4Test::runRef(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int invert_mask, unsigned sads[], + int times) { + for (int repeat = 0; repeat < times; ++repeat) { + ref_maskedSAD_op_(src_ptr, src_stride, ref_ptr, ref_stride, second_pred, + msk, msk_stride, invert_mask, sads); + } +} + +void MaskedSADx4Test::runTest(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr[], int ref_stride, + const uint8_t *second_pred, const uint8_t *msk, + int msk_stride, int invert_mask, unsigned sads[], + int times) { + if (times == 1) { + ASM_REGISTER_STATE_CHECK(maskedSAD_op_(src_ptr, src_stride, ref_ptr, + ref_stride, second_pred, msk, + msk_stride, invert_mask, sads)); + } else { + for (int repeat = 0; repeat < times; ++repeat) { + maskedSAD_op_(src_ptr, src_stride, ref_ptr, ref_stride, second_pred, msk, + msk_stride, invert_mask, sads); + } + } +} + +void MaskedSADTestBase::runMaskedSADTest(int run_times) { ACMRandom rnd(ACMRandom::DeterministicSeed()); + const unsigned kBlockSize = MAX_SB_SIZE * MAX_SB_SIZE; DECLARE_ALIGNED(16, uint8_t, src_ptr[MAX_SB_SIZE * MAX_SB_SIZE]); - DECLARE_ALIGNED(16, uint8_t, ref_ptr[MAX_SB_SIZE * MAX_SB_SIZE]); + DECLARE_ALIGNED(16, uint8_t, ref_ptr[MAX_SB_SIZE * MAX_SB_SIZE * 4]); DECLARE_ALIGNED(16, uint8_t, second_pred_ptr[MAX_SB_SIZE * MAX_SB_SIZE]); DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE * MAX_SB_SIZE]); + + const uint8_t *refs[] = { ref_ptr, ref_ptr + kBlockSize, + ref_ptr + 2 * kBlockSize, + ref_ptr + 3 * kBlockSize }; + unsigned sads[] = { 0, 0, 0, 0 }; + unsigned sads_ref[] = { 0, 0, 0, 0 }; int err_count = 0; int first_failure = -1; int src_stride = MAX_SB_SIZE; @@ -67,6 +189,9 @@ void MaskedSADTest::runMaskedSADTest(int run_times) { for (int j = 0; j < MAX_SB_SIZE * MAX_SB_SIZE; j++) { src_ptr[j] = rnd.Rand8(); ref_ptr[j] = rnd.Rand8(); + (ref_ptr + kBlockSize)[j] = rnd.Rand8(); + (ref_ptr + 2 * kBlockSize)[j] = rnd.Rand8(); + (ref_ptr + 3 * kBlockSize)[j] = rnd.Rand8(); second_pred_ptr[j] = rnd.Rand8(); msk_ptr[j] = ((rnd.Rand8() & 0x7f) > 64) ? rnd.Rand8() & 0x3f : 64; assert(msk_ptr[j] <= 64); @@ -75,33 +200,23 @@ void MaskedSADTest::runMaskedSADTest(int run_times) { for (int invert_mask = 0; invert_mask < 2; ++invert_mask) { aom_usec_timer timer; aom_usec_timer_start(&timer); - for (int repeat = 0; repeat < run_times; ++repeat) { - ref_ret = ref_maskedSAD_op_(src_ptr, src_stride, ref_ptr, ref_stride, - second_pred_ptr, msk_ptr, msk_stride, - invert_mask); - } + runRef(src_ptr, src_stride, refs, ref_stride, second_pred_ptr, msk_ptr, + msk_stride, invert_mask, sads_ref, run_times); aom_usec_timer_mark(&timer); const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer)); + aom_usec_timer_start(&timer); - if (run_times == 1) { - ASM_REGISTER_STATE_CHECK(ret = maskedSAD_op_(src_ptr, src_stride, - ref_ptr, ref_stride, - second_pred_ptr, msk_ptr, - msk_stride, invert_mask)); - } else { - for (int repeat = 0; repeat < run_times; ++repeat) { - ret = - maskedSAD_op_(src_ptr, src_stride, ref_ptr, ref_stride, - second_pred_ptr, msk_ptr, msk_stride, invert_mask); - } - } + runTest(src_ptr, src_stride, refs, ref_stride, second_pred_ptr, msk_ptr, + msk_stride, invert_mask, sads, run_times); aom_usec_timer_mark(&timer); const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer)); + if (run_times > 10) { printf("%7.2f/%7.2fns", time1, time2); printf("(%3.2f)\n", time1 / time2); } - if (ret != ref_ret) { + if (sads_ref[0] != sads[0] || sads_ref[1] != sads[1] || + sads_ref[2] != sads[2] || sads_ref[3] != sads[3]) { err_count++; if (first_failure == -1) first_failure = i; } @@ -115,12 +230,17 @@ TEST_P(MaskedSADTest, OperationCheck) { runMaskedSADTest(1); } TEST_P(MaskedSADTest, DISABLED_Speed) { runMaskedSADTest(2000000); } +TEST_P(MaskedSADx4Test, OperationCheck) { runMaskedSADTest(1); } + +TEST_P(MaskedSADx4Test, DISABLED_Speed) { runMaskedSADTest(2000000); } + +#if CONFIG_AV1_HIGHBITDEPTH typedef unsigned int (*HighbdMaskedSADFunc)(const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask); -typedef ::testing::tuple<HighbdMaskedSADFunc, HighbdMaskedSADFunc> +typedef std::tuple<HighbdMaskedSADFunc, HighbdMaskedSADFunc> HighbdMaskedSADParam; class HighbdMaskedSADTest @@ -206,8 +326,9 @@ void HighbdMaskedSADTest::runHighbdMaskedSADTest(int run_times) { TEST_P(HighbdMaskedSADTest, OperationCheck) { runHighbdMaskedSADTest(1); } TEST_P(HighbdMaskedSADTest, DISABLED_Speed) { runHighbdMaskedSADTest(1000000); } +#endif // CONFIG_AV1_HIGHBITDEPTH -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSSE3 const MaskedSADParam msad_test[] = { @@ -235,8 +356,37 @@ const MaskedSADParam msad_test[] = { make_tuple(&aom_masked_sad64x16_ssse3, &aom_masked_sad64x16_c), }; -INSTANTIATE_TEST_CASE_P(SSSE3, MaskedSADTest, ::testing::ValuesIn(msad_test)); +INSTANTIATE_TEST_SUITE_P(SSSE3, MaskedSADTest, ::testing::ValuesIn(msad_test)); + +const MaskedSADx4Param msadx4_test[] = { + make_tuple(&aom_masked_sad4x4x4d_ssse3, &aom_masked_sad4x4x4d_c), + make_tuple(&aom_masked_sad4x8x4d_ssse3, &aom_masked_sad4x8x4d_c), + make_tuple(&aom_masked_sad8x4x4d_ssse3, &aom_masked_sad8x4x4d_c), + make_tuple(&aom_masked_sad8x8x4d_ssse3, &aom_masked_sad8x8x4d_c), + make_tuple(&aom_masked_sad8x16x4d_ssse3, &aom_masked_sad8x16x4d_c), + make_tuple(&aom_masked_sad16x8x4d_ssse3, &aom_masked_sad16x8x4d_c), + make_tuple(&aom_masked_sad16x16x4d_ssse3, &aom_masked_sad16x16x4d_c), + make_tuple(&aom_masked_sad16x32x4d_ssse3, &aom_masked_sad16x32x4d_c), + make_tuple(&aom_masked_sad32x16x4d_ssse3, &aom_masked_sad32x16x4d_c), + make_tuple(&aom_masked_sad32x32x4d_ssse3, &aom_masked_sad32x32x4d_c), + make_tuple(&aom_masked_sad32x64x4d_ssse3, &aom_masked_sad32x64x4d_c), + make_tuple(&aom_masked_sad64x32x4d_ssse3, &aom_masked_sad64x32x4d_c), + make_tuple(&aom_masked_sad64x64x4d_ssse3, &aom_masked_sad64x64x4d_c), + make_tuple(&aom_masked_sad64x128x4d_ssse3, &aom_masked_sad64x128x4d_c), + make_tuple(&aom_masked_sad128x64x4d_ssse3, &aom_masked_sad128x64x4d_c), + make_tuple(&aom_masked_sad128x128x4d_ssse3, &aom_masked_sad128x128x4d_c), + make_tuple(&aom_masked_sad4x16x4d_ssse3, &aom_masked_sad4x16x4d_c), + make_tuple(&aom_masked_sad16x4x4d_ssse3, &aom_masked_sad16x4x4d_c), + make_tuple(&aom_masked_sad8x32x4d_ssse3, &aom_masked_sad8x32x4d_c), + make_tuple(&aom_masked_sad32x8x4d_ssse3, &aom_masked_sad32x8x4d_c), + make_tuple(&aom_masked_sad16x64x4d_ssse3, &aom_masked_sad16x64x4d_c), + make_tuple(&aom_masked_sad64x16x4d_ssse3, &aom_masked_sad64x16x4d_c), +}; + +INSTANTIATE_TEST_SUITE_P(SSSE3, MaskedSADx4Test, + ::testing::ValuesIn(msadx4_test)); +#if CONFIG_AV1_HIGHBITDEPTH const HighbdMaskedSADParam hbd_msad_test[] = { make_tuple(&aom_highbd_masked_sad4x4_ssse3, &aom_highbd_masked_sad4x4_c), make_tuple(&aom_highbd_masked_sad4x8_ssse3, &aom_highbd_masked_sad4x8_c), @@ -265,8 +415,9 @@ const HighbdMaskedSADParam hbd_msad_test[] = { make_tuple(&aom_highbd_masked_sad64x16_ssse3, &aom_highbd_masked_sad64x16_c), }; -INSTANTIATE_TEST_CASE_P(SSSE3, HighbdMaskedSADTest, - ::testing::ValuesIn(hbd_msad_test)); +INSTANTIATE_TEST_SUITE_P(SSSE3, HighbdMaskedSADTest, + ::testing::ValuesIn(hbd_msad_test)); +#endif // CONFIG_AV1_HIGHBITDEPTH #endif // HAVE_SSSE3 #if HAVE_AVX2 @@ -295,9 +446,10 @@ const MaskedSADParam msad_avx2_test[] = { make_tuple(&aom_masked_sad64x16_avx2, &aom_masked_sad64x16_ssse3) }; -INSTANTIATE_TEST_CASE_P(AVX2, MaskedSADTest, - ::testing::ValuesIn(msad_avx2_test)); +INSTANTIATE_TEST_SUITE_P(AVX2, MaskedSADTest, + ::testing::ValuesIn(msad_avx2_test)); +#if CONFIG_AV1_HIGHBITDEPTH const HighbdMaskedSADParam hbd_msad_avx2_test[] = { make_tuple(&aom_highbd_masked_sad4x4_avx2, &aom_highbd_masked_sad4x4_ssse3), make_tuple(&aom_highbd_masked_sad4x8_avx2, &aom_highbd_masked_sad4x8_ssse3), @@ -335,8 +487,9 @@ const HighbdMaskedSADParam hbd_msad_avx2_test[] = { &aom_highbd_masked_sad64x16_ssse3) }; -INSTANTIATE_TEST_CASE_P(AVX2, HighbdMaskedSADTest, - ::testing::ValuesIn(hbd_msad_avx2_test)); +INSTANTIATE_TEST_SUITE_P(AVX2, HighbdMaskedSADTest, + ::testing::ValuesIn(hbd_msad_avx2_test)); +#endif // CONFIG_AV1_HIGHBITDEPTH #endif // HAVE_AVX2 } // namespace diff --git a/media/libaom/src/test/masked_variance_test.cc b/media/libaom/src/test/masked_variance_test.cc index 275b9feb6..bf814cea2 100644 --- a/media/libaom/src/test/masked_variance_test.cc +++ b/media/libaom/src/test/masked_variance_test.cc @@ -12,6 +12,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/acm_random.h" @@ -37,7 +38,7 @@ typedef unsigned int (*MaskedSubPixelVarianceFunc)( const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse); -typedef ::testing::tuple<MaskedSubPixelVarianceFunc, MaskedSubPixelVarianceFunc> +typedef std::tuple<MaskedSubPixelVarianceFunc, MaskedSubPixelVarianceFunc> MaskedSubPixelVarianceParam; class MaskedSubPixelVarianceTest @@ -170,8 +171,9 @@ TEST_P(MaskedSubPixelVarianceTest, ExtremeValues) { << " y_offset = " << first_failure_y; } -typedef ::testing::tuple<MaskedSubPixelVarianceFunc, MaskedSubPixelVarianceFunc, - aom_bit_depth_t> +#if CONFIG_AV1_HIGHBITDEPTH +typedef std::tuple<MaskedSubPixelVarianceFunc, MaskedSubPixelVarianceFunc, + aom_bit_depth_t> HighbdMaskedSubPixelVarianceParam; class HighbdMaskedSubPixelVarianceTest @@ -311,8 +313,9 @@ TEST_P(HighbdMaskedSubPixelVarianceTest, ExtremeValues) { << " x_offset = " << first_failure_x << " y_offset = " << first_failure_y; } +#endif // CONFIG_AV1_HIGHBITDEPTH -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSSE3 @@ -348,12 +351,26 @@ const MaskedSubPixelVarianceParam sub_pel_var_test[] = { make_tuple(&aom_masked_sub_pixel_variance4x8_ssse3, &aom_masked_sub_pixel_variance4x8_c), make_tuple(&aom_masked_sub_pixel_variance4x4_ssse3, - &aom_masked_sub_pixel_variance4x4_c) + &aom_masked_sub_pixel_variance4x4_c), + + make_tuple(&aom_masked_sub_pixel_variance64x16_ssse3, + &aom_masked_sub_pixel_variance64x16_c), + make_tuple(&aom_masked_sub_pixel_variance16x64_ssse3, + &aom_masked_sub_pixel_variance16x64_c), + make_tuple(&aom_masked_sub_pixel_variance32x8_ssse3, + &aom_masked_sub_pixel_variance32x8_c), + make_tuple(&aom_masked_sub_pixel_variance8x32_ssse3, + &aom_masked_sub_pixel_variance8x32_c), + make_tuple(&aom_masked_sub_pixel_variance16x4_ssse3, + &aom_masked_sub_pixel_variance16x4_c), + make_tuple(&aom_masked_sub_pixel_variance4x16_ssse3, + &aom_masked_sub_pixel_variance4x16_c), }; -INSTANTIATE_TEST_CASE_P(SSSE3_C_COMPARE, MaskedSubPixelVarianceTest, - ::testing::ValuesIn(sub_pel_var_test)); +INSTANTIATE_TEST_SUITE_P(SSSE3_C_COMPARE, MaskedSubPixelVarianceTest, + ::testing::ValuesIn(sub_pel_var_test)); +#if CONFIG_AV1_HIGHBITDEPTH const HighbdMaskedSubPixelVarianceParam hbd_sub_pel_var_test[] = { make_tuple(&aom_highbd_8_masked_sub_pixel_variance128x128_ssse3, &aom_highbd_8_masked_sub_pixel_variance128x128_c, AOM_BITS_8), @@ -450,10 +467,48 @@ const HighbdMaskedSubPixelVarianceParam hbd_sub_pel_var_test[] = { make_tuple(&aom_highbd_12_masked_sub_pixel_variance4x8_ssse3, &aom_highbd_12_masked_sub_pixel_variance4x8_c, AOM_BITS_12), make_tuple(&aom_highbd_12_masked_sub_pixel_variance4x4_ssse3, - &aom_highbd_12_masked_sub_pixel_variance4x4_c, AOM_BITS_12) + &aom_highbd_12_masked_sub_pixel_variance4x4_c, AOM_BITS_12), + + make_tuple(&aom_highbd_8_masked_sub_pixel_variance64x16_ssse3, + &aom_highbd_8_masked_sub_pixel_variance64x16_c, AOM_BITS_8), + make_tuple(&aom_highbd_8_masked_sub_pixel_variance16x64_ssse3, + &aom_highbd_8_masked_sub_pixel_variance16x64_c, AOM_BITS_8), + make_tuple(&aom_highbd_8_masked_sub_pixel_variance32x8_ssse3, + &aom_highbd_8_masked_sub_pixel_variance32x8_c, AOM_BITS_8), + make_tuple(&aom_highbd_8_masked_sub_pixel_variance8x32_ssse3, + &aom_highbd_8_masked_sub_pixel_variance8x32_c, AOM_BITS_8), + make_tuple(&aom_highbd_8_masked_sub_pixel_variance16x4_ssse3, + &aom_highbd_8_masked_sub_pixel_variance16x4_c, AOM_BITS_8), + make_tuple(&aom_highbd_8_masked_sub_pixel_variance4x16_ssse3, + &aom_highbd_8_masked_sub_pixel_variance4x16_c, AOM_BITS_8), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance64x16_ssse3, + &aom_highbd_10_masked_sub_pixel_variance64x16_c, AOM_BITS_10), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance16x64_ssse3, + &aom_highbd_10_masked_sub_pixel_variance16x64_c, AOM_BITS_10), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance32x8_ssse3, + &aom_highbd_10_masked_sub_pixel_variance32x8_c, AOM_BITS_10), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance8x32_ssse3, + &aom_highbd_10_masked_sub_pixel_variance8x32_c, AOM_BITS_10), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance16x4_ssse3, + &aom_highbd_10_masked_sub_pixel_variance16x4_c, AOM_BITS_10), + make_tuple(&aom_highbd_10_masked_sub_pixel_variance4x16_ssse3, + &aom_highbd_10_masked_sub_pixel_variance4x16_c, AOM_BITS_10), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance64x16_ssse3, + &aom_highbd_12_masked_sub_pixel_variance64x16_c, AOM_BITS_12), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance16x64_ssse3, + &aom_highbd_12_masked_sub_pixel_variance16x64_c, AOM_BITS_12), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance32x8_ssse3, + &aom_highbd_12_masked_sub_pixel_variance32x8_c, AOM_BITS_12), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance8x32_ssse3, + &aom_highbd_12_masked_sub_pixel_variance8x32_c, AOM_BITS_12), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance16x4_ssse3, + &aom_highbd_12_masked_sub_pixel_variance16x4_c, AOM_BITS_12), + make_tuple(&aom_highbd_12_masked_sub_pixel_variance4x16_ssse3, + &aom_highbd_12_masked_sub_pixel_variance4x16_c, AOM_BITS_12), }; -INSTANTIATE_TEST_CASE_P(SSSE3_C_COMPARE, HighbdMaskedSubPixelVarianceTest, - ::testing::ValuesIn(hbd_sub_pel_var_test)); +INSTANTIATE_TEST_SUITE_P(SSSE3_C_COMPARE, HighbdMaskedSubPixelVarianceTest, + ::testing::ValuesIn(hbd_sub_pel_var_test)); +#endif // CONFIG_AV1_HIGHBITDEPTH #endif // HAVE_SSSE3 } // namespace diff --git a/media/libaom/src/test/metadata_test.cc b/media/libaom/src/test/metadata_test.cc new file mode 100644 index 000000000..79e08a7a5 --- /dev/null +++ b/media/libaom/src/test/metadata_test.cc @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "aom/aom_codec.h" +#include "aom/aom_image.h" +#include "aom/internal/aom_image_internal.h" +#include "aom_scale/yv12config.h" +#include "av1/encoder/bitstream.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" +#include "test/video_source.h" + +namespace { +const size_t kMetadataPayloadSizeT35 = 24; +// 0xB5 stands for the itut t35 metadata country code for the Unites States +const uint8_t kMetadataPayloadT35[kMetadataPayloadSizeT35] = { + 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 +}; + +const size_t kMetadataPayloadSizeCll = 4; +const uint8_t kMetadataPayloadCll[kMetadataPayloadSizeCll] = { 0xB5, 0x01, 0x02, + 0x03 }; + +#if CONFIG_AV1_ENCODER + +const size_t kMetadataObuSizeT35 = 28; +const uint8_t kMetadataObuT35[kMetadataObuSizeT35] = { + 0x2A, 0x1A, 0x02, 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x80 +}; +const size_t kMetadataObuSizeMdcv = 28; +const uint8_t kMetadataObuMdcv[kMetadataObuSizeMdcv] = { + 0x2A, 0x1A, 0x02, 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x80 +}; +const size_t kMetadataObuSizeCll = 8; +const uint8_t kMetadataObuCll[kMetadataObuSizeCll] = { 0x2A, 0x06, 0x01, 0xB5, + 0x01, 0x02, 0x03, 0x80 }; + +class MetadataEncodeTest + : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>, + public ::libaom_test::EncoderTest { + protected: + MetadataEncodeTest() : EncoderTest(GET_PARAM(0)) {} + + virtual ~MetadataEncodeTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video) { + aom_image_t *current_frame = video->img(); + if (current_frame) { + if (current_frame->metadata) aom_img_remove_metadata(current_frame); + ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, 0, AOM_MIF_ANY_FRAME), + -1); + ASSERT_EQ( + aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35, NULL, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME), + -1); + ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35, + NULL, 0, AOM_MIF_ANY_FRAME), + -1); + ASSERT_EQ( + aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_ANY_FRAME), + 0); + + ASSERT_EQ( + aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_MDCV, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_KEY_FRAME), + 0); + + ASSERT_EQ( + aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_CLL, + kMetadataPayloadCll, kMetadataPayloadSizeCll, + AOM_MIF_KEY_FRAME), + 0); + } + } + + virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { + if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) { + const size_t bitstream_size = pkt->data.frame.sz; + const uint8_t *bitstream = + static_cast<const uint8_t *>(pkt->data.frame.buf); + // look for valid metadatas in bitstream + bool itut_t35_metadata_found = false; + if (bitstream_size >= kMetadataObuSizeT35) { + for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeT35; ++i) { + if (memcmp(bitstream + i, kMetadataObuT35, kMetadataObuSizeT35) == + 0) { + itut_t35_metadata_found = true; + } + } + } + ASSERT_EQ(itut_t35_metadata_found, 1u); + + // Testing for HDR MDCV metadata + bool hdr_mdcv_metadata_found = false; + if (bitstream_size >= kMetadataObuSizeMdcv) { + for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeMdcv; ++i) { + if (memcmp(bitstream + i, kMetadataObuMdcv, kMetadataObuSizeMdcv) == + 0) { + hdr_mdcv_metadata_found = true; + } + } + } + ASSERT_TRUE(hdr_mdcv_metadata_found); + + // Testing for HDR CLL metadata + bool hdr_cll_metadata_found = false; + if (bitstream_size >= kMetadataObuSizeCll) { + for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeCll; ++i) { + if (memcmp(bitstream + i, kMetadataObuCll, kMetadataObuSizeCll) == + 0) { + hdr_cll_metadata_found = true; + } + } + } + ASSERT_TRUE(hdr_cll_metadata_found); + } + } + + virtual void DecompressedFrameHook(const aom_image_t &img, + aom_codec_pts_t /*pts*/) { + ASSERT_TRUE(img.metadata != nullptr); + + ASSERT_EQ(img.metadata->sz, 3u); + + for (size_t i = 0; i < img.metadata->sz - 1; ++i) { + ASSERT_EQ(kMetadataPayloadSizeT35, img.metadata->metadata_array[i]->sz); + EXPECT_EQ( + memcmp(kMetadataPayloadT35, img.metadata->metadata_array[i]->payload, + kMetadataPayloadSizeT35), + 0); + } + + ASSERT_EQ(kMetadataPayloadSizeCll, img.metadata->metadata_array[2]->sz); + EXPECT_EQ( + memcmp(kMetadataPayloadCll, img.metadata->metadata_array[2]->payload, + kMetadataPayloadSizeCll), + 0); + } +}; + +TEST_P(MetadataEncodeTest, TestMetadataEncoding) { + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 5); + init_flags_ = AOM_CODEC_USE_PSNR; + + cfg_.g_w = 352; + cfg_.g_h = 288; + + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 600; + cfg_.rc_buf_sz = 1000; + cfg_.rc_min_quantizer = 2; + cfg_.rc_max_quantizer = 56; + cfg_.rc_undershoot_pct = 50; + cfg_.rc_overshoot_pct = 50; + cfg_.rc_end_usage = AOM_CBR; + cfg_.kf_mode = AOM_KF_AUTO; + cfg_.g_lag_in_frames = 1; + cfg_.kf_min_dist = cfg_.kf_max_dist = 3000; + // Enable dropped frames. + cfg_.rc_dropframe_thresh = 1; + // Disable error_resilience mode. + cfg_.g_error_resilient = 0; + // Run at low bitrate. + cfg_.rc_target_bitrate = 40; + + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); +} + +AV1_INSTANTIATE_TEST_CASE(MetadataEncodeTest, + ::testing::Values(::libaom_test::kOnePassGood)); + +#endif // CONFIG_AV1_ENCODER +} // namespace + +TEST(MetadataTest, MetadataAllocation) { + aom_metadata_t *metadata = + aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME); + ASSERT_NE(metadata, nullptr); + aom_img_metadata_free(metadata); +} + +TEST(MetadataTest, MetadataArrayAllocation) { + aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(2); + ASSERT_NE(metadata_array, nullptr); + + metadata_array->metadata_array[0] = + aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME); + metadata_array->metadata_array[1] = + aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME); + + aom_img_metadata_array_free(metadata_array); +} + +TEST(MetadataTest, AddMetadataToImage) { + aom_image_t image; + image.metadata = NULL; + + ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_ANY_FRAME), + 0); + aom_img_metadata_array_free(image.metadata); + EXPECT_EQ(aom_img_add_metadata(NULL, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_ANY_FRAME), + -1); +} + +TEST(MetadataTest, RemoveMetadataFromImage) { + aom_image_t image; + image.metadata = NULL; + + ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_ANY_FRAME), + 0); + aom_img_remove_metadata(&image); + aom_img_remove_metadata(NULL); +} + +TEST(MetadataTest, CopyMetadataToFrameBuffer) { + YV12_BUFFER_CONFIG yvBuf; + yvBuf.metadata = NULL; + + aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(1); + ASSERT_NE(metadata_array, nullptr); + + metadata_array->metadata_array[0] = + aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME); + + // Metadata_array + int status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array); + EXPECT_EQ(status, 0); + status = aom_copy_metadata_to_frame_buffer(NULL, metadata_array); + EXPECT_EQ(status, -1); + aom_img_metadata_array_free(metadata_array); + + // Metadata_array_2 + aom_metadata_array_t *metadata_array_2 = aom_img_metadata_array_alloc(0); + ASSERT_NE(metadata_array_2, nullptr); + status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array_2); + EXPECT_EQ(status, -1); + aom_img_metadata_array_free(metadata_array_2); + + // YV12_BUFFER_CONFIG + status = aom_copy_metadata_to_frame_buffer(&yvBuf, NULL); + EXPECT_EQ(status, -1); + aom_remove_metadata_from_frame_buffer(&yvBuf); + aom_remove_metadata_from_frame_buffer(NULL); +} + +TEST(MetadataTest, GetMetadataFromImage) { + aom_image_t image; + image.metadata = NULL; + + ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35, + kMetadataPayloadT35, kMetadataPayloadSizeT35, + AOM_MIF_ANY_FRAME), + 0); + + EXPECT_TRUE(aom_img_get_metadata(NULL, 0) == NULL); + EXPECT_TRUE(aom_img_get_metadata(&image, 1u) == NULL); + EXPECT_TRUE(aom_img_get_metadata(&image, 10u) == NULL); + + const aom_metadata_t *metadata = aom_img_get_metadata(&image, 0); + ASSERT_TRUE(metadata != NULL); + ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35); + EXPECT_EQ( + memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35), + 0); + + aom_img_metadata_array_free(image.metadata); +} + +TEST(MetadataTest, ReadMetadatasFromImage) { + aom_image_t image; + image.metadata = NULL; + + uint32_t types[3]; + types[0] = OBU_METADATA_TYPE_ITUT_T35; + types[1] = OBU_METADATA_TYPE_HDR_CLL; + types[2] = OBU_METADATA_TYPE_HDR_MDCV; + + ASSERT_EQ(aom_img_add_metadata(&image, types[0], kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME), + 0); + ASSERT_EQ(aom_img_add_metadata(&image, types[1], kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME), + 0); + ASSERT_EQ(aom_img_add_metadata(&image, types[2], kMetadataPayloadT35, + kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME), + 0); + + size_t number_metadata = aom_img_num_metadata(&image); + ASSERT_EQ(number_metadata, 3u); + for (size_t i = 0; i < number_metadata; ++i) { + const aom_metadata_t *metadata = aom_img_get_metadata(&image, i); + ASSERT_TRUE(metadata != NULL); + ASSERT_EQ(metadata->type, types[i]); + ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35); + EXPECT_EQ( + memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35), + 0); + } + aom_img_metadata_array_free(image.metadata); +} diff --git a/media/libaom/src/test/motion_vector_test.cc b/media/libaom/src/test/motion_vector_test.cc index 27eb93893..2636c39aa 100644 --- a/media/libaom/src/test/motion_vector_test.cc +++ b/media/libaom/src/test/motion_vector_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <memory> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -60,7 +62,7 @@ class MotionVectorTestLarge virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, cpu_used_); encoder->Control(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, mv_test_mode_); if (encoding_mode_ != ::libaom_test::kRealTime) { @@ -90,7 +92,7 @@ TEST_P(MotionVectorTestLarge, OverallTest) { cfg_.g_profile = 0; init_flags_ = AOM_CODEC_USE_PSNR; - testing::internal::scoped_ptr<libaom_test::VideoSource> video; + std::unique_ptr<libaom_test::VideoSource> video; video.reset(new libaom_test::YUVVideoSource( "niklas_640_480_30.yuv", AOM_IMG_FMT_I420, width, height, 30, 1, 0, 3)); diff --git a/media/libaom/src/test/noise_model_test.cc b/media/libaom/src/test/noise_model_test.cc index b5b387e31..5b61236f0 100644 --- a/media/libaom/src/test/noise_model_test.cc +++ b/media/libaom/src/test/noise_model_test.cc @@ -343,7 +343,7 @@ class FlatBlockEstimatorTest : public ::testing::Test, public T { libaom_test::ACMRandom random_; }; -TYPED_TEST_CASE_P(FlatBlockEstimatorTest); +TYPED_TEST_SUITE_P(FlatBlockEstimatorTest); TYPED_TEST_P(FlatBlockEstimatorTest, ExtractBlock) { const int kBlockSize = 16; @@ -494,16 +494,16 @@ TYPED_TEST_P(FlatBlockEstimatorTest, FindFlatBlocks) { aom_flat_block_finder_free(&flat_block_finder); } -REGISTER_TYPED_TEST_CASE_P(FlatBlockEstimatorTest, ExtractBlock, - FindFlatBlocks); +REGISTER_TYPED_TEST_SUITE_P(FlatBlockEstimatorTest, ExtractBlock, + FindFlatBlocks); typedef ::testing::Types<BitDepthParams<uint8_t, 8, false>, // lowbd BitDepthParams<uint16_t, 8, true>, // lowbd in 16-bit BitDepthParams<uint16_t, 10, true>, // highbd data BitDepthParams<uint16_t, 12, true> > AllBitDepthParams; -INSTANTIATE_TYPED_TEST_CASE_P(FlatBlockInstatiation, FlatBlockEstimatorTest, - AllBitDepthParams); +INSTANTIATE_TYPED_TEST_SUITE_P(FlatBlockInstatiation, FlatBlockEstimatorTest, + AllBitDepthParams); template <typename T> class NoiseModelUpdateTest : public ::testing::Test, public T { @@ -570,7 +570,7 @@ class NoiseModelUpdateTest : public ::testing::Test, public T { uint8_t *denoised_ptr_raw_[3]; }; -TYPED_TEST_CASE_P(NoiseModelUpdateTest); +TYPED_TEST_SUITE_P(NoiseModelUpdateTest); TYPED_TEST_P(NoiseModelUpdateTest, UpdateFailsNoFlatBlocks) { EXPECT_EQ(AOM_NOISE_STATUS_INSUFFICIENT_FLAT_BLOCKS, @@ -929,17 +929,17 @@ TYPED_TEST_P(NoiseModelUpdateTest, NoiseCoeffsSignalsDifferentNoiseType) { } EXPECT_EQ(AOM_NOISE_STATUS_DIFFERENT_NOISE_TYPE, this->NoiseModelUpdate()); } -REGISTER_TYPED_TEST_CASE_P(NoiseModelUpdateTest, UpdateFailsNoFlatBlocks, - UpdateSuccessForZeroNoiseAllFlat, - UpdateFailsBlockSizeTooSmall, - UpdateSuccessForWhiteRandomNoise, - UpdateSuccessForScaledWhiteNoise, - UpdateSuccessForCorrelatedNoise, - NoiseStrengthChangeSignalsDifferentNoiseType, - NoiseCoeffsSignalsDifferentNoiseType); - -INSTANTIATE_TYPED_TEST_CASE_P(NoiseModelUpdateTestInstatiation, - NoiseModelUpdateTest, AllBitDepthParams); +REGISTER_TYPED_TEST_SUITE_P(NoiseModelUpdateTest, UpdateFailsNoFlatBlocks, + UpdateSuccessForZeroNoiseAllFlat, + UpdateFailsBlockSizeTooSmall, + UpdateSuccessForWhiteRandomNoise, + UpdateSuccessForScaledWhiteNoise, + UpdateSuccessForCorrelatedNoise, + NoiseStrengthChangeSignalsDifferentNoiseType, + NoiseCoeffsSignalsDifferentNoiseType); + +INSTANTIATE_TYPED_TEST_SUITE_P(NoiseModelUpdateTestInstatiation, + NoiseModelUpdateTest, AllBitDepthParams); TEST(NoiseModelGetGrainParameters, TestLagSize) { aom_film_grain_t film_grain; @@ -1229,7 +1229,7 @@ class WienerDenoiseTest : public ::testing::Test, public T { int stride_[3]; }; -TYPED_TEST_CASE_P(WienerDenoiseTest); +TYPED_TEST_SUITE_P(WienerDenoiseTest); TYPED_TEST_P(WienerDenoiseTest, InvalidBlockSize) { const uint8_t *const data_ptrs[3] = { @@ -1336,8 +1336,8 @@ TYPED_TEST_P(WienerDenoiseTest, GradientTest) { } } -REGISTER_TYPED_TEST_CASE_P(WienerDenoiseTest, InvalidBlockSize, - InvalidChromaSubsampling, GradientTest); +REGISTER_TYPED_TEST_SUITE_P(WienerDenoiseTest, InvalidBlockSize, + InvalidChromaSubsampling, GradientTest); -INSTANTIATE_TYPED_TEST_CASE_P(WienerDenoiseTestInstatiation, WienerDenoiseTest, - AllBitDepthParams); +INSTANTIATE_TYPED_TEST_SUITE_P(WienerDenoiseTestInstatiation, WienerDenoiseTest, + AllBitDepthParams); diff --git a/media/libaom/src/test/obmc_sad_test.cc b/media/libaom/src/test/obmc_sad_test.cc index 6cef86961..6b4382cd7 100644 --- a/media/libaom/src/test/obmc_sad_test.cc +++ b/media/libaom/src/test/obmc_sad_test.cc @@ -101,11 +101,18 @@ const ObmcSadTest::ParamType sse4_functions[] = { TestFuncs(aom_obmc_sad8x8_c, aom_obmc_sad8x8_sse4_1), TestFuncs(aom_obmc_sad8x4_c, aom_obmc_sad8x4_sse4_1), TestFuncs(aom_obmc_sad4x8_c, aom_obmc_sad4x8_sse4_1), - TestFuncs(aom_obmc_sad4x4_c, aom_obmc_sad4x4_sse4_1) + TestFuncs(aom_obmc_sad4x4_c, aom_obmc_sad4x4_sse4_1), + + TestFuncs(aom_obmc_sad64x16_c, aom_obmc_sad64x16_sse4_1), + TestFuncs(aom_obmc_sad16x64_c, aom_obmc_sad16x64_sse4_1), + TestFuncs(aom_obmc_sad32x8_c, aom_obmc_sad32x8_sse4_1), + TestFuncs(aom_obmc_sad8x32_c, aom_obmc_sad8x32_sse4_1), + TestFuncs(aom_obmc_sad16x4_c, aom_obmc_sad16x4_sse4_1), + TestFuncs(aom_obmc_sad4x16_c, aom_obmc_sad4x16_sse4_1), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, ObmcSadTest, - ::testing::ValuesIn(sse4_functions)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, ObmcSadTest, + ::testing::ValuesIn(sse4_functions)); #endif // HAVE_SSE4_1 #if HAVE_AVX2 @@ -125,12 +132,21 @@ const ObmcSadTest::ParamType avx2_functions[] = { TestFuncs(aom_obmc_sad8x8_c, aom_obmc_sad8x8_avx2), TestFuncs(aom_obmc_sad8x4_c, aom_obmc_sad8x4_avx2), TestFuncs(aom_obmc_sad4x8_c, aom_obmc_sad4x8_avx2), - TestFuncs(aom_obmc_sad4x4_c, aom_obmc_sad4x4_avx2) + TestFuncs(aom_obmc_sad4x4_c, aom_obmc_sad4x4_avx2), + + TestFuncs(aom_obmc_sad64x16_c, aom_obmc_sad64x16_avx2), + TestFuncs(aom_obmc_sad16x64_c, aom_obmc_sad16x64_avx2), + TestFuncs(aom_obmc_sad32x8_c, aom_obmc_sad32x8_avx2), + TestFuncs(aom_obmc_sad8x32_c, aom_obmc_sad8x32_avx2), + TestFuncs(aom_obmc_sad16x4_c, aom_obmc_sad16x4_avx2), + TestFuncs(aom_obmc_sad4x16_c, aom_obmc_sad4x16_avx2), }; -INSTANTIATE_TEST_CASE_P(AVX2, ObmcSadTest, ::testing::ValuesIn(avx2_functions)); +INSTANTIATE_TEST_SUITE_P(AVX2, ObmcSadTest, + ::testing::ValuesIn(avx2_functions)); #endif // HAVE_AVX2 +#if CONFIG_AV1_HIGHBITDEPTH //////////////////////////////////////////////////////////////////////////////// // High bit-depth //////////////////////////////////////////////////////////////////////////////// @@ -204,11 +220,18 @@ ObmcSadHBDTest::ParamType sse4_functions_hbd[] = { TestFuncs(aom_highbd_obmc_sad8x8_c, aom_highbd_obmc_sad8x8_sse4_1), TestFuncs(aom_highbd_obmc_sad8x4_c, aom_highbd_obmc_sad8x4_sse4_1), TestFuncs(aom_highbd_obmc_sad4x8_c, aom_highbd_obmc_sad4x8_sse4_1), - TestFuncs(aom_highbd_obmc_sad4x4_c, aom_highbd_obmc_sad4x4_sse4_1) + TestFuncs(aom_highbd_obmc_sad4x4_c, aom_highbd_obmc_sad4x4_sse4_1), + + TestFuncs(aom_highbd_obmc_sad64x16_c, aom_highbd_obmc_sad64x16_sse4_1), + TestFuncs(aom_highbd_obmc_sad16x64_c, aom_highbd_obmc_sad16x64_sse4_1), + TestFuncs(aom_highbd_obmc_sad32x8_c, aom_highbd_obmc_sad32x8_sse4_1), + TestFuncs(aom_highbd_obmc_sad8x32_c, aom_highbd_obmc_sad8x32_sse4_1), + TestFuncs(aom_highbd_obmc_sad16x4_c, aom_highbd_obmc_sad16x4_sse4_1), + TestFuncs(aom_highbd_obmc_sad4x16_c, aom_highbd_obmc_sad4x16_sse4_1), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, ObmcSadHBDTest, - ::testing::ValuesIn(sse4_functions_hbd)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, ObmcSadHBDTest, + ::testing::ValuesIn(sse4_functions_hbd)); #endif // HAVE_SSE4_1 #if HAVE_AVX2 @@ -228,10 +251,18 @@ ObmcSadHBDTest::ParamType avx2_functions_hbd[] = { TestFuncs(aom_highbd_obmc_sad8x8_c, aom_highbd_obmc_sad8x8_avx2), TestFuncs(aom_highbd_obmc_sad8x4_c, aom_highbd_obmc_sad8x4_avx2), TestFuncs(aom_highbd_obmc_sad4x8_c, aom_highbd_obmc_sad4x8_avx2), - TestFuncs(aom_highbd_obmc_sad4x4_c, aom_highbd_obmc_sad4x4_avx2) + TestFuncs(aom_highbd_obmc_sad4x4_c, aom_highbd_obmc_sad4x4_avx2), + + TestFuncs(aom_highbd_obmc_sad64x16_c, aom_highbd_obmc_sad64x16_avx2), + TestFuncs(aom_highbd_obmc_sad16x64_c, aom_highbd_obmc_sad16x64_avx2), + TestFuncs(aom_highbd_obmc_sad32x8_c, aom_highbd_obmc_sad32x8_avx2), + TestFuncs(aom_highbd_obmc_sad8x32_c, aom_highbd_obmc_sad8x32_avx2), + TestFuncs(aom_highbd_obmc_sad16x4_c, aom_highbd_obmc_sad16x4_avx2), + TestFuncs(aom_highbd_obmc_sad4x16_c, aom_highbd_obmc_sad4x16_avx2), }; -INSTANTIATE_TEST_CASE_P(AVX2, ObmcSadHBDTest, - ::testing::ValuesIn(avx2_functions_hbd)); +INSTANTIATE_TEST_SUITE_P(AVX2, ObmcSadHBDTest, + ::testing::ValuesIn(avx2_functions_hbd)); #endif // HAVE_AVX2 +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/obmc_variance_test.cc b/media/libaom/src/test/obmc_variance_test.cc index 4563b964a..fc281d70b 100644 --- a/media/libaom/src/test/obmc_variance_test.cc +++ b/media/libaom/src/test/obmc_variance_test.cc @@ -147,11 +147,18 @@ const ObmcVarianceTest::ParamType sse4_functions[] = { TestFuncs(aom_obmc_variance8x8_c, aom_obmc_variance8x8_sse4_1), TestFuncs(aom_obmc_variance8x4_c, aom_obmc_variance8x4_sse4_1), TestFuncs(aom_obmc_variance4x8_c, aom_obmc_variance4x8_sse4_1), - TestFuncs(aom_obmc_variance4x4_c, aom_obmc_variance4x4_sse4_1) + TestFuncs(aom_obmc_variance4x4_c, aom_obmc_variance4x4_sse4_1), + + TestFuncs(aom_obmc_variance64x16_c, aom_obmc_variance64x16_sse4_1), + TestFuncs(aom_obmc_variance16x64_c, aom_obmc_variance16x64_sse4_1), + TestFuncs(aom_obmc_variance32x8_c, aom_obmc_variance32x8_sse4_1), + TestFuncs(aom_obmc_variance8x32_c, aom_obmc_variance8x32_sse4_1), + TestFuncs(aom_obmc_variance16x4_c, aom_obmc_variance16x4_sse4_1), + TestFuncs(aom_obmc_variance4x16_c, aom_obmc_variance4x16_sse4_1), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, ObmcVarianceTest, - ::testing::ValuesIn(sse4_functions)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, ObmcVarianceTest, + ::testing::ValuesIn(sse4_functions)); #endif // HAVE_SSE4_1 #if HAVE_AVX2 @@ -170,18 +177,25 @@ const ObmcVarianceTest::ParamType avx2_functions[] = { 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) + TestFuncs(aom_obmc_variance4x8_c, aom_obmc_variance4x8_avx2), + TestFuncs(aom_obmc_variance4x4_c, aom_obmc_variance4x4_avx2), + + TestFuncs(aom_obmc_variance64x16_c, aom_obmc_variance64x16_avx2), + TestFuncs(aom_obmc_variance16x64_c, aom_obmc_variance16x64_avx2), + TestFuncs(aom_obmc_variance32x8_c, aom_obmc_variance32x8_avx2), + TestFuncs(aom_obmc_variance8x32_c, aom_obmc_variance8x32_avx2), + TestFuncs(aom_obmc_variance16x4_c, aom_obmc_variance16x4_avx2), + TestFuncs(aom_obmc_variance4x16_c, aom_obmc_variance4x16_avx2), }; -INSTANTIATE_TEST_CASE_P(AVX2, ObmcVarianceTest, - ::testing::ValuesIn(avx2_functions)); +INSTANTIATE_TEST_SUITE_P(AVX2, ObmcVarianceTest, + ::testing::ValuesIn(avx2_functions)); #endif // HAVE_AVX2 //////////////////////////////////////////////////////////////////////////////// // High bit-depth //////////////////////////////////////////////////////////////////////////////// - +#if CONFIG_AV1_HIGHBITDEPTH class ObmcVarianceHBDTest : public FunctionEquivalenceTest<ObmcVarF> {}; TEST_P(ObmcVarianceHBDTest, RandomValues) { @@ -336,10 +350,48 @@ ObmcVarianceHBDTest::ParamType sse4_functions_hbd[] = { TestFuncs(aom_highbd_12_obmc_variance4x8_c, aom_highbd_12_obmc_variance4x8_sse4_1, 12), TestFuncs(aom_highbd_12_obmc_variance4x4_c, - aom_highbd_12_obmc_variance4x4_sse4_1, 12) + aom_highbd_12_obmc_variance4x4_sse4_1, 12), + + TestFuncs(aom_highbd_obmc_variance64x16_c, + aom_highbd_obmc_variance64x16_sse4_1, 8), + TestFuncs(aom_highbd_obmc_variance16x64_c, + aom_highbd_obmc_variance16x64_sse4_1, 8), + TestFuncs(aom_highbd_obmc_variance32x8_c, aom_highbd_obmc_variance32x8_sse4_1, + 8), + TestFuncs(aom_highbd_obmc_variance8x32_c, aom_highbd_obmc_variance8x32_sse4_1, + 8), + TestFuncs(aom_highbd_obmc_variance16x4_c, aom_highbd_obmc_variance16x4_sse4_1, + 8), + TestFuncs(aom_highbd_obmc_variance4x16_c, aom_highbd_obmc_variance4x16_sse4_1, + 8), + TestFuncs(aom_highbd_10_obmc_variance64x16_c, + aom_highbd_10_obmc_variance64x16_sse4_1, 10), + TestFuncs(aom_highbd_10_obmc_variance16x64_c, + aom_highbd_10_obmc_variance16x64_sse4_1, 10), + TestFuncs(aom_highbd_10_obmc_variance32x8_c, + aom_highbd_10_obmc_variance32x8_sse4_1, 10), + TestFuncs(aom_highbd_10_obmc_variance8x32_c, + aom_highbd_10_obmc_variance8x32_sse4_1, 10), + TestFuncs(aom_highbd_10_obmc_variance16x4_c, + aom_highbd_10_obmc_variance16x4_sse4_1, 10), + TestFuncs(aom_highbd_10_obmc_variance4x16_c, + aom_highbd_10_obmc_variance4x16_sse4_1, 10), + TestFuncs(aom_highbd_12_obmc_variance64x16_c, + aom_highbd_12_obmc_variance64x16_sse4_1, 12), + TestFuncs(aom_highbd_12_obmc_variance16x64_c, + aom_highbd_12_obmc_variance16x64_sse4_1, 12), + TestFuncs(aom_highbd_12_obmc_variance32x8_c, + aom_highbd_12_obmc_variance32x8_sse4_1, 12), + TestFuncs(aom_highbd_12_obmc_variance8x32_c, + aom_highbd_12_obmc_variance8x32_sse4_1, 12), + TestFuncs(aom_highbd_12_obmc_variance16x4_c, + aom_highbd_12_obmc_variance16x4_sse4_1, 12), + TestFuncs(aom_highbd_12_obmc_variance4x16_c, + aom_highbd_12_obmc_variance4x16_sse4_1, 12), }; -INSTANTIATE_TEST_CASE_P(SSE4_1, ObmcVarianceHBDTest, - ::testing::ValuesIn(sse4_functions_hbd)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, ObmcVarianceHBDTest, + ::testing::ValuesIn(sse4_functions_hbd)); #endif // HAVE_SSE4_1 +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/pickrst_test.cc b/media/libaom/src/test/pickrst_test.cc index 040e8e8b7..9a2c5bcd4 100644 --- a/media/libaom/src/test/pickrst_test.cc +++ b/media/libaom/src/test/pickrst_test.cc @@ -9,21 +9,24 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" -#include "test/function_equivalence_test.h" #include "test/register_state_check.h" +#include "test/acm_random.h" +#include "test/util.h" #include "config/aom_config.h" #include "config/aom_dsp_rtcd.h" #include "aom/aom_integer.h" +#include "aom_ports/aom_timer.h" #include "av1/encoder/pickrst.h" -using libaom_test::FunctionEquivalenceTest; #define MAX_DATA_BLOCK 384 -namespace { +namespace pickrst_test_lowbd { static const int kIterations = 100; typedef int64_t (*lowbd_pixel_proj_error_func)( @@ -31,14 +34,11 @@ typedef int64_t (*lowbd_pixel_proj_error_func)( 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; +typedef std::tuple<const lowbd_pixel_proj_error_func> PixelProjErrorTestParam; class PixelProjErrorTest : public ::testing::TestWithParam<PixelProjErrorTestParam> { @@ -46,13 +46,17 @@ class PixelProjErrorTest virtual void SetUp() { target_func_ = GET_PARAM(0); src_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * - sizeof(uint8_t))); + sizeof(*src_))); + ASSERT_NE(src_, nullptr); dgd_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * - sizeof(uint8_t))); + sizeof(*dgd_))); + ASSERT_NE(dgd_, nullptr); flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * - sizeof(int32_t))); + sizeof(*flt0_))); + ASSERT_NE(flt0_, nullptr); flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * - sizeof(int32_t))); + sizeof(*flt1_))); + ASSERT_NE(flt1_, nullptr); } virtual void TearDown() { aom_free(src_); @@ -60,19 +64,19 @@ class PixelProjErrorTest aom_free(flt0_); aom_free(flt1_); } - void runPixelProjErrorTest(int32_t run_times); - void runPixelProjErrorTest_ExtremeValues(); + void RunPixelProjErrorTest(int32_t run_times); + void RunPixelProjErrorTest_ExtremeValues(); private: lowbd_pixel_proj_error_func target_func_; - ACMRandom rng_; + libaom_test::ACMRandom rng_; uint8_t *src_; uint8_t *dgd_; int32_t *flt0_; int32_t *flt1_; }; -void PixelProjErrorTest::runPixelProjErrorTest(int32_t run_times) { +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; @@ -124,7 +128,7 @@ void PixelProjErrorTest::runPixelProjErrorTest(int32_t run_times) { } } -void PixelProjErrorTest::runPixelProjErrorTest_ExtremeValues() { +void PixelProjErrorTest::RunPixelProjErrorTest_ExtremeValues() { const int h_start = 0; int h_end = 192; const int v_start = 0; @@ -165,23 +169,366 @@ void PixelProjErrorTest::runPixelProjErrorTest_ExtremeValues() { } } -TEST_P(PixelProjErrorTest, RandomValues) { runPixelProjErrorTest(1); } +TEST_P(PixelProjErrorTest, RandomValues) { RunPixelProjErrorTest(1); } TEST_P(PixelProjErrorTest, ExtremeValues) { - runPixelProjErrorTest_ExtremeValues(); + RunPixelProjErrorTest_ExtremeValues(); +} + +TEST_P(PixelProjErrorTest, DISABLED_Speed) { RunPixelProjErrorTest(200000); } + +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P(SSE4_1, PixelProjErrorTest, + ::testing::Values(av1_lowbd_pixel_proj_error_sse4_1)); +#endif // HAVE_SSE4_1 + +#if HAVE_AVX2 + +INSTANTIATE_TEST_SUITE_P(AVX2, PixelProjErrorTest, + ::testing::Values(av1_lowbd_pixel_proj_error_avx2)); +#endif // HAVE_AVX2 + +} // namespace pickrst_test_lowbd + +#if CONFIG_AV1_HIGHBITDEPTH +namespace pickrst_test_highbd { +static const int kIterations = 100; + +typedef int64_t (*highbd_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); + +//////////////////////////////////////////////////////////////////////////////// +// High bit-depth +//////////////////////////////////////////////////////////////////////////////// + +typedef std::tuple<const highbd_pixel_proj_error_func> PixelProjErrorTestParam; + +class PixelProjHighbdErrorTest + : public ::testing::TestWithParam<PixelProjErrorTestParam> { + public: + virtual void SetUp() { + target_func_ = GET_PARAM(0); + src_ = + (uint16_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_)); + ASSERT_NE(src_, nullptr); + dgd_ = + (uint16_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_)); + ASSERT_NE(dgd_, nullptr); + flt0_ = + (int32_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*flt0_)); + ASSERT_NE(flt0_, nullptr); + flt1_ = + (int32_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*flt1_)); + ASSERT_NE(flt1_, nullptr); + } + 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: + highbd_pixel_proj_error_func target_func_; + libaom_test::ACMRandom rng_; + uint16_t *src_; + uint16_t *dgd_; + int32_t *flt0_; + int32_t *flt1_; +}; + +void PixelProjHighbdErrorTest::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_.Rand16() % (1 << 12); + src_[i] = rng_.Rand16() % (1 << 12); + 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 *dgd8 = CONVERT_TO_BYTEPTR(dgd_); + uint8_t *src8 = CONVERT_TO_BYTEPTR(src_); + + aom_usec_timer timer; + aom_usec_timer_start(&timer); + for (int i = 0; i < run_times; ++i) { + err_ref = av1_highbd_pixel_proj_error_c( + src8, h_end, v_end, src_stride, dgd8, 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_(src8, h_end, v_end, src_stride, dgd8, 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 PixelProjHighbdErrorTest::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] = (1 << 12) - 1; + 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 *dgd8 = CONVERT_TO_BYTEPTR(dgd_); + uint8_t *src8 = CONVERT_TO_BYTEPTR(src_); + + err_ref = av1_highbd_pixel_proj_error_c( + src8, h_end - h_start, v_end - v_start, src_stride, dgd8, dgd_stride, + flt0_, flt0_stride, flt1_, flt1_stride, xq, ¶ms); + + err_test = target_func_(src8, h_end - h_start, v_end - v_start, src_stride, + dgd8, dgd_stride, flt0_, flt0_stride, flt1_, + flt1_stride, xq, ¶ms); + + ASSERT_EQ(err_ref, err_test); + } +} + +TEST_P(PixelProjHighbdErrorTest, RandomValues) { RunPixelProjErrorTest(1); } + +TEST_P(PixelProjHighbdErrorTest, ExtremeValues) { + RunPixelProjErrorTest_ExtremeValues(); } -TEST_P(PixelProjErrorTest, DISABLED_Speed) { runPixelProjErrorTest(200000); } +TEST_P(PixelProjHighbdErrorTest, DISABLED_Speed) { + RunPixelProjErrorTest(200000); +} #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1, PixelProjErrorTest, - ::testing::Values(av1_lowbd_pixel_proj_error_sse4_1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, PixelProjHighbdErrorTest, + ::testing::Values(av1_highbd_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)); +INSTANTIATE_TEST_SUITE_P(AVX2, PixelProjHighbdErrorTest, + ::testing::Values(av1_highbd_pixel_proj_error_avx2)); +#endif // HAVE_AVX2 + +} // namespace pickrst_test_highbd + +//////////////////////////////////////////////////////////////////////////////// +// Get_proj_subspace_Test +//////////////////////////////////////////////////////////////////////////////// + +namespace get_proj_subspace_test_lowbd { +static const int kIterations = 100; + +typedef void (*set_get_proj_subspace)(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, + int64_t H[2][2], int64_t C[2], + const sgr_params_type *params); + +typedef std::tuple<const set_get_proj_subspace> GetProjSubspaceTestParam; + +class GetProjSubspaceTest + : public ::testing::TestWithParam<GetProjSubspaceTestParam> { + public: + virtual void SetUp() { + target_func_ = GET_PARAM(0); + src_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * + sizeof(*src_))); + ASSERT_NE(src_, nullptr); + dgd_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * + sizeof(*dgd_))); + ASSERT_NE(dgd_, nullptr); + flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * + sizeof(*flt0_))); + ASSERT_NE(flt0_, nullptr); + flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * + sizeof(*flt1_))); + ASSERT_NE(flt1_, nullptr); + } + virtual void TearDown() { + aom_free(src_); + aom_free(dgd_); + aom_free(flt0_); + aom_free(flt1_); + } + void RunGetProjSubspaceTest(int32_t run_times); + void RunGetProjSubspaceTest_ExtremeValues(); + + private: + set_get_proj_subspace target_func_; + libaom_test::ACMRandom rng_; + uint8_t *src_; + uint8_t *dgd_; + int32_t *flt0_; + int32_t *flt1_; +}; + +void GetProjSubspaceTest::RunGetProjSubspaceTest(int32_t run_times) { + int h_end = run_times != 1 + ? 128 + : ((rng_.Rand16() % MAX_DATA_BLOCK) & + 2147483640); // We test for widths divisible by 8. + int v_end = + run_times != 1 ? 128 : ((rng_.Rand16() % MAX_DATA_BLOCK) & 2147483640); + 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; + const int iters = run_times == 1 ? kIterations : 4; + for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) { + int64_t C_ref[2] = { 0 }, C_test[2] = { 0 }; + int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } }; + int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } }; + 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(); + } + + params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : 1; + params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : 1; + 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) { + av1_calc_proj_params_c(src, v_end, h_end, src_stride, dgd, dgd_stride, + flt0_, flt0_stride, flt1_, flt1_stride, H_ref, + C_ref, ¶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) { + target_func_(src, v_end, h_end, src_stride, dgd, dgd_stride, flt0_, + flt0_stride, flt1_, flt1_stride, H_test, C_test, ¶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); + } else { + ASSERT_EQ(H_ref[0][0], H_test[0][0]); + ASSERT_EQ(H_ref[0][1], H_test[0][1]); + ASSERT_EQ(H_ref[1][0], H_test[1][0]); + ASSERT_EQ(H_ref[1][1], H_test[1][1]); + ASSERT_EQ(C_ref[0], C_test[0]); + ASSERT_EQ(C_ref[1], C_test[1]); + } + } +} + +void GetProjSubspaceTest::RunGetProjSubspaceTest_ExtremeValues() { + const int h_start = 0; + int h_end = MAX_DATA_BLOCK; + const int v_start = 0; + int v_end = MAX_DATA_BLOCK; + 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; + const int iters = kIterations; + for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) { + int64_t C_ref[2] = { 0 }, C_test[2] = { 0 }; + int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } }; + int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } }; + 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(); + } + params.r[0] = 1; + params.r[1] = 1; + params.s[0] = rng_.Rand8() % MAX_RADIUS; + params.s[1] = rng_.Rand8() % MAX_RADIUS; + uint8_t *dgd = dgd_; + uint8_t *src = src_; + + av1_calc_proj_params_c(src, h_end - h_start, v_end - v_start, src_stride, + dgd, dgd_stride, flt0_, flt0_stride, flt1_, + flt1_stride, H_ref, C_ref, ¶ms); + + target_func_(src, h_end - h_start, v_end - v_start, src_stride, dgd, + dgd_stride, flt0_, flt0_stride, flt1_, flt1_stride, H_test, + C_test, ¶ms); + + ASSERT_EQ(H_ref[0][0], H_test[0][0]); + ASSERT_EQ(H_ref[0][1], H_test[0][1]); + ASSERT_EQ(H_ref[1][0], H_test[1][0]); + ASSERT_EQ(H_ref[1][1], H_test[1][1]); + ASSERT_EQ(C_ref[0], C_test[0]); + ASSERT_EQ(C_ref[1], C_test[1]); + } +} + +TEST_P(GetProjSubspaceTest, RandomValues) { RunGetProjSubspaceTest(1); } + +TEST_P(GetProjSubspaceTest, ExtremeValues) { + RunGetProjSubspaceTest_ExtremeValues(); +} + +TEST_P(GetProjSubspaceTest, DISABLED_Speed) { RunGetProjSubspaceTest(200000); } + +#if HAVE_AVX2 + +INSTANTIATE_TEST_SUITE_P(AVX2, GetProjSubspaceTest, + ::testing::Values(av1_calc_proj_params_avx2)); #endif // HAVE_AVX2 -} // namespace +} // namespace get_proj_subspace_test_lowbd +#endif // CONFIG_AV1_HIGHBITDEPTH diff --git a/media/libaom/src/test/qm_test.cc b/media/libaom/src/test/qm_test.cc index c87506b41..d1dfbb849 100644 --- a/media/libaom/src/test/qm_test.cc +++ b/media/libaom/src/test/qm_test.cc @@ -33,7 +33,7 @@ class QMTest virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); encoder->Control(AV1E_SET_ENABLE_QM, 1); encoder->Control(AV1E_SET_QM_MIN, qm_min_); diff --git a/media/libaom/src/test/quantize_func_test.cc b/media/libaom/src/test/quantize_func_test.cc index 554d0c721..b40b38d5a 100644 --- a/media/libaom/src/test/quantize_func_test.cc +++ b/media/libaom/src/test/quantize_func_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/aom_config.h" @@ -63,9 +65,9 @@ void highbd_quan64x64_wrapper(QUAN_PARAM_LIST) { HBD_QUAN_FUNC; } -typedef enum { TYPE_B, TYPE_DC, TYPE_FP } QuantType; +enum QuantType { TYPE_B, TYPE_DC, TYPE_FP }; -using ::testing::tuple; +using std::tuple; typedef tuple<QuantizeFunc, QuantizeFunc, TX_SIZE, QuantType, aom_bit_depth_t> QuantizeParam; @@ -191,6 +193,13 @@ class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> { } } + void FillCoeffRandomRows(int num) { + FillCoeffZero(); + for (int i = 0; i < num; ++i) { + coeff_[i] = GetRandomCoeff(); + } + } + void FillCoeffZero() { FillCoeff(0); } void FillCoeffConstant() { @@ -286,140 +295,253 @@ TEST_P(QuantizeTest, DISABLED_Speed) { const int16_t *quant_shift = qtab_->quant.y_quant_shift[q]; const int16_t *dequant = qtab_->dequant.y_dequant_QTX[q]; const int kNumTests = 5000000; - aom_usec_timer timer; + aom_usec_timer timer, simd_timer; + int rows = tx_size_high[tx_size_]; + int cols = tx_size_wide[tx_size_]; + rows = AOMMIN(32, rows); + cols = AOMMIN(32, cols); + for (int cnt = 0; cnt <= rows; cnt++) { + FillCoeffRandomRows(cnt * cols); + + aom_usec_timer_start(&timer); + for (int n = 0; n < kNumTests; ++n) { + quant_ref_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, + qcoeff, dqcoeff, dequant, eob, sc->scan, sc->iscan); + } + aom_usec_timer_mark(&timer); - FillCoeffRandom(); + aom_usec_timer_start(&simd_timer); + for (int n = 0; n < kNumTests; ++n) { + quant_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, qcoeff, + dqcoeff, dequant, eob, sc->scan, sc->iscan); + } + aom_usec_timer_mark(&simd_timer); - aom_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - quant_(coeff_ptr, n_coeffs, zbin, round_fp, quant_fp, quant_shift, qcoeff, - dqcoeff, dequant, eob, sc->scan, sc->iscan); + const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); + const int simd_elapsed_time = + static_cast<int>(aom_usec_timer_elapsed(&simd_timer)); + printf("c_time = %d \t simd_time = %d \t Gain = %d \n", elapsed_time, + simd_elapsed_time, (elapsed_time / simd_elapsed_time)); } - aom_usec_timer_mark(&timer); - - const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); - printf("Elapsed time: %d us\n", elapsed_time); } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_AVX2 const QuantizeParam kQParamArrayAvx2[] = { - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_16X16, TYPE_FP, - AOM_BITS_8), - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_4X16, TYPE_FP, - AOM_BITS_8), - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_16X4, TYPE_FP, - AOM_BITS_8), - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, TX_32X8, TYPE_FP, - AOM_BITS_8), - 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(&av1_quantize_fp_c, &av1_quantize_fp_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, + static_cast<TX_SIZE>(TX_4X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, + static_cast<TX_SIZE>(TX_16X4), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, + static_cast<TX_SIZE>(TX_32X8), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_avx2, + static_cast<TX_SIZE>(TX_8X32), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, + static_cast<TX_SIZE>(TX_32X32), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, + static_cast<TX_SIZE>(TX_16X64), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_32x32_c, &av1_quantize_fp_32x32_avx2, + static_cast<TX_SIZE>(TX_64X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_64x64_c, &av1_quantize_fp_64x64_avx2, + static_cast<TX_SIZE>(TX_64X64), TYPE_FP, AOM_BITS_8), +#if CONFIG_AV1_HIGHBITDEPTH 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), + &highbd_quan16x16_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_16X16), 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_10), + &highbd_quan16x16_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_16X16), TYPE_FP, AOM_BITS_10), make_tuple(&highbd_quan16x16_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan16x16_wrapper<av1_highbd_quantize_fp_avx2>, TX_16X16, - TYPE_FP, AOM_BITS_12), + &highbd_quan16x16_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_16X16), TYPE_FP, AOM_BITS_12), make_tuple(&highbd_quan32x32_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, TX_32X32, - TYPE_FP, AOM_BITS_8), + &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_32X32), TYPE_FP, AOM_BITS_8), make_tuple(&highbd_quan32x32_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, TX_32X32, - TYPE_FP, AOM_BITS_10), + &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_32X32), TYPE_FP, AOM_BITS_10), make_tuple(&highbd_quan32x32_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, TX_32X32, - TYPE_FP, AOM_BITS_12), + &highbd_quan32x32_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_32X32), TYPE_FP, AOM_BITS_12), make_tuple(&highbd_quan64x64_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, TX_64X64, - TYPE_FP, AOM_BITS_8), + &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_64X64), TYPE_FP, AOM_BITS_8), make_tuple(&highbd_quan64x64_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, TX_64X64, - TYPE_FP, AOM_BITS_10), + &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_64X64), TYPE_FP, AOM_BITS_10), make_tuple(&highbd_quan64x64_wrapper<av1_highbd_quantize_fp_c>, - &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, TX_64X64, - TYPE_FP, AOM_BITS_12), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, TX_16X16, - TYPE_B, AOM_BITS_8), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, TX_16X16, - TYPE_B, AOM_BITS_10), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, TX_16X16, - TYPE_B, AOM_BITS_12), + &highbd_quan64x64_wrapper<av1_highbd_quantize_fp_avx2>, + static_cast<TX_SIZE>(TX_64X64), TYPE_FP, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_avx2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_avx2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_avx2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_12), +#endif + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_8X8), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_avx2, + static_cast<TX_SIZE>(TX_4X4), TYPE_B, AOM_BITS_8) }; -INSTANTIATE_TEST_CASE_P(AVX2, QuantizeTest, - ::testing::ValuesIn(kQParamArrayAvx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, QuantizeTest, + ::testing::ValuesIn(kQParamArrayAvx2)); #endif // HAVE_AVX2 #if HAVE_SSE2 const QuantizeParam kQParamArraySSE2[] = { - 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(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_16X4, TYPE_FP, - AOM_BITS_8), - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_8X32, TYPE_FP, - AOM_BITS_8), - make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, TX_32X8, TYPE_FP, - AOM_BITS_8), - make_tuple(&aom_quantize_b_c, &aom_quantize_b_sse2, TX_16X16, TYPE_B, - AOM_BITS_8), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, TX_16X16, - TYPE_B, AOM_BITS_8), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, TX_16X16, - TYPE_B, AOM_BITS_10), - make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, TX_16X16, - TYPE_B, AOM_BITS_12), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, + static_cast<TX_SIZE>(TX_4X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, + static_cast<TX_SIZE>(TX_16X4), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, + static_cast<TX_SIZE>(TX_8X32), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_sse2, + static_cast<TX_SIZE>(TX_32X8), TYPE_FP, AOM_BITS_8), + make_tuple(&aom_quantize_b_c, &aom_quantize_b_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_c, &aom_highbd_quantize_b_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_adaptive_c, + &aom_highbd_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_12), make_tuple(&aom_highbd_quantize_b_32x32_c, &aom_highbd_quantize_b_32x32_sse2, - TX_32X32, TYPE_B, AOM_BITS_8), + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8), make_tuple(&aom_highbd_quantize_b_32x32_c, &aom_highbd_quantize_b_32x32_sse2, - TX_32X32, TYPE_B, AOM_BITS_10), + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_10), make_tuple(&aom_highbd_quantize_b_32x32_c, &aom_highbd_quantize_b_32x32_sse2, - TX_32X32, TYPE_B, AOM_BITS_12), + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_32x32_adaptive_c, + &aom_highbd_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_64x64_c, &aom_highbd_quantize_b_64x64_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_12), + make_tuple(&aom_highbd_quantize_b_64x64_adaptive_c, + &aom_highbd_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_8), + make_tuple(&aom_highbd_quantize_b_64x64_adaptive_c, + &aom_highbd_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_10), + make_tuple(&aom_highbd_quantize_b_64x64_adaptive_c, + &aom_highbd_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_12), +#endif + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_8X8), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_adaptive_c, &aom_quantize_b_adaptive_sse2, + static_cast<TX_SIZE>(TX_4X4), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_32x32_adaptive_c, + &aom_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_32x32_adaptive_c, + &aom_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_16X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_32x32_adaptive_c, + &aom_quantize_b_32x32_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_64x64_adaptive_c, + &aom_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_32X64), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_64x64_adaptive_c, + &aom_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_64X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_64x64_adaptive_c, + &aom_quantize_b_64x64_adaptive_sse2, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_8) }; -INSTANTIATE_TEST_CASE_P(SSE2, QuantizeTest, - ::testing::ValuesIn(kQParamArraySSE2)); +INSTANTIATE_TEST_SUITE_P(SSE2, QuantizeTest, + ::testing::ValuesIn(kQParamArraySSE2)); +#endif + +#if HAVE_NEON +const QuantizeParam kQParamArrayNEON[] = { + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_neon, + static_cast<TX_SIZE>(TX_16X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_neon, + static_cast<TX_SIZE>(TX_4X16), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_neon, + static_cast<TX_SIZE>(TX_16X4), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_neon, + static_cast<TX_SIZE>(TX_8X32), TYPE_FP, AOM_BITS_8), + make_tuple(&av1_quantize_fp_c, &av1_quantize_fp_neon, + static_cast<TX_SIZE>(TX_32X8), TYPE_FP, AOM_BITS_8) +}; + +INSTANTIATE_TEST_SUITE_P(NEON, QuantizeTest, + ::testing::ValuesIn(kQParamArrayNEON)); #endif #if HAVE_SSSE3 && ARCH_X86_64 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_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))); + ::testing::Values( + make_tuple(&aom_quantize_b_c, &aom_quantize_b_ssse3, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_32x32_c, &aom_quantize_b_32x32_ssse3, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_64x64_c, &aom_quantize_b_64x64_ssse3, + static_cast<TX_SIZE>(TX_64X64), TYPE_B, AOM_BITS_8))); #endif // HAVE_SSSE3 && ARCH_X86_64 #if HAVE_AVX && ARCH_X86_64 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_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))); + make_tuple(&aom_quantize_b_c, &aom_quantize_b_avx, + static_cast<TX_SIZE>(TX_16X16), TYPE_B, AOM_BITS_8), + make_tuple(&aom_quantize_b_32x32_c, &aom_quantize_b_32x32_avx, + static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8))); #endif // HAVE_AVX && ARCH_X86_64 } // namespace diff --git a/media/libaom/src/test/reconinter_test.cc b/media/libaom/src/test/reconinter_test.cc index a8536e517..51bec0eab 100644 --- a/media/libaom/src/test/reconinter_test.cc +++ b/media/libaom/src/test/reconinter_test.cc @@ -12,6 +12,7 @@ #include <stdint.h> #include <stdio.h> #include <string.h> +#include <tuple> #include "config/aom_config.h" #include "config/av1_rtcd.h" @@ -34,7 +35,7 @@ typedef void (*buildcompdiffwtdmaskd_func)(uint8_t *mask, const uint8_t *src1, int src1_stride, int h, int w); -typedef ::testing::tuple<BLOCK_SIZE, buildcompdiffwtdmaskd_func> +typedef std::tuple<BLOCK_SIZE, buildcompdiffwtdmaskd_func> BuildCompDiffwtdMaskDParam; #if HAVE_SSE4_1 @@ -63,7 +64,7 @@ typedef void (*buildcompdiffwtdmaskd16_func)( int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, ConvolveParams *conv_params, int bd); -typedef ::testing::tuple<int, buildcompdiffwtdmaskd16_func, BLOCK_SIZE> +typedef std::tuple<int, buildcompdiffwtdmaskd16_func, BLOCK_SIZE> BuildCompDiffwtdMaskD16Param; #if HAVE_SSE4_1 || HAVE_NEON @@ -234,25 +235,25 @@ TEST_P(BuildCompDiffwtdMaskD16Test, DISABLED_Speed) { } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1, BuildCompDiffwtdMaskTest, - BuildParams(av1_build_compound_diffwtd_mask_sse4_1)); +INSTANTIATE_TEST_SUITE_P(SSE4_1, BuildCompDiffwtdMaskTest, + BuildParams(av1_build_compound_diffwtd_mask_sse4_1)); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, BuildCompDiffwtdMaskD16Test, 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_SUITE_P(AVX2, BuildCompDiffwtdMaskTest, + BuildParams(av1_build_compound_diffwtd_mask_avx2)); -INSTANTIATE_TEST_CASE_P(AVX2, BuildCompDiffwtdMaskD16Test, - BuildParams(av1_build_compound_diffwtd_mask_d16_avx2)); +INSTANTIATE_TEST_SUITE_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)); +INSTANTIATE_TEST_SUITE_P(NEON, BuildCompDiffwtdMaskD16Test, + BuildParams(av1_build_compound_diffwtd_mask_d16_neon)); #endif } // namespace diff --git a/media/libaom/src/test/resize_test.cc b/media/libaom/src/test/resize_test.cc index b270b8362..bcf6794d0 100644 --- a/media/libaom/src/test/resize_test.cc +++ b/media/libaom/src/test/resize_test.cc @@ -12,6 +12,7 @@ #include <climits> #include <vector> #include "aom_dsp/aom_dsp_common.h" +#include "common/tools_common.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" #include "test/encode_test_driver.h" @@ -47,7 +48,7 @@ static void write_ivf_file_header(const aom_codec_enc_cfg_t *const cfg, header[3] = 'F'; mem_put_le16(header + 4, 0); /* version */ mem_put_le16(header + 6, 32); /* headersize */ - mem_put_le32(header + 8, 0x30395056); /* fourcc (av1) */ + mem_put_le32(header + 8, AV1_FOURCC); /* fourcc (av1) */ mem_put_le16(header + 12, cfg->g_w); /* width */ mem_put_le16(header + 14, cfg->g_h); /* height */ mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */ @@ -297,7 +298,7 @@ class ResizeInternalTestLarge : public ResizeTest { virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0]; - EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.5); + EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 3.0); } #if WRITE_COMPRESSED_STREAM @@ -374,6 +375,7 @@ class ResizeRealtimeTest if (video->frame() == 0) { encoder->Control(AV1E_SET_AQ_MODE, 3); encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); + encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); } if (change_bitrate_ && video->frame() == 120) { @@ -616,12 +618,12 @@ TEST_P(ResizeCspTest, DISABLED_TestResizeCspWorks) { TEST_P(ResizeCspTest, TestResizeCspWorks) { #endif const aom_img_fmt_t image_formats[] = { AOM_IMG_FMT_I420, AOM_IMG_FMT_I444 }; - for (size_t i = 0; i < GTEST_ARRAY_SIZE_(image_formats); ++i) { - ResizingCspVideoSource video(image_formats[i]); + for (const aom_img_fmt_t &img_format : image_formats) { + ResizingCspVideoSource video(img_format); init_flags_ = AOM_CODEC_USE_PSNR; cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48; cfg_.g_lag_in_frames = 0; - cfg_.g_profile = (image_formats[i] == AOM_IMG_FMT_I420) ? 0 : 1; + cfg_.g_profile = (img_format == AOM_IMG_FMT_I420) ? 0 : 1; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // Check we decoded the same number of frames as we attempted to encode diff --git a/media/libaom/src/test/rt_end_to_end_test.cc b/media/libaom/src/test/rt_end_to_end_test.cc new file mode 100644 index 000000000..f14d12474 --- /dev/null +++ b/media/libaom/src/test/rt_end_to_end_test.cc @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <memory> +#include <ostream> +#include <string> +#include <unordered_map> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/util.h" +#include "test/y4m_video_source.h" +#include "test/yuv_video_source.h" + +namespace { + +const unsigned int kFrames = 10; +const int kBitrate = 500; + +// List of psnr thresholds for speed settings 6-8 +// keys: video, speed, aq mode. +std::unordered_map<std::string, + std::unordered_map<int, std::unordered_map<int, double>>> + kPsnrThreshold = { { "park_joy_90p_8_420.y4m", + { { 5, { { 0, 35.4 }, { 3, 36.4 } } }, + { 6, { { 0, 35.3 }, { 3, 36.2 } } }, + { 7, { { 0, 34.9 }, { 3, 35.8 } } }, + { 8, { { 0, 35.0 }, { 3, 35.8 } } } } }, + { "paris_352_288_30.y4m", + { { 5, { { 0, 36.2 }, { 3, 36.7 } } }, + { 6, { { 0, 36.1 }, { 3, 36.6 } } }, + { 7, { { 0, 35.5 }, { 3, 36.0 } } }, + { 8, { { 0, 36.0 }, { 3, 36.5 } } } } }, + { "niklas_1280_720_30.y4m", + { { 5, { { 0, 34.6 }, { 3, 34.6 } } }, + { 6, { { 0, 34.2 }, { 3, 34.2 } } }, + { 7, { { 0, 33.7 }, { 3, 33.6 } } }, + { 8, { { 0, 33.6 }, { 3, 33.4 } } } } } }; + +typedef struct { + const char *filename; + unsigned int input_bit_depth; + aom_img_fmt fmt; + aom_bit_depth_t bit_depth; + unsigned int profile; +} TestVideoParam; + +std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) { + return os << "TestVideoParam { filename:" << test_arg.filename + << " input_bit_depth:" << test_arg.input_bit_depth + << " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth + << " profile:" << test_arg.profile << " }"; +} + +const TestVideoParam kTestVectors[] = { + { "park_joy_90p_8_420.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, + { "paris_352_288_30.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, + { "niklas_1280_720_30.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, +}; + +// Params: test video, speed, aq mode, threads, tile columns. +class RTEndToEndTest + : public ::libaom_test::CodecTestWith5Params<TestVideoParam, int, + unsigned int, int, int>, + public ::libaom_test::EncoderTest { + protected: + RTEndToEndTest() + : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), + cpu_used_(GET_PARAM(2)), psnr_(0.0), nframes_(0), + aq_mode_(GET_PARAM(3)), threads_(GET_PARAM(4)), + tile_columns_(GET_PARAM(5)) {} + + virtual ~RTEndToEndTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(::libaom_test::kRealTime); + + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_threads = threads_; + cfg_.rc_buf_sz = 1000; + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 600; + } + + virtual void BeginPassHook(unsigned int) { + psnr_ = 0.0; + nframes_ = 0; + } + + virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { + psnr_ += pkt->data.psnr.psnr[0]; + nframes_++; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); + encoder->Control(AV1E_SET_TILE_COLUMNS, tile_columns_); + encoder->Control(AOME_SET_CPUUSED, cpu_used_); + encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); + encoder->Control(AV1E_SET_AQ_MODE, aq_mode_); + encoder->Control(AV1E_SET_ROW_MT, 1); + } + } + + double GetAveragePsnr() const { + if (nframes_) return psnr_ / nframes_; + return 0.0; + } + + double GetPsnrThreshold() { + return kPsnrThreshold[test_video_param_.filename][cpu_used_][aq_mode_]; + } + + void DoTest() { + cfg_.rc_target_bitrate = kBitrate; + cfg_.g_error_resilient = 0; + cfg_.g_profile = test_video_param_.profile; + cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; + cfg_.g_bit_depth = test_video_param_.bit_depth; + init_flags_ = AOM_CODEC_USE_PSNR; + if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; + + std::unique_ptr<libaom_test::VideoSource> video; + video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, + kFrames)); + ASSERT_TRUE(video.get() != NULL); + + ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); + const double psnr = GetAveragePsnr(); + EXPECT_GT(psnr, GetPsnrThreshold()) + << "cpu used = " << cpu_used_ << " aq mode = " << aq_mode_; + } + + TestVideoParam test_video_param_; + int cpu_used_; + + private: + double psnr_; + unsigned int nframes_; + unsigned int aq_mode_; + int threads_; + int tile_columns_; +}; + +class RTEndToEndTestThreaded : public RTEndToEndTest {}; + +TEST_P(RTEndToEndTest, EndtoEndPSNRTest) { DoTest(); } + +TEST_P(RTEndToEndTestThreaded, EndtoEndPSNRTest) { DoTest(); } + +AV1_INSTANTIATE_TEST_CASE(RTEndToEndTest, ::testing::ValuesIn(kTestVectors), + ::testing::Range(5, 9), + ::testing::Values<unsigned int>(0, 3), + ::testing::Values(1), ::testing::Values(1)); + +AV1_INSTANTIATE_TEST_CASE(RTEndToEndTestThreaded, + ::testing::ValuesIn(kTestVectors), + ::testing::Range(5, 9), + ::testing::Values<unsigned int>(0, 3), + ::testing::Range(2, 5), ::testing::Range(2, 5)); +} // namespace diff --git a/media/libaom/src/test/sad_test.cc b/media/libaom/src/test/sad_test.cc index 845fe79da..0bdbf3745 100644 --- a/media/libaom/src/test/sad_test.cc +++ b/media/libaom/src/test/sad_test.cc @@ -12,6 +12,7 @@ #include <string.h> #include <limits.h> #include <stdio.h> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -28,34 +29,42 @@ typedef unsigned int (*SadMxNFunc)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); -typedef ::testing::tuple<int, int, SadMxNFunc, int> SadMxNParam; +typedef std::tuple<int, int, SadMxNFunc, int> SadMxNParam; typedef uint32_t (*SadMxNAvgFunc)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); -typedef ::testing::tuple<int, int, SadMxNAvgFunc, int> SadMxNAvgParam; - -typedef void (*JntCompAvgFunc)(uint8_t *comp_pred, const uint8_t *pred, - int width, int height, const uint8_t *ref, - int ref_stride, - const JNT_COMP_PARAMS *jcp_param); -typedef ::testing::tuple<int, int, JntCompAvgFunc, int> JntCompAvgParam; - -typedef unsigned int (*JntSadMxhFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int width, int height); -typedef ::testing::tuple<int, int, JntSadMxhFunc, int> JntSadMxhParam; - -typedef uint32_t (*JntSadMxNAvgFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - const uint8_t *second_pred, - const JNT_COMP_PARAMS *jcp_param); -typedef ::testing::tuple<int, int, JntSadMxNAvgFunc, int> JntSadMxNAvgParam; +typedef std::tuple<int, int, SadMxNAvgFunc, int> SadMxNAvgParam; + +typedef void (*DistWtdCompAvgFunc)(uint8_t *comp_pred, const uint8_t *pred, + int width, int height, const uint8_t *ref, + int ref_stride, + const DIST_WTD_COMP_PARAMS *jcp_param); +typedef std::tuple<int, int, DistWtdCompAvgFunc, int> DistWtdCompAvgParam; + +typedef unsigned int (*DistWtdSadMxhFunc)(const uint8_t *src_ptr, + int src_stride, + const uint8_t *ref_ptr, + int ref_stride, int width, + int height); +typedef std::tuple<int, int, DistWtdSadMxhFunc, int> DistWtdSadMxhParam; + +typedef uint32_t (*DistWtdSadMxNAvgFunc)(const uint8_t *src_ptr, int src_stride, + const uint8_t *ref_ptr, int ref_stride, + const uint8_t *second_pred, + const DIST_WTD_COMP_PARAMS *jcp_param); +typedef std::tuple<int, int, DistWtdSadMxNAvgFunc, int> DistWtdSadMxNAvgParam; typedef void (*SadMxNx4Func)(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_ptr[], int ref_stride, uint32_t *sad_array); -typedef ::testing::tuple<int, int, SadMxNx4Func, int> SadMxNx4Param; +typedef std::tuple<int, int, SadMxNx4Func, int> SadMxNx4Param; + +typedef void (*SadMxNx4AvgFunc)(const uint8_t *src_ptr, int src_stride, + const uint8_t *const ref_ptr[], int ref_stride, + const uint8_t *second_pred, + uint32_t *sad_array); +typedef std::tuple<int, int, SadMxNx4AvgFunc, int> SadMxNx4AvgParam; using libaom_test::ACMRandom; @@ -203,7 +212,7 @@ class SADTestBase : public ::testing::Test { return sad; } - void ReferenceJntCompAvg(int block_idx) { + void ReferenceDistWtdCompAvg(int block_idx) { const uint8_t *const reference8 = GetReference(block_idx); const uint8_t *const second_pred8 = second_pred_; uint8_t *const comp_pred8 = comp_pred_; @@ -228,7 +237,7 @@ class SADTestBase : public ::testing::Test { } } - unsigned int ReferenceJntSADavg(int block_idx) { + unsigned int ReferenceDistWtdSADavg(int block_idx) { unsigned int sad = 0; const uint8_t *const reference8 = GetReference(block_idx); const uint8_t *const source8 = source_data_; @@ -305,7 +314,7 @@ class SADTestBase : public ::testing::Test { static uint8_t *comp_pred_test_; static uint8_t *comp_pred8_test_; static uint16_t *comp_pred16_test_; - JNT_COMP_PARAMS jcp_param_; + DIST_WTD_COMP_PARAMS jcp_param_; ACMRandom rnd_; }; @@ -336,6 +345,42 @@ class SADx4Test : public ::testing::WithParamInterface<SadMxNx4Param>, } }; +class SADx4AvgTest : public ::testing::WithParamInterface<SadMxNx4AvgParam>, + public SADTestBase { + public: + SADx4AvgTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} + + protected: + void SADs(unsigned int *results) { + const uint8_t *references[] = { GetReference(0), GetReference(1), + GetReference(2), GetReference(3) }; + + ASM_REGISTER_STATE_CHECK(GET_PARAM(2)(source_data_, source_stride_, + references, reference_stride_, + second_pred_, results)); + } + + void CheckSADs() { + unsigned int reference_sad, exp_sad[4]; + + SADs(exp_sad); + for (int block = 0; block < 4; ++block) { + reference_sad = ReferenceSADavg(block); + + EXPECT_EQ(reference_sad, exp_sad[block]) << "block " << block; + } + } + + void SpeedSAD() { + int test_count = 200000; + unsigned int exp_sad[4]; + while (test_count > 0) { + SADs(exp_sad); + test_count -= 1; + } + } +}; + class SADTest : public ::testing::WithParamInterface<SadMxNParam>, public SADTestBase { public: @@ -391,13 +436,15 @@ class SADavgTest : public ::testing::WithParamInterface<SadMxNAvgParam>, } }; -class JntCompAvgTest : public ::testing::WithParamInterface<JntCompAvgParam>, - public SADTestBase { +class DistWtdCompAvgTest + : public ::testing::WithParamInterface<DistWtdCompAvgParam>, + public SADTestBase { public: - JntCompAvgTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} + DistWtdCompAvgTest() + : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} protected: - void jnt_comp_avg(int block_idx) { + void dist_wtd_comp_avg(int block_idx) { const uint8_t *const reference = GetReference(block_idx); ASM_REGISTER_STATE_CHECK(GET_PARAM(2)(comp_pred_test_, second_pred_, width_, @@ -411,8 +458,8 @@ class JntCompAvgTest : public ::testing::WithParamInterface<JntCompAvgParam>, jcp_param_.fwd_offset = quant_dist_lookup_table[j][i][0]; jcp_param_.bck_offset = quant_dist_lookup_table[j][i][1]; - ReferenceJntCompAvg(0); - jnt_comp_avg(0); + ReferenceDistWtdCompAvg(0); + dist_wtd_comp_avg(0); for (int y = 0; y < height_; ++y) for (int x = 0; x < width_; ++x) @@ -423,10 +470,10 @@ class JntCompAvgTest : public ::testing::WithParamInterface<JntCompAvgParam>, } }; -class JntSADTest : public ::testing::WithParamInterface<JntSadMxhParam>, - public SADTestBase { +class DistWtdSADTest : public ::testing::WithParamInterface<DistWtdSadMxhParam>, + public SADTestBase { public: - JntSADTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} + DistWtdSADTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} protected: unsigned int SAD(int block_idx) { @@ -455,13 +502,14 @@ class JntSADTest : public ::testing::WithParamInterface<JntSadMxhParam>, } }; -class JntSADavgTest : public ::testing::WithParamInterface<JntSadMxNAvgParam>, - public SADTestBase { +class DistWtdSADavgTest + : public ::testing::WithParamInterface<DistWtdSadMxNAvgParam>, + public SADTestBase { public: - JntSADavgTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} + DistWtdSADavgTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(3)) {} protected: - unsigned int jnt_SAD_avg(int block_idx) { + unsigned int dist_wtd_SAD_avg(int block_idx) { unsigned int ret; const uint8_t *const reference = GetReference(block_idx); @@ -477,8 +525,8 @@ class JntSADavgTest : public ::testing::WithParamInterface<JntSadMxNAvgParam>, jcp_param_.fwd_offset = quant_dist_lookup_table[j][i][0]; jcp_param_.bck_offset = quant_dist_lookup_table[j][i][1]; - const unsigned int reference_sad = ReferenceJntSADavg(0); - const unsigned int exp_sad = jnt_SAD_avg(0); + const unsigned int reference_sad = ReferenceDistWtdSADavg(0); + const unsigned int exp_sad = dist_wtd_SAD_avg(0); ASSERT_EQ(reference_sad, exp_sad); } @@ -608,19 +656,19 @@ TEST_P(SADavgTest, ShortSrc) { source_stride_ = tmp_stride; } -TEST_P(JntCompAvgTest, MaxRef) { +TEST_P(DistWtdCompAvgTest, MaxRef) { FillConstant(reference_data_, reference_stride_, mask_); FillConstant(second_pred_, width_, 0); CheckCompAvg(); } -TEST_P(JntCompAvgTest, MaxSecondPred) { +TEST_P(DistWtdCompAvgTest, MaxSecondPred) { FillConstant(reference_data_, reference_stride_, 0); FillConstant(second_pred_, width_, mask_); CheckCompAvg(); } -TEST_P(JntCompAvgTest, ShortRef) { +TEST_P(DistWtdCompAvgTest, ShortRef) { const int tmp_stride = reference_stride_; reference_stride_ >>= 1; FillRandom(reference_data_, reference_stride_); @@ -629,7 +677,7 @@ TEST_P(JntCompAvgTest, ShortRef) { reference_stride_ = tmp_stride; } -TEST_P(JntCompAvgTest, UnalignedRef) { +TEST_P(DistWtdCompAvgTest, UnalignedRef) { // The reference frame, but not the source frame, may be unaligned for // certain types of searches. const int tmp_stride = reference_stride_; @@ -640,19 +688,19 @@ TEST_P(JntCompAvgTest, UnalignedRef) { reference_stride_ = tmp_stride; } -TEST_P(JntSADTest, MaxRef) { +TEST_P(DistWtdSADTest, MaxRef) { FillConstant(source_data_, source_stride_, 0); FillConstant(reference_data_, reference_stride_, mask_); CheckSAD(); } -TEST_P(JntSADTest, MaxSrc) { +TEST_P(DistWtdSADTest, MaxSrc) { FillConstant(source_data_, source_stride_, mask_); FillConstant(reference_data_, reference_stride_, 0); CheckSAD(); } -TEST_P(JntSADTest, ShortRef) { +TEST_P(DistWtdSADTest, ShortRef) { const int tmp_stride = reference_stride_; reference_stride_ >>= 1; FillRandom(source_data_, source_stride_); @@ -661,7 +709,7 @@ TEST_P(JntSADTest, ShortRef) { reference_stride_ = tmp_stride; } -TEST_P(JntSADTest, UnalignedRef) { +TEST_P(DistWtdSADTest, UnalignedRef) { // The reference frame, but not the source frame, may be unaligned for // certain types of searches. const int tmp_stride = reference_stride_; @@ -672,7 +720,7 @@ TEST_P(JntSADTest, UnalignedRef) { reference_stride_ = tmp_stride; } -TEST_P(JntSADTest, ShortSrc) { +TEST_P(DistWtdSADTest, ShortSrc) { const int tmp_stride = source_stride_; source_stride_ >>= 1; int test_count = 2000; @@ -685,20 +733,20 @@ TEST_P(JntSADTest, ShortSrc) { source_stride_ = tmp_stride; } -TEST_P(JntSADavgTest, MaxRef) { +TEST_P(DistWtdSADavgTest, MaxRef) { FillConstant(source_data_, source_stride_, 0); FillConstant(reference_data_, reference_stride_, mask_); FillConstant(second_pred_, width_, 0); CheckSAD(); } -TEST_P(JntSADavgTest, MaxSrc) { +TEST_P(DistWtdSADavgTest, MaxSrc) { FillConstant(source_data_, source_stride_, mask_); FillConstant(reference_data_, reference_stride_, 0); FillConstant(second_pred_, width_, 0); CheckSAD(); } -TEST_P(JntSADavgTest, ShortRef) { +TEST_P(DistWtdSADavgTest, ShortRef) { const int tmp_stride = reference_stride_; reference_stride_ >>= 1; FillRandom(source_data_, source_stride_); @@ -708,7 +756,7 @@ TEST_P(JntSADavgTest, ShortRef) { reference_stride_ = tmp_stride; } -TEST_P(JntSADavgTest, UnalignedRef) { +TEST_P(DistWtdSADavgTest, UnalignedRef) { // The reference frame, but not the source frame, may be unaligned for // certain types of searches. const int tmp_stride = reference_stride_; @@ -720,7 +768,7 @@ TEST_P(JntSADavgTest, UnalignedRef) { reference_stride_ = tmp_stride; } -TEST_P(JntSADavgTest, ShortSrc) { +TEST_P(DistWtdSADavgTest, ShortSrc) { const int tmp_stride = source_stride_; source_stride_ >>= 1; int test_count = 2000; @@ -806,7 +854,70 @@ TEST_P(SADx4Test, SrcAlignedByWidth) { source_data_ = tmp_source_data; } -using ::testing::make_tuple; +using std::make_tuple; + +#if SPEED_TEST +TEST_P(SADx4AvgTest, Speed) { + int tmp_stride = reference_stride_; + reference_stride_ >>= 1; + FillRandom(source_data_, source_stride_); + FillRandom(GetReference(0), reference_stride_); + FillRandom(GetReference(1), reference_stride_); + FillRandom(GetReference(2), reference_stride_); + FillRandom(GetReference(3), reference_stride_); + FillRandom(second_pred_, width_); + SpeedSAD(); + reference_stride_ = tmp_stride; +} +#endif + +TEST_P(SADx4AvgTest, MaxRef) { + FillConstant(source_data_, source_stride_, 0); + FillConstant(GetReference(0), reference_stride_, mask_); + FillConstant(GetReference(1), reference_stride_, mask_); + FillConstant(GetReference(2), reference_stride_, mask_); + FillConstant(GetReference(3), reference_stride_, mask_); + FillConstant(second_pred_, width_, 0); + CheckSADs(); +} + +TEST_P(SADx4AvgTest, MaxSrc) { + FillConstant(source_data_, source_stride_, mask_); + FillConstant(GetReference(0), reference_stride_, 0); + FillConstant(GetReference(1), reference_stride_, 0); + FillConstant(GetReference(2), reference_stride_, 0); + FillConstant(GetReference(3), reference_stride_, 0); + FillConstant(second_pred_, width_, 0); + CheckSADs(); +} + +TEST_P(SADx4AvgTest, ShortRef) { + int tmp_stride = reference_stride_; + reference_stride_ >>= 1; + FillRandom(source_data_, source_stride_); + FillRandom(GetReference(0), reference_stride_); + FillRandom(GetReference(1), reference_stride_); + FillRandom(GetReference(2), reference_stride_); + FillRandom(GetReference(3), reference_stride_); + FillRandom(second_pred_, width_); + CheckSADs(); + reference_stride_ = tmp_stride; +} + +TEST_P(SADx4AvgTest, UnalignedRef) { + // The reference frame, but not the source frame, may be unaligned for + // certain types of searches. + int tmp_stride = reference_stride_; + reference_stride_ -= 1; + FillRandom(source_data_, source_stride_); + FillRandom(GetReference(0), reference_stride_); + FillRandom(GetReference(1), reference_stride_); + FillRandom(GetReference(2), reference_stride_); + FillRandom(GetReference(3), reference_stride_); + FillRandom(second_pred_, width_); + CheckSADs(); + reference_stride_ = tmp_stride; +} //------------------------------------------------------------------------------ // C functions @@ -827,6 +938,7 @@ const SadMxNParam c_tests[] = { make_tuple(8, 4, &aom_sad8x4_c, -1), make_tuple(4, 8, &aom_sad4x8_c, -1), make_tuple(4, 4, &aom_sad4x4_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128_c, 8), make_tuple(128, 64, &aom_highbd_sad128x64_c, 8), make_tuple(64, 128, &aom_highbd_sad64x128_c, 8), @@ -875,8 +987,39 @@ const SadMxNParam c_tests[] = { make_tuple(8, 4, &aom_highbd_sad8x4_c, 12), make_tuple(4, 8, &aom_highbd_sad4x8_c, 12), make_tuple(4, 4, &aom_highbd_sad4x4_c, 12), +#endif // CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_sad64x16_c, -1), + make_tuple(16, 64, &aom_sad16x64_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16_c, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_c, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_c, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_c, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_c, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_c, 12), +#endif + make_tuple(32, 8, &aom_sad32x8_c, -1), + make_tuple(8, 32, &aom_sad8x32_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8_c, 8), + make_tuple(8, 32, &aom_highbd_sad8x32_c, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_c, 10), + make_tuple(8, 32, &aom_highbd_sad8x32_c, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_c, 12), + make_tuple(8, 32, &aom_highbd_sad8x32_c, 12), +#endif + make_tuple(16, 4, &aom_sad16x4_c, -1), + make_tuple(4, 16, &aom_sad4x16_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4_c, 8), + make_tuple(4, 16, &aom_highbd_sad4x16_c, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_c, 10), + make_tuple(4, 16, &aom_highbd_sad4x16_c, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_c, 12), + make_tuple(4, 16, &aom_highbd_sad4x16_c, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(C, SADTest, ::testing::ValuesIn(c_tests)); +INSTANTIATE_TEST_SUITE_P(C, SADTest, ::testing::ValuesIn(c_tests)); const SadMxNAvgParam avg_c_tests[] = { make_tuple(128, 128, &aom_sad128x128_avg_c, -1), @@ -895,6 +1038,7 @@ const SadMxNAvgParam avg_c_tests[] = { make_tuple(8, 4, &aom_sad8x4_avg_c, -1), make_tuple(4, 8, &aom_sad4x8_avg_c, -1), make_tuple(4, 4, &aom_sad4x4_avg_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128_avg_c, 8), make_tuple(128, 64, &aom_highbd_sad128x64_avg_c, 8), make_tuple(64, 128, &aom_highbd_sad64x128_avg_c, 8), @@ -943,51 +1087,98 @@ const SadMxNAvgParam avg_c_tests[] = { make_tuple(8, 4, &aom_highbd_sad8x4_avg_c, 12), make_tuple(4, 8, &aom_highbd_sad4x8_avg_c, 12), make_tuple(4, 4, &aom_highbd_sad4x4_avg_c, 12), +#endif // CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_sad64x16_avg_c, -1), + make_tuple(16, 64, &aom_sad16x64_avg_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16_avg_c, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_c, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_c, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_c, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_c, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_c, 12), +#endif + make_tuple(32, 8, &aom_sad32x8_avg_c, -1), + make_tuple(8, 32, &aom_sad8x32_avg_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8_avg_c, 8), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_c, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_c, 10), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_c, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_c, 12), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_c, 12), +#endif + make_tuple(16, 4, &aom_sad16x4_avg_c, -1), + make_tuple(4, 16, &aom_sad4x16_avg_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4_avg_c, 8), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_c, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_c, 10), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_c, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_c, 12), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_c, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(C, SADavgTest, ::testing::ValuesIn(avg_c_tests)); +INSTANTIATE_TEST_SUITE_P(C, SADavgTest, ::testing::ValuesIn(avg_c_tests)); // TODO(chengchen): add highbd tests -const JntCompAvgParam jnt_comp_avg_c_tests[] = { - make_tuple(128, 128, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(128, 64, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(64, 128, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(64, 64, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(64, 32, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(32, 64, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(32, 32, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(32, 16, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(16, 32, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(16, 16, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(16, 8, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(8, 16, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(8, 8, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(8, 4, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(4, 8, &aom_jnt_comp_avg_pred_c, -1), - make_tuple(4, 4, &aom_jnt_comp_avg_pred_c, -1), +const DistWtdCompAvgParam dist_wtd_comp_avg_c_tests[] = { + make_tuple(128, 128, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(128, 64, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(64, 128, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(64, 64, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(64, 32, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(32, 64, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(32, 32, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(32, 16, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(16, 32, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(16, 16, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(16, 8, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(8, 16, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(8, 8, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(8, 4, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(4, 8, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(4, 4, &aom_dist_wtd_comp_avg_pred_c, -1), + + make_tuple(64, 16, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(16, 64, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(32, 8, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(8, 32, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(16, 4, &aom_dist_wtd_comp_avg_pred_c, -1), + make_tuple(4, 16, &aom_dist_wtd_comp_avg_pred_c, -1), }; -INSTANTIATE_TEST_CASE_P(C, JntCompAvgTest, - ::testing::ValuesIn(jnt_comp_avg_c_tests)); - -const JntSadMxNAvgParam jnt_avg_c_tests[] = { - make_tuple(128, 128, &aom_jnt_sad128x128_avg_c, -1), - make_tuple(128, 64, &aom_jnt_sad128x64_avg_c, -1), - make_tuple(64, 128, &aom_jnt_sad64x128_avg_c, -1), - make_tuple(64, 64, &aom_jnt_sad64x64_avg_c, -1), - make_tuple(64, 32, &aom_jnt_sad64x32_avg_c, -1), - make_tuple(32, 64, &aom_jnt_sad32x64_avg_c, -1), - make_tuple(32, 32, &aom_jnt_sad32x32_avg_c, -1), - make_tuple(32, 16, &aom_jnt_sad32x16_avg_c, -1), - make_tuple(16, 32, &aom_jnt_sad16x32_avg_c, -1), - make_tuple(16, 16, &aom_jnt_sad16x16_avg_c, -1), - make_tuple(16, 8, &aom_jnt_sad16x8_avg_c, -1), - make_tuple(8, 16, &aom_jnt_sad8x16_avg_c, -1), - make_tuple(8, 8, &aom_jnt_sad8x8_avg_c, -1), - make_tuple(8, 4, &aom_jnt_sad8x4_avg_c, -1), - make_tuple(4, 8, &aom_jnt_sad4x8_avg_c, -1), - make_tuple(4, 4, &aom_jnt_sad4x4_avg_c, -1), +INSTANTIATE_TEST_SUITE_P(C, DistWtdCompAvgTest, + ::testing::ValuesIn(dist_wtd_comp_avg_c_tests)); + +const DistWtdSadMxNAvgParam dist_wtd_avg_c_tests[] = { + make_tuple(128, 128, &aom_dist_wtd_sad128x128_avg_c, -1), + make_tuple(128, 64, &aom_dist_wtd_sad128x64_avg_c, -1), + make_tuple(64, 128, &aom_dist_wtd_sad64x128_avg_c, -1), + make_tuple(64, 64, &aom_dist_wtd_sad64x64_avg_c, -1), + make_tuple(64, 32, &aom_dist_wtd_sad64x32_avg_c, -1), + make_tuple(32, 64, &aom_dist_wtd_sad32x64_avg_c, -1), + make_tuple(32, 32, &aom_dist_wtd_sad32x32_avg_c, -1), + make_tuple(32, 16, &aom_dist_wtd_sad32x16_avg_c, -1), + make_tuple(16, 32, &aom_dist_wtd_sad16x32_avg_c, -1), + make_tuple(16, 16, &aom_dist_wtd_sad16x16_avg_c, -1), + make_tuple(16, 8, &aom_dist_wtd_sad16x8_avg_c, -1), + make_tuple(8, 16, &aom_dist_wtd_sad8x16_avg_c, -1), + make_tuple(8, 8, &aom_dist_wtd_sad8x8_avg_c, -1), + make_tuple(8, 4, &aom_dist_wtd_sad8x4_avg_c, -1), + make_tuple(4, 8, &aom_dist_wtd_sad4x8_avg_c, -1), + make_tuple(4, 4, &aom_dist_wtd_sad4x4_avg_c, -1), + + make_tuple(64, 16, &aom_dist_wtd_sad64x16_avg_c, -1), + make_tuple(16, 64, &aom_dist_wtd_sad16x64_avg_c, -1), + make_tuple(32, 8, &aom_dist_wtd_sad32x8_avg_c, -1), + make_tuple(8, 32, &aom_dist_wtd_sad8x32_avg_c, -1), + make_tuple(16, 4, &aom_dist_wtd_sad16x4_avg_c, -1), + make_tuple(4, 16, &aom_dist_wtd_sad4x16_avg_c, -1), }; -INSTANTIATE_TEST_CASE_P(C, JntSADavgTest, ::testing::ValuesIn(jnt_avg_c_tests)); + +INSTANTIATE_TEST_SUITE_P(C, DistWtdSADavgTest, + ::testing::ValuesIn(dist_wtd_avg_c_tests)); const SadMxNx4Param x4d_c_tests[] = { make_tuple(128, 128, &aom_sad128x128x4d_c, -1), @@ -1006,6 +1197,7 @@ const SadMxNx4Param x4d_c_tests[] = { make_tuple(8, 4, &aom_sad8x4x4d_c, -1), make_tuple(4, 8, &aom_sad4x8x4d_c, -1), make_tuple(4, 4, &aom_sad4x4x4d_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128x4d_c, 8), make_tuple(128, 64, &aom_highbd_sad128x64x4d_c, 8), make_tuple(64, 128, &aom_highbd_sad64x128x4d_c, 8), @@ -1054,8 +1246,65 @@ const SadMxNx4Param x4d_c_tests[] = { make_tuple(8, 4, &aom_highbd_sad8x4x4d_c, 12), make_tuple(4, 8, &aom_highbd_sad4x8x4d_c, 12), make_tuple(4, 4, &aom_highbd_sad4x4x4d_c, 12), +#endif + make_tuple(64, 16, &aom_sad64x16x4d_c, -1), + make_tuple(16, 64, &aom_sad16x64x4d_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16x4d_c, 8), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_c, 8), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_c, 10), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_c, 10), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_c, 12), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_c, 12), +#endif + make_tuple(32, 8, &aom_sad32x8x4d_c, -1), + make_tuple(8, 32, &aom_sad8x32x4d_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8x4d_c, 8), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_c, 8), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_c, 10), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_c, 10), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_c, 12), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_c, 12), +#endif + make_tuple(16, 4, &aom_sad16x4x4d_c, -1), + make_tuple(4, 16, &aom_sad4x16x4d_c, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4x4d_c, 8), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_c, 8), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_c, 10), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_c, 10), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_c, 12), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_c, 12), +#endif +}; +INSTANTIATE_TEST_SUITE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests)); + +const SadMxNx4AvgParam x4d_avg_c_tests[] = { + make_tuple(128, 128, &aom_sad128x128x4d_avg_c, -1), + make_tuple(128, 64, &aom_sad128x64x4d_avg_c, -1), + make_tuple(64, 128, &aom_sad64x128x4d_avg_c, -1), + make_tuple(64, 64, &aom_sad64x64x4d_avg_c, -1), + make_tuple(64, 32, &aom_sad64x32x4d_avg_c, -1), + make_tuple(32, 64, &aom_sad32x64x4d_avg_c, -1), + make_tuple(32, 32, &aom_sad32x32x4d_avg_c, -1), + make_tuple(32, 16, &aom_sad32x16x4d_avg_c, -1), + make_tuple(16, 32, &aom_sad16x32x4d_avg_c, -1), + make_tuple(16, 16, &aom_sad16x16x4d_avg_c, -1), + make_tuple(16, 8, &aom_sad16x8x4d_avg_c, -1), + make_tuple(8, 16, &aom_sad8x16x4d_avg_c, -1), + make_tuple(8, 8, &aom_sad8x8x4d_avg_c, -1), + make_tuple(8, 4, &aom_sad8x4x4d_avg_c, -1), + make_tuple(4, 8, &aom_sad4x8x4d_avg_c, -1), + make_tuple(4, 4, &aom_sad4x4x4d_avg_c, -1), + make_tuple(64, 16, &aom_sad64x16x4d_avg_c, -1), + make_tuple(16, 64, &aom_sad16x64x4d_avg_c, -1), + make_tuple(32, 8, &aom_sad32x8x4d_avg_c, -1), + make_tuple(8, 32, &aom_sad8x32x4d_avg_c, -1), + make_tuple(16, 4, &aom_sad16x4x4d_avg_c, -1), + make_tuple(4, 16, &aom_sad4x16x4d_avg_c, -1), }; -INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests)); +INSTANTIATE_TEST_SUITE_P(C, SADx4AvgTest, ::testing::ValuesIn(x4d_avg_c_tests)); //------------------------------------------------------------------------------ // ARM functions @@ -1069,14 +1318,14 @@ const SadMxNParam neon_tests[] = { make_tuple(8, 8, &aom_sad8x8_neon, -1), make_tuple(4, 4, &aom_sad4x4_neon, -1), }; -INSTANTIATE_TEST_CASE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests)); +INSTANTIATE_TEST_SUITE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests)); const SadMxNx4Param x4d_neon_tests[] = { make_tuple(64, 64, &aom_sad64x64x4d_neon, -1), make_tuple(32, 32, &aom_sad32x32x4d_neon, -1), make_tuple(16, 16, &aom_sad16x16x4d_neon, -1), }; -INSTANTIATE_TEST_CASE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests)); +INSTANTIATE_TEST_SUITE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests)); #endif // HAVE_NEON //------------------------------------------------------------------------------ @@ -1099,6 +1348,7 @@ const SadMxNParam sse2_tests[] = { make_tuple(8, 4, &aom_sad8x4_sse2, -1), make_tuple(4, 8, &aom_sad4x8_sse2, -1), make_tuple(4, 4, &aom_sad4x4_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(64, 64, &aom_highbd_sad64x64_sse2, 8), make_tuple(64, 32, &aom_highbd_sad64x32_sse2, 8), make_tuple(32, 64, &aom_highbd_sad32x64_sse2, 8), @@ -1110,6 +1360,8 @@ const SadMxNParam sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_sse2, 8), make_tuple(8, 8, &aom_highbd_sad8x8_sse2, 8), make_tuple(8, 4, &aom_highbd_sad8x4_sse2, 8), + make_tuple(4, 8, &aom_highbd_sad4x8_sse2, 8), + make_tuple(4, 4, &aom_highbd_sad4x4_sse2, 8), make_tuple(64, 64, &aom_highbd_sad64x64_sse2, 10), make_tuple(64, 32, &aom_highbd_sad64x32_sse2, 10), make_tuple(32, 64, &aom_highbd_sad32x64_sse2, 10), @@ -1121,6 +1373,8 @@ const SadMxNParam sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_sse2, 10), make_tuple(8, 8, &aom_highbd_sad8x8_sse2, 10), make_tuple(8, 4, &aom_highbd_sad8x4_sse2, 10), + make_tuple(4, 8, &aom_highbd_sad4x8_sse2, 10), + make_tuple(4, 4, &aom_highbd_sad4x4_sse2, 10), make_tuple(64, 64, &aom_highbd_sad64x64_sse2, 12), make_tuple(64, 32, &aom_highbd_sad64x32_sse2, 12), make_tuple(32, 64, &aom_highbd_sad32x64_sse2, 12), @@ -1132,8 +1386,41 @@ const SadMxNParam sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_sse2, 12), make_tuple(8, 8, &aom_highbd_sad8x8_sse2, 12), make_tuple(8, 4, &aom_highbd_sad8x4_sse2, 12), + make_tuple(4, 8, &aom_highbd_sad4x8_sse2, 12), + make_tuple(4, 4, &aom_highbd_sad4x4_sse2, 12), +#endif + make_tuple(64, 16, &aom_sad64x16_sse2, -1), + make_tuple(16, 64, &aom_sad16x64_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16_sse2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_sse2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_sse2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_sse2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_sse2, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_sse2, 12), +#endif + make_tuple(32, 8, &aom_sad32x8_sse2, -1), + make_tuple(8, 32, &aom_sad8x32_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8_sse2, 8), + make_tuple(8, 32, &aom_highbd_sad8x32_sse2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_sse2, 10), + make_tuple(8, 32, &aom_highbd_sad8x32_sse2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_sse2, 12), + make_tuple(8, 32, &aom_highbd_sad8x32_sse2, 12), +#endif + make_tuple(16, 4, &aom_sad16x4_sse2, -1), + make_tuple(4, 16, &aom_sad4x16_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4_sse2, 8), + make_tuple(4, 16, &aom_highbd_sad4x16_sse2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_sse2, 10), + make_tuple(4, 16, &aom_highbd_sad4x16_sse2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_sse2, 12), + make_tuple(4, 16, &aom_highbd_sad4x16_sse2, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests)); +INSTANTIATE_TEST_SUITE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests)); const SadMxNAvgParam avg_sse2_tests[] = { make_tuple(128, 128, &aom_sad128x128_avg_sse2, -1), @@ -1152,6 +1439,7 @@ const SadMxNAvgParam avg_sse2_tests[] = { make_tuple(8, 4, &aom_sad8x4_avg_sse2, -1), make_tuple(4, 8, &aom_sad4x8_avg_sse2, -1), make_tuple(4, 4, &aom_sad4x4_avg_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(64, 64, &aom_highbd_sad64x64_avg_sse2, 8), make_tuple(64, 32, &aom_highbd_sad64x32_avg_sse2, 8), make_tuple(32, 64, &aom_highbd_sad32x64_avg_sse2, 8), @@ -1163,6 +1451,8 @@ const SadMxNAvgParam avg_sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_avg_sse2, 8), make_tuple(8, 8, &aom_highbd_sad8x8_avg_sse2, 8), make_tuple(8, 4, &aom_highbd_sad8x4_avg_sse2, 8), + make_tuple(4, 8, &aom_highbd_sad4x8_avg_sse2, 8), + make_tuple(4, 4, &aom_highbd_sad4x4_avg_sse2, 8), make_tuple(64, 64, &aom_highbd_sad64x64_avg_sse2, 10), make_tuple(64, 32, &aom_highbd_sad64x32_avg_sse2, 10), make_tuple(32, 64, &aom_highbd_sad32x64_avg_sse2, 10), @@ -1174,6 +1464,8 @@ const SadMxNAvgParam avg_sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_avg_sse2, 10), make_tuple(8, 8, &aom_highbd_sad8x8_avg_sse2, 10), make_tuple(8, 4, &aom_highbd_sad8x4_avg_sse2, 10), + make_tuple(4, 8, &aom_highbd_sad4x8_avg_sse2, 10), + make_tuple(4, 4, &aom_highbd_sad4x4_avg_sse2, 10), make_tuple(64, 64, &aom_highbd_sad64x64_avg_sse2, 12), make_tuple(64, 32, &aom_highbd_sad64x32_avg_sse2, 12), make_tuple(32, 64, &aom_highbd_sad32x64_avg_sse2, 12), @@ -1185,8 +1477,41 @@ const SadMxNAvgParam avg_sse2_tests[] = { make_tuple(8, 16, &aom_highbd_sad8x16_avg_sse2, 12), make_tuple(8, 8, &aom_highbd_sad8x8_avg_sse2, 12), make_tuple(8, 4, &aom_highbd_sad8x4_avg_sse2, 12), + make_tuple(4, 8, &aom_highbd_sad4x8_avg_sse2, 12), + make_tuple(4, 4, &aom_highbd_sad4x4_avg_sse2, 12), +#endif + make_tuple(64, 16, &aom_sad64x16_avg_sse2, -1), + make_tuple(16, 64, &aom_sad16x64_avg_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16_avg_sse2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_sse2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_sse2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_sse2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_sse2, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_sse2, 12), +#endif + make_tuple(32, 8, &aom_sad32x8_avg_sse2, -1), + make_tuple(8, 32, &aom_sad8x32_avg_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8_avg_sse2, 8), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_sse2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_sse2, 10), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_sse2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_sse2, 12), + make_tuple(8, 32, &aom_highbd_sad8x32_avg_sse2, 12), +#endif + make_tuple(16, 4, &aom_sad16x4_avg_sse2, -1), + make_tuple(4, 16, &aom_sad4x16_avg_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4_avg_sse2, 8), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_sse2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_sse2, 10), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_sse2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_sse2, 12), + make_tuple(4, 16, &aom_highbd_sad4x16_avg_sse2, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(SSE2, SADavgTest, ::testing::ValuesIn(avg_sse2_tests)); +INSTANTIATE_TEST_SUITE_P(SSE2, SADavgTest, ::testing::ValuesIn(avg_sse2_tests)); const SadMxNx4Param x4d_sse2_tests[] = { make_tuple(128, 128, &aom_sad128x128x4d_sse2, -1), @@ -1205,6 +1530,7 @@ const SadMxNx4Param x4d_sse2_tests[] = { make_tuple(8, 4, &aom_sad8x4x4d_sse2, -1), make_tuple(4, 8, &aom_sad4x8x4d_sse2, -1), make_tuple(4, 4, &aom_sad4x4x4d_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(64, 64, &aom_highbd_sad64x64x4d_sse2, 8), make_tuple(64, 32, &aom_highbd_sad64x32x4d_sse2, 8), make_tuple(32, 64, &aom_highbd_sad32x64x4d_sse2, 8), @@ -1244,14 +1570,72 @@ const SadMxNx4Param x4d_sse2_tests[] = { make_tuple(8, 4, &aom_highbd_sad8x4x4d_sse2, 12), make_tuple(4, 8, &aom_highbd_sad4x8x4d_sse2, 12), make_tuple(4, 4, &aom_highbd_sad4x4x4d_sse2, 12), +#endif + make_tuple(64, 16, &aom_sad64x16x4d_sse2, -1), + make_tuple(16, 64, &aom_sad16x64x4d_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(64, 16, &aom_highbd_sad64x16x4d_sse2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_sse2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_sse2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_sse2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_sse2, 12), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_sse2, 12), +#endif + make_tuple(32, 8, &aom_sad32x8x4d_sse2, -1), + make_tuple(8, 32, &aom_sad8x32x4d_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(32, 8, &aom_highbd_sad32x8x4d_sse2, 8), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_sse2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_sse2, 10), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_sse2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_sse2, 12), + make_tuple(8, 32, &aom_highbd_sad8x32x4d_sse2, 12), +#endif + make_tuple(16, 4, &aom_sad16x4x4d_sse2, -1), + make_tuple(4, 16, &aom_sad4x16x4d_sse2, -1), +#if CONFIG_AV1_HIGHBITDEPTH + make_tuple(16, 4, &aom_highbd_sad16x4x4d_sse2, 8), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_sse2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_sse2, 10), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_sse2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_sse2, 12), + make_tuple(4, 16, &aom_highbd_sad4x16x4d_sse2, 12), +#endif +}; +INSTANTIATE_TEST_SUITE_P(SSE2, SADx4Test, ::testing::ValuesIn(x4d_sse2_tests)); + +const SadMxNx4AvgParam x4d_avg_sse2_tests[] = { + make_tuple(128, 128, &aom_sad128x128x4d_avg_sse2, -1), + make_tuple(128, 64, &aom_sad128x64x4d_avg_sse2, -1), + make_tuple(64, 128, &aom_sad64x128x4d_avg_sse2, -1), + make_tuple(64, 64, &aom_sad64x64x4d_avg_sse2, -1), + make_tuple(64, 32, &aom_sad64x32x4d_avg_sse2, -1), + make_tuple(32, 64, &aom_sad32x64x4d_avg_sse2, -1), + make_tuple(32, 32, &aom_sad32x32x4d_avg_sse2, -1), + make_tuple(32, 16, &aom_sad32x16x4d_avg_sse2, -1), + make_tuple(16, 32, &aom_sad16x32x4d_avg_sse2, -1), + make_tuple(16, 16, &aom_sad16x16x4d_avg_sse2, -1), + make_tuple(16, 8, &aom_sad16x8x4d_avg_sse2, -1), + make_tuple(8, 16, &aom_sad8x16x4d_avg_sse2, -1), + make_tuple(8, 8, &aom_sad8x8x4d_avg_sse2, -1), + make_tuple(8, 4, &aom_sad8x4x4d_avg_sse2, -1), + make_tuple(4, 8, &aom_sad4x8x4d_avg_sse2, -1), + make_tuple(4, 4, &aom_sad4x4x4d_avg_sse2, -1), + make_tuple(64, 16, &aom_sad64x16x4d_avg_sse2, -1), + make_tuple(16, 64, &aom_sad16x64x4d_avg_sse2, -1), + make_tuple(32, 8, &aom_sad32x8x4d_avg_sse2, -1), + make_tuple(8, 32, &aom_sad8x32x4d_avg_sse2, -1), + make_tuple(16, 4, &aom_sad16x4x4d_avg_sse2, -1), + make_tuple(4, 16, &aom_sad4x16x4d_avg_sse2, -1), }; -INSTANTIATE_TEST_CASE_P(SSE2, SADx4Test, ::testing::ValuesIn(x4d_sse2_tests)); +INSTANTIATE_TEST_SUITE_P(SSE2, SADx4AvgTest, + ::testing::ValuesIn(x4d_avg_sse2_tests)); #endif // HAVE_SSE2 #if HAVE_SSSE3 // Note: These are named sse2, but part of ssse3 file and only built and linked // when ssse3 is enabled. -const JntSadMxhParam jnt_sad_sse2_tests[] = { +const DistWtdSadMxhParam dist_wtd_sad_sse2_tests[] = { make_tuple(4, 4, &aom_sad4xh_sse2, -1), make_tuple(4, 8, &aom_sad4xh_sse2, -1), make_tuple(8, 4, &aom_sad8xh_sse2, -1), @@ -1274,9 +1658,16 @@ const JntSadMxhParam jnt_sad_sse2_tests[] = { make_tuple(32, 8, &aom_sad32xh_sse2, -1), make_tuple(16, 64, &aom_sad16xh_sse2, -1), make_tuple(64, 16, &aom_sad64xh_sse2, -1), + + make_tuple(16, 64, &aom_sad16xh_sse2, -1), + make_tuple(64, 16, &aom_sad64xh_sse2, -1), + make_tuple(8, 32, &aom_sad8xh_sse2, -1), + make_tuple(32, 8, &aom_sad32xh_sse2, -1), + make_tuple(4, 16, &aom_sad4xh_sse2, -1), + make_tuple(16, 4, &aom_sad16xh_sse2, -1), }; -INSTANTIATE_TEST_CASE_P(SSE2, JntSADTest, - ::testing::ValuesIn(jnt_sad_sse2_tests)); +INSTANTIATE_TEST_SUITE_P(SSE2, DistWtdSADTest, + ::testing::ValuesIn(dist_wtd_sad_sse2_tests)); #endif // HAVE_SSSE3 @@ -1285,49 +1676,63 @@ INSTANTIATE_TEST_CASE_P(SSE2, JntSADTest, #endif // HAVE_SSE3 #if HAVE_SSSE3 -const JntCompAvgParam jnt_comp_avg_ssse3_tests[] = { - make_tuple(128, 128, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(128, 64, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(64, 128, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(64, 64, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(64, 32, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(32, 64, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(32, 32, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(32, 16, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(16, 32, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(16, 16, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(16, 8, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(8, 16, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(8, 8, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(8, 4, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(4, 8, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(4, 4, &aom_jnt_comp_avg_pred_ssse3, -1), - make_tuple(16, 16, &aom_jnt_comp_avg_pred_ssse3, -1), +const DistWtdCompAvgParam dist_wtd_comp_avg_ssse3_tests[] = { + make_tuple(128, 128, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(128, 64, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(64, 128, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(64, 64, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(64, 32, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(32, 64, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(32, 32, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(32, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 32, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 8, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(8, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(8, 8, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(8, 4, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(4, 8, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(4, 4, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + + make_tuple(64, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 64, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(32, 8, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(8, 32, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(16, 4, &aom_dist_wtd_comp_avg_pred_ssse3, -1), + make_tuple(4, 16, &aom_dist_wtd_comp_avg_pred_ssse3, -1), }; -INSTANTIATE_TEST_CASE_P(SSSE3, JntCompAvgTest, - ::testing::ValuesIn(jnt_comp_avg_ssse3_tests)); - -const JntSadMxNAvgParam jnt_avg_ssse3_tests[] = { - make_tuple(128, 128, &aom_jnt_sad128x128_avg_ssse3, -1), - make_tuple(128, 64, &aom_jnt_sad128x64_avg_ssse3, -1), - make_tuple(64, 128, &aom_jnt_sad64x128_avg_ssse3, -1), - make_tuple(64, 64, &aom_jnt_sad64x64_avg_ssse3, -1), - make_tuple(64, 32, &aom_jnt_sad64x32_avg_ssse3, -1), - make_tuple(32, 64, &aom_jnt_sad32x64_avg_ssse3, -1), - make_tuple(32, 32, &aom_jnt_sad32x32_avg_ssse3, -1), - make_tuple(32, 16, &aom_jnt_sad32x16_avg_ssse3, -1), - make_tuple(16, 32, &aom_jnt_sad16x32_avg_ssse3, -1), - make_tuple(16, 16, &aom_jnt_sad16x16_avg_ssse3, -1), - make_tuple(16, 8, &aom_jnt_sad16x8_avg_ssse3, -1), - make_tuple(8, 16, &aom_jnt_sad8x16_avg_ssse3, -1), - make_tuple(8, 8, &aom_jnt_sad8x8_avg_ssse3, -1), - make_tuple(8, 4, &aom_jnt_sad8x4_avg_ssse3, -1), - make_tuple(4, 8, &aom_jnt_sad4x8_avg_ssse3, -1), - make_tuple(4, 4, &aom_jnt_sad4x4_avg_ssse3, -1), +INSTANTIATE_TEST_SUITE_P(SSSE3, DistWtdCompAvgTest, + ::testing::ValuesIn(dist_wtd_comp_avg_ssse3_tests)); + +const DistWtdSadMxNAvgParam dist_wtd_avg_ssse3_tests[] = { + make_tuple(128, 128, &aom_dist_wtd_sad128x128_avg_ssse3, -1), + make_tuple(128, 64, &aom_dist_wtd_sad128x64_avg_ssse3, -1), + make_tuple(64, 128, &aom_dist_wtd_sad64x128_avg_ssse3, -1), + make_tuple(64, 64, &aom_dist_wtd_sad64x64_avg_ssse3, -1), + make_tuple(64, 32, &aom_dist_wtd_sad64x32_avg_ssse3, -1), + make_tuple(32, 64, &aom_dist_wtd_sad32x64_avg_ssse3, -1), + make_tuple(32, 32, &aom_dist_wtd_sad32x32_avg_ssse3, -1), + make_tuple(32, 16, &aom_dist_wtd_sad32x16_avg_ssse3, -1), + make_tuple(16, 32, &aom_dist_wtd_sad16x32_avg_ssse3, -1), + make_tuple(16, 16, &aom_dist_wtd_sad16x16_avg_ssse3, -1), + make_tuple(16, 8, &aom_dist_wtd_sad16x8_avg_ssse3, -1), + make_tuple(8, 16, &aom_dist_wtd_sad8x16_avg_ssse3, -1), + make_tuple(8, 8, &aom_dist_wtd_sad8x8_avg_ssse3, -1), + make_tuple(8, 4, &aom_dist_wtd_sad8x4_avg_ssse3, -1), + make_tuple(4, 8, &aom_dist_wtd_sad4x8_avg_ssse3, -1), + make_tuple(4, 4, &aom_dist_wtd_sad4x4_avg_ssse3, -1), + + make_tuple(64, 16, &aom_dist_wtd_sad64x16_avg_ssse3, -1), + make_tuple(16, 64, &aom_dist_wtd_sad16x64_avg_ssse3, -1), + make_tuple(32, 8, &aom_dist_wtd_sad32x8_avg_ssse3, -1), + make_tuple(8, 32, &aom_dist_wtd_sad8x32_avg_ssse3, -1), + make_tuple(16, 4, &aom_dist_wtd_sad16x4_avg_ssse3, -1), + make_tuple(4, 16, &aom_dist_wtd_sad4x16_avg_ssse3, -1), }; -INSTANTIATE_TEST_CASE_P(SSSE3, JntSADavgTest, - ::testing::ValuesIn(jnt_avg_ssse3_tests)); +INSTANTIATE_TEST_SUITE_P(SSSE3, DistWtdSADavgTest, + ::testing::ValuesIn(dist_wtd_avg_ssse3_tests)); #endif // HAVE_SSSE3 #if HAVE_SSE4_1 @@ -1344,6 +1749,7 @@ const SadMxNParam avx2_tests[] = { make_tuple(32, 64, &aom_sad32x64_avx2, -1), make_tuple(32, 32, &aom_sad32x32_avx2, -1), make_tuple(32, 16, &aom_sad32x16_avx2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128_avx2, 8), make_tuple(128, 128, &aom_highbd_sad128x128_avx2, 10), make_tuple(128, 128, &aom_highbd_sad128x128_avx2, 12), @@ -1377,8 +1783,22 @@ const SadMxNParam avx2_tests[] = { make_tuple(16, 8, &aom_highbd_sad16x8_avx2, 8), make_tuple(16, 8, &aom_highbd_sad16x8_avx2, 10), make_tuple(16, 8, &aom_highbd_sad16x8_avx2, 12), + + make_tuple(64, 16, &aom_highbd_sad64x16_avx2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_avx2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_avx2, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_avx2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_avx2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_avx2, 12), + make_tuple(32, 8, &aom_highbd_sad32x8_avx2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_avx2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_avx2, 12), + make_tuple(16, 4, &aom_highbd_sad16x4_avx2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_avx2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_avx2, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(AVX2, SADTest, ::testing::ValuesIn(avx2_tests)); +INSTANTIATE_TEST_SUITE_P(AVX2, SADTest, ::testing::ValuesIn(avx2_tests)); const SadMxNAvgParam avg_avx2_tests[] = { make_tuple(64, 128, &aom_sad64x128_avg_avx2, -1), @@ -1389,6 +1809,7 @@ const SadMxNAvgParam avg_avx2_tests[] = { make_tuple(32, 64, &aom_sad32x64_avg_avx2, -1), make_tuple(32, 32, &aom_sad32x32_avg_avx2, -1), make_tuple(32, 16, &aom_sad32x16_avg_avx2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128_avg_avx2, 8), make_tuple(128, 128, &aom_highbd_sad128x128_avg_avx2, 10), make_tuple(128, 128, &aom_highbd_sad128x128_avg_avx2, 12), @@ -1422,17 +1843,35 @@ const SadMxNAvgParam avg_avx2_tests[] = { make_tuple(16, 8, &aom_highbd_sad16x8_avg_avx2, 8), make_tuple(16, 8, &aom_highbd_sad16x8_avg_avx2, 10), make_tuple(16, 8, &aom_highbd_sad16x8_avg_avx2, 12), + + make_tuple(64, 16, &aom_highbd_sad64x16_avg_avx2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_avx2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16_avg_avx2, 12), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_avx2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_avx2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64_avg_avx2, 12), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_avx2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_avx2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8_avg_avx2, 12), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_avx2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_avx2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4_avg_avx2, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(AVX2, SADavgTest, ::testing::ValuesIn(avg_avx2_tests)); +INSTANTIATE_TEST_SUITE_P(AVX2, SADavgTest, ::testing::ValuesIn(avg_avx2_tests)); const SadMxNx4Param x4d_avx2_tests[] = { + make_tuple(32, 64, &aom_sad32x64x4d_avx2, -1), + make_tuple(32, 32, &aom_sad32x32x4d_avx2, -1), + make_tuple(32, 16, &aom_sad32x16x4d_avx2, -1), + make_tuple(32, 8, &aom_sad32x8x4d_avx2, -1), make_tuple(64, 128, &aom_sad64x128x4d_avx2, -1), - make_tuple(128, 64, &aom_sad128x64x4d_avx2, -1), - make_tuple(128, 128, &aom_sad128x128x4d_avx2, -1), make_tuple(64, 64, &aom_sad64x64x4d_avx2, -1), - make_tuple(32, 64, &aom_sad32x64x4d_avx2, -1), make_tuple(64, 32, &aom_sad64x32x4d_avx2, -1), - make_tuple(32, 32, &aom_sad32x32x4d_avx2, -1), + make_tuple(64, 16, &aom_sad64x16x4d_avx2, -1), + make_tuple(128, 128, &aom_sad128x128x4d_avx2, -1), + make_tuple(128, 64, &aom_sad128x64x4d_avx2, -1), +#if CONFIG_AV1_HIGHBITDEPTH make_tuple(128, 128, &aom_highbd_sad128x128x4d_avx2, 8), make_tuple(128, 128, &aom_highbd_sad128x128x4d_avx2, 10), make_tuple(128, 128, &aom_highbd_sad128x128x4d_avx2, 12), @@ -1466,8 +1905,22 @@ const SadMxNx4Param x4d_avx2_tests[] = { make_tuple(16, 8, &aom_highbd_sad16x8x4d_avx2, 8), make_tuple(16, 8, &aom_highbd_sad16x8x4d_avx2, 10), make_tuple(16, 8, &aom_highbd_sad16x8x4d_avx2, 12), + + make_tuple(16, 64, &aom_highbd_sad16x64x4d_avx2, 8), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_avx2, 10), + make_tuple(16, 64, &aom_highbd_sad16x64x4d_avx2, 12), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_avx2, 8), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_avx2, 10), + make_tuple(64, 16, &aom_highbd_sad64x16x4d_avx2, 12), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_avx2, 8), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_avx2, 10), + make_tuple(32, 8, &aom_highbd_sad32x8x4d_avx2, 12), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_avx2, 8), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_avx2, 10), + make_tuple(16, 4, &aom_highbd_sad16x4x4d_avx2, 12), +#endif }; -INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests)); +INSTANTIATE_TEST_SUITE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests)); #endif // HAVE_AVX2 //------------------------------------------------------------------------------ @@ -1488,7 +1941,7 @@ const SadMxNParam msa_tests[] = { make_tuple(4, 8, &aom_sad4x8_msa, -1), make_tuple(4, 4, &aom_sad4x4_msa, -1), }; -INSTANTIATE_TEST_CASE_P(MSA, SADTest, ::testing::ValuesIn(msa_tests)); +INSTANTIATE_TEST_SUITE_P(MSA, SADTest, ::testing::ValuesIn(msa_tests)); const SadMxNAvgParam avg_msa_tests[] = { make_tuple(64, 64, &aom_sad64x64_avg_msa, -1), @@ -1505,7 +1958,7 @@ const SadMxNAvgParam avg_msa_tests[] = { make_tuple(4, 8, &aom_sad4x8_avg_msa, -1), make_tuple(4, 4, &aom_sad4x4_avg_msa, -1), }; -INSTANTIATE_TEST_CASE_P(MSA, SADavgTest, ::testing::ValuesIn(avg_msa_tests)); +INSTANTIATE_TEST_SUITE_P(MSA, SADavgTest, ::testing::ValuesIn(avg_msa_tests)); const SadMxNx4Param x4d_msa_tests[] = { make_tuple(64, 64, &aom_sad64x64x4d_msa, -1), @@ -1522,7 +1975,7 @@ const SadMxNx4Param x4d_msa_tests[] = { make_tuple(4, 8, &aom_sad4x8x4d_msa, -1), make_tuple(4, 4, &aom_sad4x4x4d_msa, -1), }; -INSTANTIATE_TEST_CASE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests)); +INSTANTIATE_TEST_SUITE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests)); #endif // HAVE_MSA } // namespace diff --git a/media/libaom/src/test/sb_multipass_test.cc b/media/libaom/src/test/sb_multipass_test.cc new file mode 100644 index 000000000..0ca76ab85 --- /dev/null +++ b/media/libaom/src/test/sb_multipass_test.cc @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020, 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 <initializer_list> +#include <string> +#include <vector> +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/md5_helper.h" +#include "test/util.h" +#include "test/yuv_video_source.h" + +namespace { +class AV1SBMultipassTest + : public ::libaom_test::CodecTestWith2Params<int, bool>, + public ::libaom_test::EncoderTest { + protected: + AV1SBMultipassTest() + : EncoderTest(GET_PARAM(0)), set_cpu_used_(GET_PARAM(1)), + row_mt_(GET_PARAM(2)) { + init_flags_ = AOM_CODEC_USE_PSNR; + aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); + cfg.w = 1280; + cfg.h = 720; + cfg.allow_lowbitdepth = 1; + decoder_ = codec_->CreateDecoder(cfg, 0); + if (decoder_->IsAV1()) { + decoder_->Control(AV1_SET_DECODE_TILE_ROW, -1); + decoder_->Control(AV1_SET_DECODE_TILE_COL, -1); + } + + size_enc_.clear(); + md5_dec_.clear(); + md5_enc_.clear(); + } + virtual ~AV1SBMultipassTest() { delete decoder_; } + + virtual void SetUp() { + InitializeConfig(); + SetMode(::libaom_test::kTwoPassGood); + + 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; + + cfg_.rc_max_quantizer = 56; + cfg_.rc_min_quantizer = 0; + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + if (video->frame() == 0) { + SetTileSize(encoder); + encoder->Control(AOME_SET_CPUUSED, set_cpu_used_); + encoder->Control(AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST, use_multipass_); + encoder->Control(AV1E_SET_ROW_MT, row_mt_); + + encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); + encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); + encoder->Control(AOME_SET_ARNR_STRENGTH, 5); + } + } + + virtual void SetTileSize(libaom_test::Encoder *encoder) { + encoder->Control(AV1E_SET_TILE_COLUMNS, 1); + encoder->Control(AV1E_SET_TILE_ROWS, 1); + } + + virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { + size_enc_.push_back(pkt->data.frame.sz); + + ::libaom_test::MD5 md5_enc; + md5_enc.Add(reinterpret_cast<uint8_t *>(pkt->data.frame.buf), + pkt->data.frame.sz); + md5_enc_.push_back(md5_enc.Get()); + + const aom_codec_err_t res = decoder_->DecodeFrame( + reinterpret_cast<uint8_t *>(pkt->data.frame.buf), pkt->data.frame.sz); + if (res != AOM_CODEC_OK) { + abort_ = true; + ASSERT_EQ(AOM_CODEC_OK, res); + } + const aom_image_t *img = decoder_->GetDxData().Next(); + + if (img) { + ::libaom_test::MD5 md5_res; + md5_res.Add(img); + md5_dec_.push_back(md5_res.Get()); + } + } + + void DoTest() { + ::libaom_test::YUVVideoSource video( + "niklas_640_480_30.yuv", AOM_IMG_FMT_I420, 640, 480, 30, 1, 0, 6); + cfg_.rc_target_bitrate = 1000; + + // Encode while coding each sb once + use_multipass_ = false; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + std::vector<size_t> single_pass_size_enc; + std::vector<std::string> single_pass_md5_enc; + std::vector<std::string> single_pass_md5_dec; + single_pass_size_enc = size_enc_; + single_pass_md5_enc = md5_enc_; + single_pass_md5_dec = md5_dec_; + size_enc_.clear(); + md5_enc_.clear(); + md5_dec_.clear(); + + // Encode while coding each sb twice + use_multipass_ = true; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + std::vector<size_t> multi_pass_size_enc; + std::vector<std::string> multi_pass_md5_enc; + std::vector<std::string> multi_pass_md5_dec; + multi_pass_size_enc = size_enc_; + multi_pass_md5_enc = md5_enc_; + multi_pass_md5_dec = md5_dec_; + size_enc_.clear(); + md5_enc_.clear(); + md5_dec_.clear(); + + // Check that the vectors are equal. + ASSERT_EQ(single_pass_size_enc, multi_pass_size_enc); + ASSERT_EQ(single_pass_md5_enc, multi_pass_md5_enc); + ASSERT_EQ(single_pass_md5_dec, multi_pass_md5_dec); + } + + bool use_multipass_; + int set_cpu_used_; + bool row_mt_; + ::libaom_test::Decoder *decoder_; + std::vector<size_t> size_enc_; + std::vector<std::string> md5_enc_; + std::vector<std::string> md5_dec_; +}; + +TEST_P(AV1SBMultipassTest, TwoPassMatchTest) { DoTest(); } + +AV1_INSTANTIATE_TEST_CASE(AV1SBMultipassTest, ::testing::Range(0, 6), + ::testing::Bool()); + +} // namespace diff --git a/media/libaom/src/test/selfguided_filter_test.cc b/media/libaom/src/test/selfguided_filter_test.cc index d2d5c6105..d65cce58a 100644 --- a/media/libaom/src/test/selfguided_filter_test.cc +++ b/media/libaom/src/test/selfguided_filter_test.cc @@ -10,6 +10,7 @@ */ #include <ctime> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -26,9 +27,9 @@ namespace { -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; +using std::make_tuple; +using std::tuple; typedef void (*SgrFunc)(const uint8_t *dat8, int width, int height, int stride, int eps, const int *xqd, uint8_t *dst8, int dst_stride, @@ -88,8 +89,9 @@ class AV1SelfguidedFilterTest int h = AOMMIN(pu_height, height - k); uint8_t *input_p = input + k * stride + j; uint8_t *output_p = output + k * out_stride + j; - apply_selfguided_restoration_c(input_p, w, h, stride, eps, xqd, - output_p, out_stride, tmpbuf, 8, 0); + av1_apply_selfguided_restoration_c(input_p, w, h, stride, eps, xqd, + output_p, out_stride, tmpbuf, 8, + 0); } } aom_usec_timer_mark(&ref_timer); @@ -175,8 +177,9 @@ class AV1SelfguidedFilterTest uint8_t *output2_p = output2 + k * out_stride + j; tst_fun_(input_p, w, h, stride, eps, xqd, output_p, out_stride, tmpbuf, 8, 0); - apply_selfguided_restoration_c(input_p, w, h, stride, eps, xqd, - output2_p, out_stride, tmpbuf, 8, 0); + av1_apply_selfguided_restoration_c(input_p, w, h, stride, eps, xqd, + output2_p, out_stride, tmpbuf, 8, + 0); } for (j = 0; j < test_h; ++j) @@ -199,20 +202,24 @@ TEST_P(AV1SelfguidedFilterTest, DISABLED_SpeedTest) { RunSpeedTest(); } TEST_P(AV1SelfguidedFilterTest, CorrectnessTest) { RunCorrectnessTest(); } #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1SelfguidedFilterTest, - ::testing::Values(apply_selfguided_restoration_sse4_1)); +INSTANTIATE_TEST_SUITE_P( + SSE4_1, AV1SelfguidedFilterTest, + ::testing::Values(av1_apply_selfguided_restoration_sse4_1)); #endif #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AV1SelfguidedFilterTest, - ::testing::Values(apply_selfguided_restoration_avx2)); +INSTANTIATE_TEST_SUITE_P( + AVX2, AV1SelfguidedFilterTest, + ::testing::Values(av1_apply_selfguided_restoration_avx2)); #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON, AV1SelfguidedFilterTest, - ::testing::Values(apply_selfguided_restoration_neon)); +INSTANTIATE_TEST_SUITE_P( + NEON, AV1SelfguidedFilterTest, + ::testing::Values(av1_apply_selfguided_restoration_neon)); #endif +#if CONFIG_AV1_HIGHBITDEPTH // Test parameter list: // <tst_fun_, bit_depth> typedef tuple<SgrFunc, int> HighbdFilterTestParam; @@ -269,7 +276,7 @@ class AV1HighbdSelfguidedFilterTest int h = AOMMIN(pu_height, height - k); uint16_t *input_p = input + k * stride + j; uint16_t *output_p = output + k * out_stride + j; - apply_selfguided_restoration_c( + av1_apply_selfguided_restoration_c( CONVERT_TO_BYTEPTR(input_p), w, h, stride, eps, xqd, CONVERT_TO_BYTEPTR(output_p), out_stride, tmpbuf, bit_depth, 1); } @@ -362,7 +369,7 @@ class AV1HighbdSelfguidedFilterTest tst_fun_(CONVERT_TO_BYTEPTR(input_p), w, h, stride, eps, xqd, CONVERT_TO_BYTEPTR(output_p), out_stride, tmpbuf, bit_depth, 1); - apply_selfguided_restoration_c( + av1_apply_selfguided_restoration_c( CONVERT_TO_BYTEPTR(input_p), w, h, stride, eps, xqd, CONVERT_TO_BYTEPTR(output2_p), out_stride, tmpbuf, bit_depth, 1); } @@ -387,24 +394,27 @@ TEST_P(AV1HighbdSelfguidedFilterTest, CorrectnessTest) { RunCorrectnessTest(); } #if HAVE_SSE4_1 const int highbd_params_sse4_1[] = { 8, 10, 12 }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AV1HighbdSelfguidedFilterTest, - ::testing::Combine(::testing::Values(apply_selfguided_restoration_sse4_1), - ::testing::ValuesIn(highbd_params_sse4_1))); + ::testing::Combine( + ::testing::Values(av1_apply_selfguided_restoration_sse4_1), + ::testing::ValuesIn(highbd_params_sse4_1))); #endif #if HAVE_AVX2 const int highbd_params_avx2[] = { 8, 10, 12 }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AV1HighbdSelfguidedFilterTest, - ::testing::Combine(::testing::Values(apply_selfguided_restoration_avx2), + ::testing::Combine(::testing::Values(av1_apply_selfguided_restoration_avx2), ::testing::ValuesIn(highbd_params_avx2))); #endif + #if HAVE_NEON const int highbd_params_neon[] = { 8, 10, 12 }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AV1HighbdSelfguidedFilterTest, - ::testing::Combine(::testing::Values(apply_selfguided_restoration_neon), + ::testing::Combine(::testing::Values(av1_apply_selfguided_restoration_neon), ::testing::ValuesIn(highbd_params_neon))); #endif +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/simd_cmp_impl.h b/media/libaom/src/test/simd_cmp_impl.h index b98af9aad..d3eb33619 100644 --- a/media/libaom/src/test/simd_cmp_impl.h +++ b/media/libaom/src/test/simd_cmp_impl.h @@ -469,11 +469,8 @@ typedef struct { fptr simd; } mapping; -#define MAP(name) \ - { \ - #name, reinterpret_cast < fptr > (c_##name), \ - reinterpret_cast < fptr > (name) \ - } +#define MAP(name) \ + { #name, reinterpret_cast < fptr>(c_##name), reinterpret_cast < fptr>(name) } const mapping m[] = { MAP(v64_sad_u8), MAP(v64_ssd_u8), @@ -1478,8 +1475,8 @@ int CompareSimd3Args(fptr store, fptr load1, fptr load2, fptr load3, fptr simd, (CArg1(*const)(const void *))c_load1; CArg2 (*const my_c_load2)(const void *) = (CArg2(*const)(const void *))c_load2; - CArg2 (*const my_c_load3)(const void *) = - (CArg2(*const)(const void *))c_load3; + CArg3 (*const my_c_load3)(const void *) = + (CArg3(*const)(const void *))c_load3; CRet (*const my_c_simd)(CArg1, CArg2, CArg3) = (CRet(*const)(CArg1, CArg2, CArg3))c_simd; @@ -1734,8 +1731,9 @@ void TestSimd1Arg(uint32_t iterations, uint32_t mask, uint32_t maskwidth, } EXPECT_EQ(0, error) << "Error: mismatch for " << name << "(" - << Print(s, sizeof(s)) << ") -> " << Print(d, sizeof(d)) - << " (simd), " << Print(ref_d, sizeof(ref_d)) << " (ref)"; + << Print(s, sizeof(CArg)) << ") -> " + << Print(d, sizeof(CRet)) << " (simd), " + << Print(ref_d, sizeof(CRet)) << " (ref)"; } template <typename CRet, typename CArg1, typename CArg2> @@ -1990,9 +1988,10 @@ void TestSimd2Args(uint32_t iterations, uint32_t mask, uint32_t maskwidth, } EXPECT_EQ(0, error) << "Error: mismatch for " << name << "(" - << Print(s1, sizeof(s1)) << ", " << Print(s2, sizeof(s2)) - << ") -> " << Print(d, sizeof(d)) << " (simd), " - << Print(ref_d, sizeof(ref_d)) << " (ref)"; + << Print(s1, sizeof(CArg1)) << ", " + << Print(s2, sizeof(CArg2)) << ") -> " + << Print(d, sizeof(CRet)) << " (simd), " + << Print(ref_d, sizeof(CRet)) << " (ref)"; } template <typename CRet, typename CArg1, typename CArg2, typename CArg3> @@ -2066,10 +2065,11 @@ void TestSimd3Args(uint32_t iterations, uint32_t mask, uint32_t maskwidth, } EXPECT_EQ(0, error) << "Error: mismatch for " << name << "(" - << Print(s1, sizeof(s1)) << ", " << Print(s2, sizeof(s2)) - << ", " << Print(s3, sizeof(s3)) << ") -> " - << Print(d, sizeof(d)) << " (simd), " - << Print(ref_d, sizeof(ref_d)) << " (ref)"; + << Print(s1, sizeof(CArg1)) << ", " + << Print(s2, sizeof(CArg2)) << ", " + << Print(s3, sizeof(CArg3)) << ") -> " + << Print(d, sizeof(CRet)) << " (simd), " + << Print(ref_d, sizeof(CRet)) << " (ref)"; } // Instantiations to make the functions callable from another files diff --git a/media/libaom/src/test/simd_impl.h b/media/libaom/src/test/simd_impl.h index fd06f67fd..61fda009f 100644 --- a/media/libaom/src/test/simd_impl.h +++ b/media/libaom/src/test/simd_impl.h @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #define SIMD_CHECK 1 #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/clear_system_state.h" @@ -23,9 +25,9 @@ class TestIntrinsic : public ::testing::TestWithParam<param_signature> { public: virtual ~TestIntrinsic() {} virtual void SetUp() { - mask = ::testing::get<0>(this->GetParam()); - maskwidth = ::testing::get<1>(this->GetParam()); - name = ::testing::get<2>(this->GetParam()); + mask = std::get<0>(this->GetParam()); + maskwidth = std::get<1>(this->GetParam()); + name = std::get<2>(this->GetParam()); } virtual void TearDown() { libaom_test::ClearSystemState(); } @@ -36,8 +38,8 @@ class TestIntrinsic : public ::testing::TestWithParam<param_signature> { }; // Create one typedef for each function signature -#define TYPEDEF_SIMD(name) \ - typedef TestIntrinsic< ::testing::tuple<uint32_t, uint32_t, const char *> > \ +#define TYPEDEF_SIMD(name) \ + typedef TestIntrinsic<std::tuple<uint32_t, uint32_t, const char *> > \ ARCH_POSTFIX(name) TYPEDEF_SIMD(V64_U8); @@ -350,16 +352,16 @@ MY_TEST_P(ARCH_POSTFIX(V64_V256), TestIntrinsics) { TestSimd1Arg<c_v64, c_v256>(kIterations, mask, maskwidth, name); } -// Add a macro layer since INSTANTIATE_TEST_CASE_P will quote the name +// Add a macro layer since INSTANTIATE_TEST_SUITE_P will quote the name // so we need to expand it first with the prefix #define INSTANTIATE(name, type, ...) \ - INSTANTIATE_TEST_CASE_P(name, type, ::testing::Values(__VA_ARGS__)) + INSTANTIATE_TEST_SUITE_P(name, type, ::testing::Values(__VA_ARGS__)) #define SIMD_TUPLE(name, mask, maskwidth) \ - ::testing::make_tuple(mask, maskwidth, static_cast<const char *>(#name)) + std::make_tuple(mask, maskwidth, static_cast<const char *>(#name)) -INSTANTIATE(ARCH, ARCH_POSTFIX(U32_V64V64), - (SIMD_TUPLE(v64_sad_u8, 0U, 0U), SIMD_TUPLE(v64_ssd_u8, 0U, 0U))); +INSTANTIATE(ARCH, ARCH_POSTFIX(U32_V64V64), SIMD_TUPLE(v64_sad_u8, 0U, 0U), + SIMD_TUPLE(v64_ssd_u8, 0U, 0U)); INSTANTIATE( ARCH, ARCH_POSTFIX(V64_V64V64), SIMD_TUPLE(v64_add_8, 0U, 0U), diff --git a/media/libaom/src/test/subtract_test.cc b/media/libaom/src/test/subtract_test.cc index 7dcedf56d..4001e8b7a 100644 --- a/media/libaom/src/test/subtract_test.cc +++ b/media/libaom/src/test/subtract_test.cc @@ -9,6 +9,8 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "config/aom_config.h" @@ -88,30 +90,31 @@ TEST_P(AV1SubtractBlockTest, SimpleSubtract) { } } -INSTANTIATE_TEST_CASE_P(C, AV1SubtractBlockTest, - ::testing::Values(aom_subtract_block_c)); +INSTANTIATE_TEST_SUITE_P(C, AV1SubtractBlockTest, + ::testing::Values(aom_subtract_block_c)); #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, AV1SubtractBlockTest, - ::testing::Values(aom_subtract_block_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1SubtractBlockTest, + ::testing::Values(aom_subtract_block_sse2)); #endif #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON, AV1SubtractBlockTest, - ::testing::Values(aom_subtract_block_neon)); +INSTANTIATE_TEST_SUITE_P(NEON, AV1SubtractBlockTest, + ::testing::Values(aom_subtract_block_neon)); #endif #if HAVE_MSA -INSTANTIATE_TEST_CASE_P(MSA, AV1SubtractBlockTest, - ::testing::Values(aom_subtract_block_msa)); +INSTANTIATE_TEST_SUITE_P(MSA, AV1SubtractBlockTest, + ::testing::Values(aom_subtract_block_msa)); #endif +#if CONFIG_AV1_HIGHBITDEPTH typedef void (*HBDSubtractFunc)(int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride, int bd); -using ::testing::get; -using ::testing::make_tuple; -using ::testing::tuple; +using std::get; +using std::make_tuple; +using std::tuple; // <width, height, bit_dpeth, subtract> typedef tuple<int, int, int, HBDSubtractFunc> Params; @@ -207,7 +210,6 @@ void AV1HBDSubtractBlockTest::RunForSpeed() { TEST_P(AV1HBDSubtractBlockTest, DISABLED_Speed) { RunForSpeed(); } #if HAVE_SSE2 - const Params kAV1HBDSubtractBlock_sse2[] = { make_tuple(4, 4, 12, &aom_highbd_subtract_block_sse2), make_tuple(4, 4, 12, &aom_highbd_subtract_block_c), @@ -243,7 +245,8 @@ const Params kAV1HBDSubtractBlock_sse2[] = { make_tuple(128, 128, 12, &aom_highbd_subtract_block_c) }; -INSTANTIATE_TEST_CASE_P(SSE2, AV1HBDSubtractBlockTest, - ::testing::ValuesIn(kAV1HBDSubtractBlock_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AV1HBDSubtractBlockTest, + ::testing::ValuesIn(kAV1HBDSubtractBlock_sse2)); #endif // HAVE_SSE2 +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace diff --git a/media/libaom/src/test/sum_squares_test.cc b/media/libaom/src/test/sum_squares_test.cc index f10998498..8845466b8 100644 --- a/media/libaom/src/test/sum_squares_test.cc +++ b/media/libaom/src/test/sum_squares_test.cc @@ -12,6 +12,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -27,6 +28,10 @@ using libaom_test::ACMRandom; using libaom_test::FunctionEquivalenceTest; +using ::testing::Combine; +using ::testing::Range; +using ::testing::Values; +using ::testing::ValuesIn; namespace { const int kNumIterations = 10000; @@ -153,7 +158,7 @@ TEST_P(SumSquaresTest, DISABLED_Speed) { RunSpeedTest(); } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, SumSquaresTest, ::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c, &aom_sum_squares_2d_i16_sse2))); @@ -161,7 +166,7 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_SSE2 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, SumSquaresTest, ::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c, &aom_sum_squares_2d_i16_avx2))); @@ -220,9 +225,615 @@ TEST_P(SumSquares1DTest, ExtremeValues) { } #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, SumSquares1DTest, - ::testing::Values(TestFuncs1D( - aom_sum_squares_i16_c, aom_sum_squares_i16_sse2))); +INSTANTIATE_TEST_SUITE_P(SSE2, SumSquares1DTest, + ::testing::Values(TestFuncs1D( + aom_sum_squares_i16_c, aom_sum_squares_i16_sse2))); + +#endif // HAVE_SSE2 + +typedef int64_t (*sse_func)(const uint8_t *a, int a_stride, const uint8_t *b, + int b_stride, int width, int height); +typedef libaom_test::FuncParam<sse_func> TestSSEFuncs; + +typedef std::tuple<TestSSEFuncs, int> SSETestParam; + +class SSETest : public ::testing::TestWithParam<SSETestParam> { + public: + virtual ~SSETest() {} + virtual void SetUp() { + params_ = GET_PARAM(0); + width_ = GET_PARAM(1); + isHbd_ = +#if CONFIG_AV1_HIGHBITDEPTH + params_.ref_func == aom_highbd_sse_c; +#else + 0; +#endif + rnd_.Reset(ACMRandom::DeterministicSeed()); + src_ = reinterpret_cast<uint8_t *>(aom_memalign(32, 256 * 256 * 2)); + ref_ = reinterpret_cast<uint8_t *>(aom_memalign(32, 256 * 256 * 2)); + ASSERT_TRUE(src_ != NULL); + ASSERT_TRUE(ref_ != NULL); + } + + virtual void TearDown() { + libaom_test::ClearSystemState(); + aom_free(src_); + aom_free(ref_); + } + void RunTest(int isRandom, int width, int height, int run_times); + + void GenRandomData(int width, int height, int stride) { + uint16_t *pSrc = (uint16_t *)src_; + uint16_t *pRef = (uint16_t *)ref_; + const int msb = 11; // Up to 12 bit input + const int limit = 1 << (msb + 1); + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + if (!isHbd_) { + src_[ii * stride + jj] = rnd_.Rand8(); + ref_[ii * stride + jj] = rnd_.Rand8(); + } else { + pSrc[ii * stride + jj] = rnd_(limit); + pRef[ii * stride + jj] = rnd_(limit); + } + } + } + } + + void GenExtremeData(int width, int height, int stride, uint8_t *data, + int16_t val) { + uint16_t *pData = (uint16_t *)data; + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + if (!isHbd_) { + data[ii * stride + jj] = (uint8_t)val; + } else { + pData[ii * stride + jj] = val; + } + } + } + } + + protected: + int isHbd_; + int width_; + TestSSEFuncs params_; + uint8_t *src_; + uint8_t *ref_; + ACMRandom rnd_; +}; + +void SSETest::RunTest(int isRandom, int width, int height, int run_times) { + int failed = 0; + aom_usec_timer ref_timer, test_timer; + for (int k = 0; k < 3; k++) { + int stride = 4 << rnd_(7); // Up to 256 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(7); + } + if (isRandom) { + GenRandomData(width, height, stride); + } else { + const int msb = isHbd_ ? 12 : 8; // Up to 12 bit input + const int limit = (1 << msb) - 1; + if (k == 0) { + GenExtremeData(width, height, stride, src_, 0); + GenExtremeData(width, height, stride, ref_, limit); + } else { + GenExtremeData(width, height, stride, src_, limit); + GenExtremeData(width, height, stride, ref_, 0); + } + } + int64_t res_ref, res_tst; + uint8_t *pSrc = src_; + uint8_t *pRef = ref_; + if (isHbd_) { + pSrc = CONVERT_TO_BYTEPTR(src_); + pRef = CONVERT_TO_BYTEPTR(ref_); + } + res_ref = params_.ref_func(pSrc, stride, pRef, stride, width, height); + res_tst = params_.tst_func(pSrc, stride, pRef, stride, width, height); + if (run_times > 1) { + aom_usec_timer_start(&ref_timer); + for (int j = 0; j < run_times; j++) { + params_.ref_func(pSrc, stride, pRef, stride, width, height); + } + 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 j = 0; j < run_times; j++) { + params_.tst_func(pSrc, stride, pRef, stride, width, height); + } + 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)); + } else { + if (!failed) { + failed = res_ref != res_tst; + EXPECT_EQ(res_ref, res_tst) + << "Error:" << (isHbd_ ? "hbd " : " ") << k << " SSE Test [" + << width << "x" << height + << "] C output does not match optimized output."; + } + } + } +} + +TEST_P(SSETest, OperationCheck) { + for (int height = 4; height <= 128; height += 4) { + RunTest(1, width_, height, 1); // GenRandomData + } +} + +TEST_P(SSETest, ExtremeValues) { + for (int height = 4; height <= 128; height += 4) { + RunTest(0, width_, height, 1); + } +} + +TEST_P(SSETest, DISABLED_Speed) { + for (int height = 4; height <= 128; height += 4) { + RunTest(1, width_, height, 100); + } +} + +#if HAVE_NEON +TestSSEFuncs sse_neon[] = { + TestSSEFuncs(&aom_sse_c, &aom_sse_neon), +#if CONFIG_AV1_HIGHBITDEPTH + TestSSEFuncs(&aom_highbd_sse_c, &aom_highbd_sse_neon) +#endif +}; +INSTANTIATE_TEST_SUITE_P(NEON, SSETest, + Combine(ValuesIn(sse_neon), Range(4, 129, 4))); +#endif // HAVE_NEON + +#if HAVE_SSE4_1 +TestSSEFuncs sse_sse4[] = { + TestSSEFuncs(&aom_sse_c, &aom_sse_sse4_1), +#if CONFIG_AV1_HIGHBITDEPTH + TestSSEFuncs(&aom_highbd_sse_c, &aom_highbd_sse_sse4_1) +#endif +}; +INSTANTIATE_TEST_SUITE_P(SSE4_1, SSETest, + Combine(ValuesIn(sse_sse4), Range(4, 129, 4))); +#endif // HAVE_SSE4_1 + +#if HAVE_AVX2 + +TestSSEFuncs sse_avx2[] = { + TestSSEFuncs(&aom_sse_c, &aom_sse_avx2), +#if CONFIG_AV1_HIGHBITDEPTH + TestSSEFuncs(&aom_highbd_sse_c, &aom_highbd_sse_avx2) +#endif +}; +INSTANTIATE_TEST_SUITE_P(AVX2, SSETest, + Combine(ValuesIn(sse_avx2), Range(4, 129, 4))); +#endif // HAVE_AVX2 + +////////////////////////////////////////////////////////////////////////////// +// get_blk sum squares test functions +////////////////////////////////////////////////////////////////////////////// + +typedef void (*sse_sum_func)(const int16_t *data, int stride, int bw, int bh, + int *x_sum, int64_t *x2_sum); +typedef libaom_test::FuncParam<sse_sum_func> TestSSE_SumFuncs; + +typedef std::tuple<TestSSE_SumFuncs, int> SSE_SumTestParam; + +class SSE_Sum_Test : public ::testing::TestWithParam<SSE_SumTestParam> { + public: + virtual ~SSE_Sum_Test() {} + virtual void SetUp() { + params_ = GET_PARAM(0); + width_ = GET_PARAM(1); + rnd_.Reset(ACMRandom::DeterministicSeed()); + src_ = reinterpret_cast<int16_t *>(aom_memalign(32, 256 * 256 * 2)); + ASSERT_TRUE(src_ != NULL); + } + + virtual void TearDown() { + libaom_test::ClearSystemState(); + aom_free(src_); + } + void RunTest(int isRandom, int width, int height, int run_times); + + void GenRandomData(int width, int height, int stride) { + const int msb = 11; // Up to 12 bit input + const int limit = 1 << (msb + 1); + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src_[ii * stride + jj] = rnd_(limit); + } + } + } + + void GenExtremeData(int width, int height, int stride, int16_t *data, + int16_t val) { + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + data[ii * stride + jj] = val; + } + } + } + + protected: + int width_; + TestSSE_SumFuncs params_; + int16_t *src_; + ACMRandom rnd_; +}; + +void SSE_Sum_Test::RunTest(int isRandom, int width, int height, int run_times) { + aom_usec_timer ref_timer, test_timer; + for (int k = 0; k < 3; k++) { + int stride = 4 << rnd_(7); // Up to 256 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(7); + } + if (isRandom) { + GenRandomData(width, height, stride); + } else { + const int msb = 12; // Up to 12 bit input + const int limit = (1 << msb) - 1; + if (k == 0) { + GenExtremeData(width, height, stride, src_, limit); + } else { + GenExtremeData(width, height, stride, src_, -limit); + } + } + int sum_c = 0; + int64_t sse_intr = 0; + int sum_intr = 0; + int64_t sse_c = 0; + + params_.ref_func(src_, stride, width, height, &sum_c, &sse_c); + params_.tst_func(src_, stride, width, height, &sum_intr, &sse_intr); + + if (run_times > 1) { + aom_usec_timer_start(&ref_timer); + for (int j = 0; j < run_times; j++) { + params_.ref_func(src_, stride, width, height, &sum_c, &sse_c); + } + 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 j = 0; j < run_times; j++) { + params_.tst_func(src_, stride, width, height, &sum_intr, &sse_intr); + } + 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=%f\t width=%d\t height=%d \n", + elapsed_time_c, elapsed_time_simd, + (float)((float)elapsed_time_c / (float)elapsed_time_simd), width, + height); + + } else { + EXPECT_EQ(sum_c, sum_intr) + << "Error:" << k << " SSE Sum Test [" << width << "x" << height + << "] C output does not match optimized output."; + EXPECT_EQ(sse_c, sse_intr) + << "Error:" << k << " SSE Sum Test [" << width << "x" << height + << "] C output does not match optimized output."; + } + } +} + +TEST_P(SSE_Sum_Test, OperationCheck) { + for (int height = 4; height <= 64; height = height * 2) { + RunTest(1, width_, height, 1); // GenRandomData + } +} + +TEST_P(SSE_Sum_Test, ExtremeValues) { + for (int height = 4; height <= 64; height = height * 2) { + RunTest(0, width_, height, 1); + } +} + +TEST_P(SSE_Sum_Test, DISABLED_Speed) { + for (int height = 4; height <= 64; height = height * 2) { + RunTest(1, width_, height, 10000); + } +} + +#if HAVE_SSE2 +TestSSE_SumFuncs sse_sum_sse2[] = { TestSSE_SumFuncs( + &aom_get_blk_sse_sum_c, &aom_get_blk_sse_sum_sse2) }; +INSTANTIATE_TEST_SUITE_P(SSE2, SSE_Sum_Test, + Combine(ValuesIn(sse_sum_sse2), Range(4, 65, 4))); +#endif // HAVE_SSE2 + +#if HAVE_AVX2 +TestSSE_SumFuncs sse_sum_avx2[] = { TestSSE_SumFuncs( + &aom_get_blk_sse_sum_c, &aom_get_blk_sse_sum_avx2) }; +INSTANTIATE_TEST_SUITE_P(AVX2, SSE_Sum_Test, + Combine(ValuesIn(sse_sum_avx2), Range(4, 65, 4))); +#endif // HAVE_AVX2 + +////////////////////////////////////////////////////////////////////////////// +// 2D Variance test functions +////////////////////////////////////////////////////////////////////////////// + +typedef uint64_t (*Var2DFunc)(uint8_t *src, int stride, int width, int height); +typedef libaom_test::FuncParam<Var2DFunc> TestFuncVar2D; + +const uint16_t test_block_size[2] = { 128, 256 }; + +class Lowbd2dVarTest : public ::testing::TestWithParam<TestFuncVar2D> { + public: + virtual ~Lowbd2dVarTest() {} + virtual void SetUp() { + params_ = this->GetParam(); + rnd_.Reset(ACMRandom::DeterministicSeed()); + src_ = reinterpret_cast<uint8_t *>( + aom_memalign(16, 512 * 512 * sizeof(uint8_t))); + ASSERT_TRUE(src_ != NULL); + } + + virtual void TearDown() { + libaom_test::ClearSystemState(); + aom_free(src_); + } + void RunTest(int isRandom); + void RunSpeedTest(); + + void GenRandomData(int width, int height, int stride) { + const int msb = 7; // Up to 8 bit input + const int limit = 1 << (msb + 1); + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src_[ii * stride + jj] = rnd_(limit); + } + } + } + + void GenExtremeData(int width, int height, int stride) { + const int msb = 7; // Up to 8 bit input + const int limit = 1 << (msb + 1); + const int val = rnd_(2) ? limit - 1 : 0; + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src_[ii * stride + jj] = val; + } + } + } + + protected: + TestFuncVar2D params_; + uint8_t *src_; + ACMRandom rnd_; +}; + +void Lowbd2dVarTest::RunTest(int isRandom) { + int failed = 0; + for (int k = 0; k < kNumIterations; k++) { + const int width = 4 * (rnd_(63) + 1); // Up to 256x256 + const int height = 4 * (rnd_(63) + 1); // Up to 256x256 + int stride = 4 << rnd_(8); // Up to 512 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(8); + } + if (isRandom) { + GenRandomData(width, height, stride); + } else { + GenExtremeData(width, height, stride); + } + + const uint64_t res_ref = params_.ref_func(src_, stride, width, height); + uint64_t res_tst; + ASM_REGISTER_STATE_CHECK(res_tst = + params_.tst_func(src_, stride, width, height)); + + if (!failed) { + failed = res_ref != res_tst; + EXPECT_EQ(res_ref, res_tst) + << "Error: Sum Squares Test [" << width << "x" << height + << "] C output does not match optimized output."; + } + } +} + +void Lowbd2dVarTest::RunSpeedTest() { + for (int block = 0; block < 2; block++) { + const int width = test_block_size[block]; + const int height = test_block_size[block]; + int stride = 4 << rnd_(8); // Up to 512 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(8); + } + 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)); + + 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("%3dx%-3d: Scaling = %.2f\n", width, height, + (double)elapsed_time / elapsed_time1); + } +} + +TEST_P(Lowbd2dVarTest, OperationCheck) { + RunTest(1); // GenRandomData +} + +TEST_P(Lowbd2dVarTest, ExtremeValues) { + RunTest(0); // GenExtremeData +} + +TEST_P(Lowbd2dVarTest, DISABLED_Speed) { RunSpeedTest(); } + +#if HAVE_SSE2 + +INSTANTIATE_TEST_SUITE_P(SSE2, Lowbd2dVarTest, + ::testing::Values(TestFuncVar2D(&aom_var_2d_u8_c, + &aom_var_2d_u8_sse2))); + +#endif // HAVE_SSE2 + +#if HAVE_AVX2 + +INSTANTIATE_TEST_SUITE_P(AVX2, Lowbd2dVarTest, + ::testing::Values(TestFuncVar2D(&aom_var_2d_u8_c, + &aom_var_2d_u8_avx2))); + +#endif // HAVE_SSE2 + +class Highbd2dVarTest : public ::testing::TestWithParam<TestFuncVar2D> { + public: + virtual ~Highbd2dVarTest() {} + virtual void SetUp() { + params_ = this->GetParam(); + rnd_.Reset(ACMRandom::DeterministicSeed()); + src_ = reinterpret_cast<uint16_t *>( + aom_memalign(16, 512 * 512 * sizeof(uint16_t))); + ASSERT_TRUE(src_ != NULL); + } + + virtual void TearDown() { + libaom_test::ClearSystemState(); + 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 + const int limit = 1 << (msb + 1); + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src_[ii * stride + jj] = rnd_(limit); + } + } + } + + void GenExtremeData(int width, int height, int stride) { + const int msb = 11; // Up to 12 bit input + const int limit = 1 << (msb + 1); + const int val = rnd_(2) ? limit - 1 : 0; + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src_[ii * stride + jj] = val; + } + } + } + + protected: + TestFuncVar2D params_; + uint16_t *src_; + ACMRandom rnd_; +}; + +void Highbd2dVarTest::RunTest(int isRandom) { + int failed = 0; + for (int k = 0; k < kNumIterations; k++) { + const int width = 4 * (rnd_(63) + 1); // Up to 256x256 + const int height = 4 * (rnd_(63) + 1); // Up to 256x256 + int stride = 4 << rnd_(8); // Up to 512 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(8); + } + if (isRandom) { + GenRandomData(width, height, stride); + } else { + GenExtremeData(width, height, stride); + } + + const uint64_t res_ref = + params_.ref_func(CONVERT_TO_BYTEPTR(src_), stride, width, height); + uint64_t res_tst; + ASM_REGISTER_STATE_CHECK( + res_tst = + params_.tst_func(CONVERT_TO_BYTEPTR(src_), stride, width, height)); + + if (!failed) { + failed = res_ref != res_tst; + EXPECT_EQ(res_ref, res_tst) + << "Error: Sum Squares Test [" << width << "x" << height + << "] C output does not match optimized output."; + } + } +} + +void Highbd2dVarTest::RunSpeedTest() { + for (int block = 0; block < 2; block++) { + const int width = test_block_size[block]; + const int height = test_block_size[block]; + int stride = 4 << rnd_(8); // Up to 512 stride + while (stride < width) { // Make sure it's valid + stride = 4 << rnd_(8); + } + 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(CONVERT_TO_BYTEPTR(src_), stride, width, height); + + aom_usec_timer_mark(&timer); + const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); + + aom_usec_timer timer1; + aom_usec_timer_start(&timer1); + for (int i = 0; i < num_loops; ++i) + params_.tst_func(CONVERT_TO_BYTEPTR(src_), stride, width, height); + aom_usec_timer_mark(&timer1); + const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1)); + printf("%3dx%-3d: Scaling = %.2f\n", width, height, + (double)elapsed_time / elapsed_time1); + } +} + +TEST_P(Highbd2dVarTest, OperationCheck) { + RunTest(1); // GenRandomData +} + +TEST_P(Highbd2dVarTest, ExtremeValues) { + RunTest(0); // GenExtremeData +} + +TEST_P(Highbd2dVarTest, DISABLED_Speed) { RunSpeedTest(); } + +#if HAVE_SSE2 + +INSTANTIATE_TEST_SUITE_P( + SSE2, Highbd2dVarTest, + ::testing::Values(TestFuncVar2D(&aom_var_2d_u16_c, &aom_var_2d_u16_sse2))); + +#endif // HAVE_SSE2 + +#if HAVE_AVX2 + +INSTANTIATE_TEST_SUITE_P( + AVX2, Highbd2dVarTest, + ::testing::Values(TestFuncVar2D(&aom_var_2d_u16_c, &aom_var_2d_u16_avx2))); #endif // HAVE_SSE2 } // namespace diff --git a/media/libaom/src/test/superframe_test.cc b/media/libaom/src/test/superframe_test.cc index 7be18f72a..024a18b97 100644 --- a/media/libaom/src/test/superframe_test.cc +++ b/media/libaom/src/test/superframe_test.cc @@ -10,6 +10,7 @@ */ #include <climits> +#include <tuple> #include <vector> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -23,7 +24,7 @@ const int kTestMode = 0; const int kTileCols = 1; const int kTileRows = 2; -typedef ::testing::tuple<libaom_test::TestMode, int, int> SuperframeTestParam; +typedef std::tuple<libaom_test::TestMode, int, int> SuperframeTestParam; class SuperframeTest : public ::libaom_test::CodecTestWithParam<SuperframeTestParam>, @@ -35,17 +36,17 @@ class SuperframeTest virtual void SetUp() { InitializeConfig(); const SuperframeTestParam input = GET_PARAM(1); - const libaom_test::TestMode mode = ::testing::get<kTestMode>(input); + const libaom_test::TestMode mode = std::get<kTestMode>(input); SetMode(mode); sf_count_ = 0; sf_count_max_ = INT_MAX; - n_tile_cols_ = ::testing::get<kTileCols>(input); - n_tile_rows_ = ::testing::get<kTileRows>(input); + n_tile_cols_ = std::get<kTileCols>(input); + n_tile_rows_ = std::get<kTileRows>(input); } virtual void PreEncodeFrameHook(libaom_test::VideoSource *video, libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); encoder->Control(AOME_SET_CPUUSED, 2); encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_); diff --git a/media/libaom/src/test/svc_datarate_test.cc b/media/libaom/src/test/svc_datarate_test.cc new file mode 100644 index 000000000..28e517ba1 --- /dev/null +++ b/media/libaom/src/test/svc_datarate_test.cc @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include "config/aom_config.h" + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/datarate_test.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/util.h" +#include "test/y4m_video_source.h" +#include "aom/aom_codec.h" +#include "av1/common/enums.h" + +namespace datarate_test { +namespace { + +class DatarateTestSVC + : public ::libaom_test::CodecTestWith4Params<libaom_test::TestMode, int, + unsigned int, int>, + public DatarateTest { + public: + DatarateTestSVC() : DatarateTest(GET_PARAM(0)) { + set_cpu_used_ = GET_PARAM(2); + aq_mode_ = GET_PARAM(3); + } + + protected: + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + ResetModel(); + } + + virtual int GetNumSpatialLayers() { return number_spatial_layers_; } + + virtual void ResetModel() { + DatarateTest::ResetModel(); + layer_frame_cnt_ = 0; + superframe_cnt_ = 0; + number_temporal_layers_ = 1; + number_spatial_layers_ = 1; + for (int i = 0; i < AOM_MAX_LAYERS; i++) { + target_layer_bitrate_[i] = 0; + effective_datarate_tl[i] = 0.0; + } + memset(&layer_id_, 0, sizeof(aom_svc_layer_id_t)); + memset(&svc_params_, 0, sizeof(aom_svc_params_t)); + memset(&ref_frame_config_, 0, sizeof(aom_svc_ref_frame_config_t)); + } + + virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, + ::libaom_test::Encoder *encoder) { + int spatial_layer_id = 0; + if (video->frame() == 0) { + initialize_svc(number_temporal_layers_, number_spatial_layers_, + &svc_params_); + encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); + encoder->Control(AV1E_SET_ENABLE_ORDER_HINT, 0); + encoder->Control(AV1E_SET_ENABLE_TPL_MODEL, 0); + encoder->Control(AV1E_SET_DELTAQ_MODE, 0); + } + if (number_spatial_layers_ == 2) { + spatial_layer_id = (layer_frame_cnt_ % 2 == 0) ? 0 : 1; + } else if (number_spatial_layers_ == 3) { + spatial_layer_id = (layer_frame_cnt_ % 3 == 0) + ? 0 + : ((layer_frame_cnt_ - 1) % 3 == 0) ? 1 : 2; + } + // Set the reference/update flags, layer_id, and reference_map + // buffer index. + frame_flags_ = set_layer_pattern(video->frame(), &layer_id_, + &ref_frame_config_, spatial_layer_id); + encoder->Control(AV1E_SET_SVC_LAYER_ID, &layer_id_); + encoder->Control(AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_); + layer_frame_cnt_++; + DatarateTest::PreEncodeFrameHook(video, encoder); + } + + virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { + const size_t frame_size_in_bits = pkt->data.frame.sz * 8; + // Update the layer cumulative bitrate. + for (int i = layer_id_.temporal_layer_id; i < number_temporal_layers_; + i++) { + int layer = layer_id_.spatial_layer_id * number_temporal_layers_ + i; + effective_datarate_tl[layer] += 1.0 * frame_size_in_bits; + } + if (layer_id_.spatial_layer_id == number_spatial_layers_ - 1) { + last_pts_ = pkt->data.frame.pts; + superframe_cnt_++; + } + } + + virtual void EndPassHook(void) { + duration_ = ((last_pts_ + 1) * timebase_); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + effective_datarate_tl[i] = (effective_datarate_tl[i] / 1000) / duration_; + } + } + + // Layer pattern configuration. + virtual int set_layer_pattern(int frame_cnt, aom_svc_layer_id_t *layer_id, + aom_svc_ref_frame_config_t *ref_frame_config, + int spatial_layer) { + layer_id->spatial_layer_id = spatial_layer; + // Set the referende map buffer idx for the 7 references: + // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3), + // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6). + for (int i = 0; i < INTER_REFS_PER_FRAME; i++) { + ref_frame_config->ref_idx[i] = i; + ref_frame_config->reference[i] = 0; + } + for (int i = 0; i < REF_FRAMES; i++) ref_frame_config->refresh[i] = 0; + // Set layer_flags to 0 when using ref_frame_config->reference. + int layer_flags = 0; + // Always reference LAST. + ref_frame_config->reference[0] = 1; + if (number_temporal_layers_ == 3 && number_spatial_layers_ == 1) { + // 3-layer: + // 1 3 5 7 + // 2 6 + // 0 4 8 + if (frame_cnt % 4 == 0) { + // Base layer. + layer_id->temporal_layer_id = 0; + // Update LAST on layer 0, reference LAST and GF. + ref_frame_config->refresh[0] = 1; + ref_frame_config->reference[3] = 1; + } else if ((frame_cnt - 1) % 4 == 0) { + layer_id->temporal_layer_id = 2; + // First top layer: no updates, only reference LAST (TL0). + } else if ((frame_cnt - 2) % 4 == 0) { + layer_id->temporal_layer_id = 1; + // Middle layer (TL1): update LAST2, only reference LAST (TL0). + ref_frame_config->refresh[1] = 1; + } else if ((frame_cnt - 3) % 4 == 0) { + layer_id->temporal_layer_id = 2; + // Second top layer: no updates, only reference LAST. + // Set buffer idx for LAST to slot 1, since that was the slot + // updated in previous frame. So LAST is TL1 frame. + ref_frame_config->ref_idx[0] = 1; + ref_frame_config->ref_idx[1] = 0; + } + } else if (number_temporal_layers_ == 1 && number_spatial_layers_ == 2) { + layer_id->temporal_layer_id = 0; + if (layer_id->spatial_layer_id == 0) { + // Reference LAST, update LAST. Keep LAST and GOLDEN in slots 0 and 3. + ref_frame_config->ref_idx[0] = 0; + ref_frame_config->ref_idx[3] = 3; + ref_frame_config->refresh[0] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 3 + // and GOLDEN to slot 0. Update slot 3 (LAST). + ref_frame_config->ref_idx[0] = 3; + ref_frame_config->ref_idx[3] = 0; + ref_frame_config->refresh[3] = 1; + } + // Reference GOLDEN. + if (layer_id->spatial_layer_id > 0) ref_frame_config->reference[3] = 1; + } else if (number_temporal_layers_ == 1 && number_spatial_layers_ == 3) { + // 3 spatial layers, 1 temporal. + // Note for this case , we set the buffer idx for all references to be + // either LAST or GOLDEN, which are always valid references, since decoder + // will check if any of the 7 references is valid scale in + // valid_ref_frame_size(). + layer_id->temporal_layer_id = 0; + if (layer_id->spatial_layer_id == 0) { + // Reference LAST, update LAST. Set all other buffer_idx to 0. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->refresh[0] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1 + // and GOLDEN (and all other refs) to slot 0. + // Update slot 1 (LAST). + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[0] = 1; + ref_frame_config->refresh[1] = 1; + } else if (layer_id->spatial_layer_id == 2) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2 + // and GOLDEN (and all other refs) to slot 1. + // Update slot 2 (LAST). + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 1; + ref_frame_config->ref_idx[0] = 2; + ref_frame_config->refresh[2] = 1; + } + // Reference GOLDEN. + if (layer_id->spatial_layer_id > 0) ref_frame_config->reference[3] = 1; + } else if (number_temporal_layers_ == 3 && number_spatial_layers_ == 3) { + // 3 spatial and 3 temporal layer. + if (superframe_cnt_ % 4 == 0) { + // Base temporal layer. + layer_id->temporal_layer_id = 0; + if (layer_id->spatial_layer_id == 0) { + // Reference LAST, update LAST. + // Set all buffer_idx to 0. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->refresh[0] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, + // GOLDEN (and all other refs) to slot 0. + // Update slot 1 (LAST). + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[0] = 1; + ref_frame_config->refresh[1] = 1; + } else if (layer_id->spatial_layer_id == 2) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, + // GOLDEN (and all other refs) to slot 1. + // Update slot 2 (LAST). + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 1; + ref_frame_config->ref_idx[0] = 2; + ref_frame_config->refresh[2] = 1; + } + } else if ((superframe_cnt_ - 1) % 4 == 0) { + // First top temporal enhancement layer. + layer_id->temporal_layer_id = 2; + if (layer_id->spatial_layer_id == 0) { + // Reference LAST (slot 0). + // Set GOLDEN to slot 3 and update slot 3. + // Set all other buffer_idx to slot 0. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[3] = 3; + ref_frame_config->refresh[3] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, + // GOLDEN (and all other refs) to slot 3. + // Set LAST2 to slot 4 and Update slot 4. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 3; + ref_frame_config->ref_idx[0] = 1; + ref_frame_config->ref_idx[1] = 4; + ref_frame_config->refresh[4] = 1; + } else if (layer_id->spatial_layer_id == 2) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, + // GOLDEN (and all other refs) to slot 4. + // No update. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 4; + ref_frame_config->ref_idx[0] = 2; + } + } else if ((superframe_cnt_ - 2) % 4 == 0) { + // Middle temporal enhancement layer. + layer_id->temporal_layer_id = 1; + if (layer_id->spatial_layer_id == 0) { + // Reference LAST. + // Set all buffer_idx to 0. + // Set GOLDEN to slot 5 and update slot 5. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[3] = 5; + ref_frame_config->refresh[5] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, + // GOLDEN (and all other refs) to slot 5. + // Set LAST2 to slot 6 and update slot 6. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 5; + ref_frame_config->ref_idx[0] = 1; + ref_frame_config->ref_idx[2] = 6; + ref_frame_config->refresh[6] = 1; + } else if (layer_id->spatial_layer_id == 2) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, + // GOLDEN (and all other refs) to slot 6. + // Set LAST2 to slot 6 and update slot 7. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 6; + ref_frame_config->ref_idx[0] = 2; + ref_frame_config->ref_idx[2] = 7; + ref_frame_config->refresh[7] = 1; + } + } else if ((superframe_cnt_ - 3) % 4 == 0) { + // Second top temporal enhancement layer. + layer_id->temporal_layer_id = 2; + if (layer_id->spatial_layer_id == 0) { + // Set LAST to slot 5 and reference LAST. + // Set GOLDEN to slot 3 and update slot 3. + // Set all other buffer_idx to 0. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[0] = 5; + ref_frame_config->ref_idx[3] = 3; + ref_frame_config->refresh[3] = 1; + } else if (layer_id->spatial_layer_id == 1) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 6, + // GOLDEN to slot 3. Set LAST2 to slot 4 and update slot 4. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[0] = 6; + ref_frame_config->ref_idx[3] = 3; + ref_frame_config->ref_idx[1] = 4; + ref_frame_config->refresh[4] = 1; + } else if (layer_id->spatial_layer_id == 2) { + // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 7, + // GOLDEN to slot 4. No update. + for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0; + ref_frame_config->ref_idx[0] = 7; + ref_frame_config->ref_idx[3] = 4; + } + } + // Reference GOLDEN. + if (layer_id->spatial_layer_id > 0) ref_frame_config->reference[3] = 1; + } + return layer_flags; + } + + virtual void initialize_svc(int number_temporal_layers, + int number_spatial_layers, + aom_svc_params *svc_params) { + svc_params->number_spatial_layers = number_spatial_layers; + svc_params->number_temporal_layers = number_temporal_layers; + for (int i = 0; i < number_temporal_layers * number_spatial_layers; ++i) { + svc_params->max_quantizers[i] = 60; + svc_params->min_quantizers[i] = 2; + svc_params->layer_target_bitrate[i] = target_layer_bitrate_[i]; + } + // Do at most 3 spatial or temporal layers here. + svc_params->framerate_factor[0] = 1; + if (number_temporal_layers == 2) { + svc_params->framerate_factor[0] = 2; + svc_params->framerate_factor[1] = 1; + } else if (number_temporal_layers == 3) { + svc_params->framerate_factor[0] = 4; + svc_params->framerate_factor[1] = 2; + svc_params->framerate_factor[2] = 1; + } + svc_params->scaling_factor_num[0] = 1; + svc_params->scaling_factor_den[0] = 1; + if (number_spatial_layers == 2) { + svc_params->scaling_factor_num[0] = 1; + svc_params->scaling_factor_den[0] = 2; + svc_params->scaling_factor_num[1] = 1; + svc_params->scaling_factor_den[1] = 1; + } else if (number_spatial_layers == 3) { + svc_params->scaling_factor_num[0] = 1; + svc_params->scaling_factor_den[0] = 4; + svc_params->scaling_factor_num[1] = 1; + svc_params->scaling_factor_den[1] = 2; + svc_params->scaling_factor_num[2] = 1; + svc_params->scaling_factor_den[2] = 1; + } + } + + virtual void BasicRateTargetingSVC3TL1SLTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 200, 550 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 3; + target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100; + target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100; + target_layer_bitrate_[2] = cfg_.rc_target_bitrate; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.30) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC1TL2SLTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 300, 600 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 1; + number_spatial_layers_ = 2; + target_layer_bitrate_[0] = 2 * cfg_.rc_target_bitrate / 4; + target_layer_bitrate_[1] = 2 * cfg_.rc_target_bitrate / 4; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.35) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC1TL3SLTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 500, 1000 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 1; + number_spatial_layers_ = 3; + target_layer_bitrate_[0] = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[1] = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[2] = 4 * cfg_.rc_target_bitrate / 8; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC3TL3SLTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 600, 1200 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 3; + number_spatial_layers_ = 3; + // SL0 + const int bitrate_sl0 = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[0] = 50 * bitrate_sl0 / 100; + target_layer_bitrate_[1] = 70 * bitrate_sl0 / 100; + target_layer_bitrate_[2] = bitrate_sl0; + // SL1 + const int bitrate_sl1 = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[3] = 50 * bitrate_sl1 / 100; + target_layer_bitrate_[4] = 70 * bitrate_sl1 / 100; + target_layer_bitrate_[5] = bitrate_sl1; + // SL2 + const int bitrate_sl2 = 4 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[6] = 50 * bitrate_sl2 / 100; + target_layer_bitrate_[7] = 70 * bitrate_sl2 / 100; + target_layer_bitrate_[8] = bitrate_sl2; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC3TL3SLHDTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + + ::libaom_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); + const int bitrate_array[2] = { 600, 1200 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 3; + number_spatial_layers_ = 3; + // SL0 + const int bitrate_sl0 = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[0] = 50 * bitrate_sl0 / 100; + target_layer_bitrate_[1] = 70 * bitrate_sl0 / 100; + target_layer_bitrate_[2] = bitrate_sl0; + // SL1 + const int bitrate_sl1 = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[3] = 50 * bitrate_sl1 / 100; + target_layer_bitrate_[4] = 70 * bitrate_sl1 / 100; + target_layer_bitrate_[5] = bitrate_sl1; + // SL2 + const int bitrate_sl2 = 4 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[6] = 50 * bitrate_sl2 / 100; + target_layer_bitrate_[7] = 70 * bitrate_sl2 / 100; + target_layer_bitrate_[8] = bitrate_sl2; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.70) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.4) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC3TL3SLKfTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + cfg_.kf_mode = AOM_KF_AUTO; + cfg_.kf_min_dist = cfg_.kf_max_dist = 100; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 600, 1200 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 3; + number_spatial_layers_ = 3; + // SL0 + const int bitrate_sl0 = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[0] = 50 * bitrate_sl0 / 100; + target_layer_bitrate_[1] = 70 * bitrate_sl0 / 100; + target_layer_bitrate_[2] = bitrate_sl0; + // SL1 + const int bitrate_sl1 = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[3] = 50 * bitrate_sl1 / 100; + target_layer_bitrate_[4] = 70 * bitrate_sl1 / 100; + target_layer_bitrate_[5] = bitrate_sl1; + // SL2 + const int bitrate_sl2 = 4 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[6] = 50 * bitrate_sl2 / 100; + target_layer_bitrate_[7] = 70 * bitrate_sl2 / 100; + target_layer_bitrate_[8] = bitrate_sl2; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.75) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.4) + << " The datarate for the file is greater than target by too much!"; + } + } + + int layer_frame_cnt_; + int superframe_cnt_; + int number_temporal_layers_; + int number_spatial_layers_; + // Allow for up to 3 temporal layers. + int target_layer_bitrate_[AOM_MAX_LAYERS]; + aom_svc_params_t svc_params_; + aom_svc_ref_frame_config_t ref_frame_config_; + aom_svc_layer_id_t layer_id_; + double effective_datarate_tl[AOM_MAX_LAYERS]; +}; + +// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SL) { + BasicRateTargetingSVC3TL1SLTest(); +} + +// Check basic rate targeting for CBR, for 2 spatial layers, 1 temporal. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL2SL) { + BasicRateTargetingSVC1TL2SLTest(); +} + +// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SL) { + BasicRateTargetingSVC1TL3SLTest(); +} + +// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SL) { + BasicRateTargetingSVC3TL3SLTest(); +} + +// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHD) { + BasicRateTargetingSVC3TL3SLHDTest(); +} + +// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, +// for auto key frame mode with short key frame period. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLKf) { + BasicRateTargetingSVC3TL3SLKfTest(); +} + +AV1_INSTANTIATE_TEST_CASE(DatarateTestSVC, + ::testing::Values(::libaom_test::kRealTime), + ::testing::Range(7, 9), + ::testing::Range<unsigned int>(0, 4), + ::testing::Values(0, 1)); + +} // namespace +} // namespace datarate_test diff --git a/media/libaom/src/test/temporal_filter_planewise_test.cc b/media/libaom/src/test/temporal_filter_planewise_test.cc new file mode 100644 index 000000000..c3f3e9e05 --- /dev/null +++ b/media/libaom/src/test/temporal_filter_planewise_test.cc @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <cmath> +#include <cstdlib> +#include <string> +#include <tuple> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/aom_config.h" +#include "config/aom_dsp_rtcd.h" +#include "config/av1_rtcd.h" + +#include "aom_ports/mem.h" +#include "test/acm_random.h" +#include "test/clear_system_state.h" +#include "test/register_state_check.h" +#include "test/util.h" +#include "test/function_equivalence_test.h" + +using libaom_test::ACMRandom; +using libaom_test::FunctionEquivalenceTest; +using ::testing::Combine; +using ::testing::Range; +using ::testing::Values; +using ::testing::ValuesIn; + +#if !CONFIG_REALTIME_ONLY +namespace { + +typedef void (*TemporalFilterPlanewiseFunc)( + const YV12_BUFFER_CONFIG *ref_frame, const MACROBLOCKD *mbd, + const BLOCK_SIZE block_size, const int mb_row, const int mb_col, + const int num_planes, const double *noise_level, const int use_subblock, + const int block_mse, const int *subblock_mses, const int q_factor, + const uint8_t *pred, uint32_t *accum, uint16_t *count); +typedef libaom_test::FuncParam<TemporalFilterPlanewiseFunc> + TemporalFilterPlanewiseFuncParam; + +typedef std::tuple<TemporalFilterPlanewiseFuncParam, int> + TemporalFilterPlanewiseWithParam; + +class TemporalFilterPlanewiseTest + : public ::testing::TestWithParam<TemporalFilterPlanewiseWithParam> { + public: + virtual ~TemporalFilterPlanewiseTest() {} + virtual void SetUp() { + params_ = GET_PARAM(0); + rnd_.Reset(ACMRandom::DeterministicSeed()); + src1_ = reinterpret_cast<uint8_t *>(aom_memalign(8, 256 * 256)); + src2_ = reinterpret_cast<uint8_t *>(aom_memalign(8, 256 * 256)); + + ASSERT_TRUE(src1_ != NULL); + ASSERT_TRUE(src2_ != NULL); + } + + virtual void TearDown() { + libaom_test::ClearSystemState(); + aom_free(src1_); + aom_free(src2_); + } + void RunTest(int isRandom, int width, int height, int run_times); + + void GenRandomData(int width, int height, int stride, int stride2) { + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + src1_[ii * stride + jj] = rnd_.Rand8(); + src2_[ii * stride2 + jj] = rnd_.Rand8(); + } + } + } + + void GenExtremeData(int width, int height, int stride, uint8_t *data, + int stride2, uint8_t *data2, uint8_t val) { + for (int ii = 0; ii < height; ii++) { + for (int jj = 0; jj < width; jj++) { + data[ii * stride + jj] = val; + data2[ii * stride2 + jj] = (255 - val); + } + } + } + + protected: + TemporalFilterPlanewiseFuncParam params_; + uint8_t *src1_; + uint8_t *src2_; + ACMRandom rnd_; +}; + +void TemporalFilterPlanewiseTest::RunTest(int isRandom, int width, int height, + int run_times) { + aom_usec_timer ref_timer, test_timer; + for (int k = 0; k < 3; k++) { + const int stride = width; + const int stride2 = width; + if (isRandom) { + GenRandomData(width, height, stride, stride2); + } else { + const int msb = 8; // Up to 8 bit input + const int limit = (1 << msb) - 1; + if (k == 0) { + GenExtremeData(width, height, stride, src1_, stride2, src2_, limit); + } else { + GenExtremeData(width, height, stride, src1_, stride2, src2_, 0); + } + } + double sigma[1] = { 2.1002103677063437 }; + DECLARE_ALIGNED(16, unsigned int, accumulator_ref[1024 * 3]); + DECLARE_ALIGNED(16, uint16_t, count_ref[1024 * 3]); + memset(accumulator_ref, 0, 1024 * 3 * sizeof(accumulator_ref[0])); + memset(count_ref, 0, 1024 * 3 * sizeof(count_ref[0])); + DECLARE_ALIGNED(16, unsigned int, accumulator_mod[1024 * 3]); + DECLARE_ALIGNED(16, uint16_t, count_mod[1024 * 3]); + memset(accumulator_mod, 0, 1024 * 3 * sizeof(accumulator_mod[0])); + memset(count_mod, 0, 1024 * 3 * sizeof(count_mod[0])); + + assert(width == 32 && height == 32); + const BLOCK_SIZE block_size = BLOCK_32X32; + const int use_subblock = 0; + const int block_mse = 20; + const int subblock_mses[4] = { 15, 16, 17, 18 }; + const int q_factor = 12; + const int mb_row = 0; + const int mb_col = 0; + const int num_planes = 1; + YV12_BUFFER_CONFIG *ref_frame = + (YV12_BUFFER_CONFIG *)malloc(sizeof(YV12_BUFFER_CONFIG)); + ref_frame->heights[0] = height; + ref_frame->strides[0] = stride; + DECLARE_ALIGNED(16, uint8_t, src[1024 * 3]); + ref_frame->buffer_alloc = src; + ref_frame->buffers[0] = ref_frame->buffer_alloc; + ref_frame->flags = 0; // Only support low bit-depth test. + memcpy(src, src1_, 1024 * 3 * sizeof(uint8_t)); + + MACROBLOCKD *mbd = (MACROBLOCKD *)malloc(sizeof(MACROBLOCKD)); + mbd->plane[0].subsampling_y = 0; + mbd->plane[0].subsampling_x = 0; + mbd->bd = 8; + + params_.ref_func(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + sigma, use_subblock, block_mse, subblock_mses, q_factor, + src2_, accumulator_ref, count_ref); + params_.tst_func(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + sigma, use_subblock, block_mse, subblock_mses, q_factor, + src2_, accumulator_mod, count_mod); + + if (run_times > 1) { + aom_usec_timer_start(&ref_timer); + for (int j = 0; j < run_times; j++) { + params_.ref_func(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + sigma, use_subblock, block_mse, subblock_mses, + q_factor, src2_, accumulator_ref, count_ref); + } + 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 j = 0; j < run_times; j++) { + params_.tst_func(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + sigma, use_subblock, block_mse, subblock_mses, + q_factor, src2_, accumulator_mod, count_mod); + } + 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=%f\t width=%d\t height=%d \n", + elapsed_time_c, elapsed_time_simd, + (float)((float)elapsed_time_c / (float)elapsed_time_simd), width, + height); + + } else { + for (int i = 0, l = 0; i < height; i++) { + for (int j = 0; j < width; j++, l++) { + EXPECT_EQ(accumulator_ref[l], accumulator_mod[l]) + << "Error:" << k << " SSE Sum Test [" << width << "x" << height + << "] C accumulator does not match optimized accumulator."; + EXPECT_EQ(count_ref[l], count_mod[l]) + << "Error:" << k << " SSE Sum Test [" << width << "x" << height + << "] C count does not match optimized count."; + } + } + } + + free(ref_frame); + free(mbd); + } +} + +TEST_P(TemporalFilterPlanewiseTest, OperationCheck) { + for (int height = 32; height <= 32; height = height * 2) { + RunTest(1, height, height, 1); // GenRandomData + } +} + +TEST_P(TemporalFilterPlanewiseTest, ExtremeValues) { + for (int height = 32; height <= 32; height = height * 2) { + RunTest(0, height, height, 1); + } +} + +TEST_P(TemporalFilterPlanewiseTest, DISABLED_Speed) { + for (int height = 32; height <= 32; height = height * 2) { + RunTest(1, height, height, 100000); + } +} + +#if HAVE_AVX2 +TemporalFilterPlanewiseFuncParam temporal_filter_planewise_test_avx2[] = { + TemporalFilterPlanewiseFuncParam(&av1_apply_temporal_filter_planewise_c, + &av1_apply_temporal_filter_planewise_avx2) +}; +INSTANTIATE_TEST_SUITE_P(AVX2, TemporalFilterPlanewiseTest, + Combine(ValuesIn(temporal_filter_planewise_test_avx2), + Range(64, 65, 4))); +#endif // HAVE_AVX2 + +#if HAVE_SSE2 +TemporalFilterPlanewiseFuncParam temporal_filter_planewise_test_sse2[] = { + TemporalFilterPlanewiseFuncParam(&av1_apply_temporal_filter_planewise_c, + &av1_apply_temporal_filter_planewise_sse2) +}; +INSTANTIATE_TEST_SUITE_P(SSE2, TemporalFilterPlanewiseTest, + Combine(ValuesIn(temporal_filter_planewise_test_sse2), + Range(64, 65, 4))); +#endif // HAVE_SSE2 + +} // namespace +#endif diff --git a/media/libaom/src/test/temporal_filter_yuv_test.cc b/media/libaom/src/test/temporal_filter_yuv_test.cc new file mode 100644 index 000000000..dc17aaaf7 --- /dev/null +++ b/media/libaom/src/test/temporal_filter_yuv_test.cc @@ -0,0 +1,841 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#include <ostream> + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +#include "config/av1_rtcd.h" +#include "test/acm_random.h" +#include "test/register_state_check.h" +#include "aom_ports/aom_timer.h" +#include "aom_ports/mem.h" + +namespace { + +using ::libaom_test::ACMRandom; + +const int MAX_WIDTH = 32; +const int MAX_HEIGHT = 32; + +typedef void (*TemporalFilterYUVFunc)( + const YV12_BUFFER_CONFIG *ref_frame, const MACROBLOCKD *mbd, + const BLOCK_SIZE block_size, const int mb_row, const int mb_col, + const int num_planes, const int strength, const int use_subblock, + const int *blk_fw, const uint8_t *pred, uint32_t *accum, uint16_t *count); + +struct TemporalFilterWithBd { + TemporalFilterWithBd(TemporalFilterYUVFunc func, int bitdepth) + : temporal_filter(func), bd(bitdepth) {} + + TemporalFilterYUVFunc temporal_filter; + int bd; +}; + +std::ostream &operator<<(std::ostream &os, const TemporalFilterWithBd &tf) { + return os << "Bitdepth: " << tf.bd; +} + +int GetFilterWeight(unsigned int row, unsigned int col, + unsigned int block_height, unsigned int block_width, + const int *const blk_fw, int use_32x32) { + if (use_32x32) { + return blk_fw[0]; + } + + return blk_fw[2 * (row >= block_height / 2) + (col >= block_width / 2)]; +} + +template <typename PixelType> +int GetModIndex(int sum_dist, int index, int rounding, int strength, + int filter_weight) { + int mod = sum_dist * 3 / index; + mod += rounding; + mod >>= strength; + + mod = AOMMIN(16, mod); + + mod = 16 - mod; + mod *= filter_weight; + + return mod; +} + +// Lowbitdepth version +template <> +int GetModIndex<uint8_t>(int sum_dist, int index, int rounding, int strength, + int filter_weight) { + unsigned int index_mult[14] = { 0, 0, 0, 0, 49152, + 39322, 32768, 28087, 24576, 21846, + 19661, 17874, 0, 15124 }; + + assert(index >= 0 && index <= 13); + assert(index_mult[index] != 0); + + int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16; + mod += rounding; + mod >>= strength; + + mod = AOMMIN(16, mod); + + mod = 16 - mod; + mod *= filter_weight; + + return mod; +} + +// Highbitdepth version +template <> +int GetModIndex<uint16_t>(int sum_dist, int index, int rounding, int strength, + int filter_weight) { + int64_t index_mult[14] = { 0U, 0U, 0U, 0U, + 3221225472U, 2576980378U, 2147483648U, 1840700270U, + 1610612736U, 1431655766U, 1288490189U, 1171354718U, + 0U, 991146300U }; + + assert(index >= 0 && index <= 13); + assert(index_mult[index] != 0); + + int mod = static_cast<int>((sum_dist * index_mult[index]) >> 32); + mod += rounding; + mod >>= strength; + + mod = AOMMIN(16, mod); + + mod = 16 - mod; + mod *= filter_weight; + + return mod; +} + +template <typename PixelType> +void SetArray(PixelType *pixel_array, int width, int height, int stride, + int val) { + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + pixel_array[col] = val; + } + pixel_array += stride; + } +} + +template <typename PixelType> +void SetArray(PixelType *pixel_array, int width, int height, int stride, + ACMRandom *rnd, int low_val, int high_val) { + EXPECT_LE(low_val, high_val); + + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + const int val = + static_cast<int>((*rnd).PseudoUniform(high_val - low_val)); + pixel_array[col] = low_val + val; + } + pixel_array += stride; + } +} + +template <typename ValueType> +bool CheckArrayEqual(const ValueType *arr_1, const ValueType *arr_2, int width, + int height, int stride_1, int stride_2) { + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + if (arr_1[col] != arr_2[col]) { + return false; + } + } + arr_1 += stride_1; + arr_2 += stride_2; + } + return true; +} + +template <typename ValueType> +void PrintArrayDiff(const ValueType *arr_1, const ValueType *arr_2, int width, + int height, int stride_1, int stride_2) { + const ValueType *arr_1_start = arr_1, *arr_2_start = arr_2; + + printf("Array 1:\n"); + for (int row = 0; row < height; ++row) { + for (int col = 0; col < width; ++col) { + if (arr_1[col] != arr_2[col]) { + printf("*%3d", arr_1[col]); + } else { + printf("%4d", arr_1[col]); + } + } + printf("\n"); + arr_1 += stride_1; + arr_2 += stride_2; + } + + arr_1 = arr_1_start; + arr_2 = arr_2_start; + + printf("Array 2:\n"); + for (int row = 0; row < height; ++row) { + for (int col = 0; col < width; ++col) { + if (arr_1[col] != arr_2[col]) { + printf("*%3d", arr_2[col]); + } else { + printf("%4d", arr_2[col]); + } + } + printf("\n"); + arr_1 += stride_1; + arr_2 += stride_2; + } + + arr_1 = arr_1_start; + arr_2 = arr_2_start; + printf("Difference:\n"); + for (int row = 0; row < height; ++row) { + for (int col = 0; col < width; ++col) { + printf("%4d", arr_1[col] - arr_2[col]); + } + printf("\n"); + arr_1 += stride_1; + arr_2 += stride_2; + } +} + +template <typename PixelType> +void ApplyReferenceFilter(const PixelType *y_src, const PixelType *y_pre, + const PixelType *u_src, const PixelType *v_src, + const PixelType *u_pre, const PixelType *v_pre, + unsigned int block_width, unsigned int block_height, + int ss_x, int ss_y, int strength, + const int *const blk_fw, int use_32x32, + uint32_t *y_accum, uint16_t *y_count, + uint32_t *u_accum, uint16_t *u_count, + uint32_t *v_accum, uint16_t *v_count) { + const int uv_block_width = block_width >> ss_x, + uv_block_height = block_height >> ss_y; + const int y_src_stride = block_width, y_pre_stride = block_width; + const int uv_src_stride = uv_block_width, uv_pre_stride = uv_block_width; + const int y_diff_stride = block_width, uv_diff_stride = uv_block_width; + const int y_count_stride = block_width, u_count_stride = uv_block_width, + v_count_stride = uv_block_width; + const int y_accum_stride = block_width, u_accum_stride = uv_block_width, + v_accum_stride = uv_block_width; + + int y_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + int u_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + int v_dif[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + + const int rounding = (1 << strength) >> 1; + + // Get the square diffs + for (int row = 0; row < (int)block_height; row++) { + for (int col = 0; col < (int)block_width; col++) { + const int diff = + y_src[row * y_src_stride + col] - y_pre[row * y_pre_stride + col]; + y_dif[row * y_diff_stride + col] = diff * diff; + } + } + + for (int row = 0; row < (int)uv_block_height; row++) { + for (int col = 0; col < (int)uv_block_width; col++) { + const int u_diff = + u_src[row * uv_src_stride + col] - u_pre[row * uv_pre_stride + col]; + const int v_diff = + v_src[row * uv_src_stride + col] - v_pre[row * uv_pre_stride + col]; + u_dif[row * uv_diff_stride + col] = u_diff * u_diff; + v_dif[row * uv_diff_stride + col] = v_diff * v_diff; + } + } + + // Apply the filter to luma + for (int row = 0; row < (int)block_height; row++) { + for (int col = 0; col < (int)block_width; col++) { + const int uv_row = row >> ss_y; + const int uv_col = col >> ss_x; + const int filter_weight = GetFilterWeight(row, col, block_height, + block_width, blk_fw, use_32x32); + + // First we get the modifier for the current y pixel + const int y_pixel = y_pre[row * y_pre_stride + col]; + int y_num_used = 0; + int y_mod = 0; + + // Sum the neighboring 3x3 y pixels + for (int row_step = -1; row_step <= 1; row_step++) { + for (int col_step = -1; col_step <= 1; col_step++) { + const int sub_row = row + row_step; + const int sub_col = col + col_step; + + if (sub_row >= 0 && sub_row < (int)block_height && sub_col >= 0 && + sub_col < (int)block_width) { + y_mod += y_dif[sub_row * y_diff_stride + sub_col]; + y_num_used++; + } + } + } + + // Sum the corresponding uv pixels to the current y modifier + // Note we are rounding down instead of rounding to the nearest pixel. + y_mod += u_dif[uv_row * uv_diff_stride + uv_col]; + y_mod += v_dif[uv_row * uv_diff_stride + uv_col]; + + y_num_used += 2; + + // Set the modifier + y_mod = GetModIndex<PixelType>(y_mod, y_num_used, rounding, strength, + filter_weight); + + // Accumulate the result + y_count[row * y_count_stride + col] += y_mod; + y_accum[row * y_accum_stride + col] += y_mod * y_pixel; + } + } + + // Apply the filter to chroma + for (int uv_row = 0; uv_row < (int)uv_block_height; uv_row++) { + for (int uv_col = 0; uv_col < (int)uv_block_width; uv_col++) { + const int y_row = uv_row << ss_y; + const int y_col = uv_col << ss_x; + const int filter_weight = GetFilterWeight( + uv_row, uv_col, uv_block_height, uv_block_width, blk_fw, use_32x32); + + const int u_pixel = u_pre[uv_row * uv_pre_stride + uv_col]; + const int v_pixel = v_pre[uv_row * uv_pre_stride + uv_col]; + + int uv_num_used = 0; + int u_mod = 0, v_mod = 0; + + // Sum the neighboring 3x3 chromal pixels to the chroma modifier + for (int row_step = -1; row_step <= 1; row_step++) { + for (int col_step = -1; col_step <= 1; col_step++) { + const int sub_row = uv_row + row_step; + const int sub_col = uv_col + col_step; + + if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 && + sub_col < uv_block_width) { + u_mod += u_dif[sub_row * uv_diff_stride + sub_col]; + v_mod += v_dif[sub_row * uv_diff_stride + sub_col]; + uv_num_used++; + } + } + } + + // Sum all the luma pixels associated with the current luma pixel + for (int row_step = 0; row_step < 1 + ss_y; row_step++) { + for (int col_step = 0; col_step < 1 + ss_x; col_step++) { + const int sub_row = y_row + row_step; + const int sub_col = y_col + col_step; + const int y_diff = y_dif[sub_row * y_diff_stride + sub_col]; + + u_mod += y_diff; + v_mod += y_diff; + uv_num_used++; + } + } + + // Set the modifier + u_mod = GetModIndex<PixelType>(u_mod, uv_num_used, rounding, strength, + filter_weight); + v_mod = GetModIndex<PixelType>(v_mod, uv_num_used, rounding, strength, + filter_weight); + + // Accumulate the result + u_count[uv_row * u_count_stride + uv_col] += u_mod; + u_accum[uv_row * u_accum_stride + uv_col] += u_mod * u_pixel; + v_count[uv_row * v_count_stride + uv_col] += v_mod; + v_accum[uv_row * v_accum_stride + uv_col] += v_mod * v_pixel; + } + } +} + +class TemporalFilterYUVTest + : public ::testing::TestWithParam<TemporalFilterWithBd> { + public: + virtual void SetUp() { + filter_func_ = GetParam().temporal_filter; + bd_ = GetParam().bd; + use_highbd_ = (bd_ != 8); + + rnd_.Reset(ACMRandom::DeterministicSeed()); + saturate_test_ = 0; + num_repeats_ = 10; + + ASSERT_TRUE(bd_ == 8 || bd_ == 10 || bd_ == 12); + } + + protected: + template <typename PixelType> + void CompareTestWithParam(int width, int height, int ss_x, int ss_y, + int filter_strength, int use_32x32, + const int *filter_weight); + template <typename PixelType> + void RunTestFilterWithParam(int width, int height, int ss_x, int ss_y, + int filter_strength, int use_32x32, + const int *filter_weight); + template <typename PixelType> + void ApplyTestFilter(const PixelType *y_src, int y_src_stride, + const PixelType *y_pre, int y_pre_stride, + const PixelType *u_src, const PixelType *v_src, + int uv_src_stride, const PixelType *u_pre, + const PixelType *v_pre, int uv_pre_stride, + unsigned int block_width, unsigned int block_height, + int ss_x, int ss_y, int strength, const int *blk_fw, + int use_32x32, uint32_t *y_accum, uint16_t *y_count, + uint32_t *u_accumu, uint16_t *u_count, uint32_t *v_accum, + uint16_t *v_count); + + TemporalFilterYUVFunc filter_func_; + ACMRandom rnd_; + int saturate_test_; + int num_repeats_; + int use_highbd_; + int bd_; +}; + +template <> +void TemporalFilterYUVTest::ApplyTestFilter<uint8_t>( + const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, + int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, + int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, + int uv_pre_stride, unsigned int block_width, unsigned int block_height, + int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32, + uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, uint16_t *u_count, + uint32_t *v_accum, uint16_t *v_count) { + (void)block_width; + (void)block_height; + (void)y_src_stride; + (void)uv_src_stride; + + assert(block_width == MAX_WIDTH && MAX_WIDTH == 32); + assert(block_height == MAX_HEIGHT && MAX_HEIGHT == 32); + const BLOCK_SIZE block_size = BLOCK_32X32; + const int num_planes = 3; + const int mb_pels = MAX_WIDTH * MAX_HEIGHT; + const int mb_row = 0; + const int mb_col = 0; + const int use_subblock = !(use_32x32); + + YV12_BUFFER_CONFIG *ref_frame = + (YV12_BUFFER_CONFIG *)malloc(sizeof(YV12_BUFFER_CONFIG)); + ref_frame->strides[0] = y_pre_stride; + ref_frame->strides[1] = uv_pre_stride; + const int alloc_size = MAX_MB_PLANE * mb_pels; + DECLARE_ALIGNED(16, uint8_t, src[alloc_size]); + ref_frame->buffer_alloc = src; + ref_frame->buffers[0] = ref_frame->buffer_alloc + 0 * mb_pels; + ref_frame->buffers[1] = ref_frame->buffer_alloc + 1 * mb_pels; + ref_frame->buffers[2] = ref_frame->buffer_alloc + 2 * mb_pels; + ref_frame->flags = bd_ > 8 ? YV12_FLAG_HIGHBITDEPTH : 0; + + MACROBLOCKD *mbd = (MACROBLOCKD *)malloc(sizeof(MACROBLOCKD)); + mbd->plane[0].subsampling_y = 0; + mbd->plane[0].subsampling_x = 0; + mbd->plane[1].subsampling_y = ss_y; + mbd->plane[1].subsampling_x = ss_x; + mbd->plane[2].subsampling_y = ss_y; + mbd->plane[2].subsampling_x = ss_x; + + DECLARE_ALIGNED(16, uint8_t, pred[alloc_size]); + DECLARE_ALIGNED(16, uint32_t, accum[alloc_size]); + DECLARE_ALIGNED(16, uint16_t, count[alloc_size]); + memcpy(src + 0 * mb_pels, y_src, mb_pels * sizeof(uint8_t)); + memcpy(src + 1 * mb_pels, u_src, mb_pels * sizeof(uint8_t)); + memcpy(src + 2 * mb_pels, v_src, mb_pels * sizeof(uint8_t)); + memcpy(pred + 0 * mb_pels, y_pre, mb_pels * sizeof(uint8_t)); + memcpy(pred + 1 * mb_pels, u_pre, mb_pels * sizeof(uint8_t)); + memcpy(pred + 2 * mb_pels, v_pre, mb_pels * sizeof(uint8_t)); + memcpy(accum + 0 * mb_pels, y_accum, mb_pels * sizeof(uint32_t)); + memcpy(accum + 1 * mb_pels, u_accum, mb_pels * sizeof(uint32_t)); + memcpy(accum + 2 * mb_pels, v_accum, mb_pels * sizeof(uint32_t)); + memcpy(count + 0 * mb_pels, y_count, mb_pels * sizeof(uint16_t)); + memcpy(count + 1 * mb_pels, u_count, mb_pels * sizeof(uint16_t)); + memcpy(count + 2 * mb_pels, v_count, mb_pels * sizeof(uint16_t)); + + ASM_REGISTER_STATE_CHECK( + filter_func_(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + strength, use_subblock, blk_fw, pred, accum, count)); + + memcpy(y_accum, accum + 0 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(u_accum, accum + 1 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(v_accum, accum + 2 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(y_count, count + 0 * mb_pels, mb_pels * sizeof(uint16_t)); + memcpy(u_count, count + 1 * mb_pels, mb_pels * sizeof(uint16_t)); + memcpy(v_count, count + 2 * mb_pels, mb_pels * sizeof(uint16_t)); + + free(ref_frame); + free(mbd); +} + +template <> +void TemporalFilterYUVTest::ApplyTestFilter<uint16_t>( + const uint16_t *y_src, int y_src_stride, const uint16_t *y_pre, + int y_pre_stride, const uint16_t *u_src, const uint16_t *v_src, + int uv_src_stride, const uint16_t *u_pre, const uint16_t *v_pre, + int uv_pre_stride, unsigned int block_width, unsigned int block_height, + int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32, + uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, uint16_t *u_count, + uint32_t *v_accum, uint16_t *v_count) { + (void)block_width; + (void)block_height; + (void)y_src_stride; + (void)uv_src_stride; + + assert(block_width == MAX_WIDTH && MAX_WIDTH == 32); + assert(block_height == MAX_HEIGHT && MAX_HEIGHT == 32); + const BLOCK_SIZE block_size = BLOCK_32X32; + const int num_planes = 3; + const int mb_pels = MAX_WIDTH * MAX_HEIGHT; + const int mb_row = 0; + const int mb_col = 0; + const int use_subblock = !(use_32x32); + + YV12_BUFFER_CONFIG *ref_frame = + (YV12_BUFFER_CONFIG *)malloc(sizeof(YV12_BUFFER_CONFIG)); + ref_frame->strides[0] = y_pre_stride; + ref_frame->strides[1] = uv_pre_stride; + const int alloc_size = MAX_MB_PLANE * mb_pels; + DECLARE_ALIGNED(16, uint16_t, src16[alloc_size]); + ref_frame->buffer_alloc = CONVERT_TO_BYTEPTR(src16); + ref_frame->buffers[0] = ref_frame->buffer_alloc + 0 * mb_pels; + ref_frame->buffers[1] = ref_frame->buffer_alloc + 1 * mb_pels; + ref_frame->buffers[2] = ref_frame->buffer_alloc + 2 * mb_pels; + ref_frame->flags = bd_ > 8 ? YV12_FLAG_HIGHBITDEPTH : 0; + + MACROBLOCKD *mbd = (MACROBLOCKD *)malloc(sizeof(MACROBLOCKD)); + mbd->plane[0].subsampling_y = 0; + mbd->plane[0].subsampling_x = 0; + mbd->plane[1].subsampling_y = ss_y; + mbd->plane[1].subsampling_x = ss_x; + mbd->plane[2].subsampling_y = ss_y; + mbd->plane[2].subsampling_x = ss_x; + + DECLARE_ALIGNED(16, uint16_t, pred16[alloc_size]); + DECLARE_ALIGNED(16, uint32_t, accum[alloc_size]); + DECLARE_ALIGNED(16, uint16_t, count[alloc_size]); + memcpy(src16 + 0 * mb_pels, y_src, mb_pels * sizeof(uint16_t)); + memcpy(src16 + 1 * mb_pels, u_src, mb_pels * sizeof(uint16_t)); + memcpy(src16 + 2 * mb_pels, v_src, mb_pels * sizeof(uint16_t)); + memcpy(pred16 + 0 * mb_pels, y_pre, mb_pels * sizeof(uint16_t)); + memcpy(pred16 + 1 * mb_pels, u_pre, mb_pels * sizeof(uint16_t)); + memcpy(pred16 + 2 * mb_pels, v_pre, mb_pels * sizeof(uint16_t)); + memcpy(accum + 0 * mb_pels, y_accum, mb_pels * sizeof(uint32_t)); + memcpy(accum + 1 * mb_pels, u_accum, mb_pels * sizeof(uint32_t)); + memcpy(accum + 2 * mb_pels, v_accum, mb_pels * sizeof(uint32_t)); + memcpy(count + 0 * mb_pels, y_count, mb_pels * sizeof(uint16_t)); + memcpy(count + 1 * mb_pels, u_count, mb_pels * sizeof(uint16_t)); + memcpy(count + 2 * mb_pels, v_count, mb_pels * sizeof(uint16_t)); + const uint8_t *pred = CONVERT_TO_BYTEPTR(pred16); + + ASM_REGISTER_STATE_CHECK( + filter_func_(ref_frame, mbd, block_size, mb_row, mb_col, num_planes, + strength, use_subblock, blk_fw, pred, accum, count)); + + memcpy(y_accum, accum + 0 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(u_accum, accum + 1 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(v_accum, accum + 2 * mb_pels, mb_pels * sizeof(uint32_t)); + memcpy(y_count, count + 0 * mb_pels, mb_pels * sizeof(uint16_t)); + memcpy(u_count, count + 1 * mb_pels, mb_pels * sizeof(uint16_t)); + memcpy(v_count, count + 2 * mb_pels, mb_pels * sizeof(uint16_t)); + + free(ref_frame); + free(mbd); +} + +template <typename PixelType> +void TemporalFilterYUVTest::CompareTestWithParam(int width, int height, + int ss_x, int ss_y, + int filter_strength, + int use_32x32, + const int *filter_weight) { + const int uv_width = width >> ss_x, uv_height = height >> ss_y; + const int y_stride = width, uv_stride = uv_width; + + DECLARE_ALIGNED(16, PixelType, y_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, PixelType, y_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, y_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, y_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, y_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, y_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + + DECLARE_ALIGNED(16, PixelType, u_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, PixelType, u_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, u_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, u_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, u_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, u_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + + DECLARE_ALIGNED(16, PixelType, v_src[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, PixelType, v_pre[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, v_count_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, v_accum_ref[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint16_t, v_count_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + DECLARE_ALIGNED(16, uint32_t, v_accum_tst[MAX_WIDTH * MAX_HEIGHT]) = { 0 }; + + for (int repeats = 0; repeats < num_repeats_; repeats++) { + if (saturate_test_) { + const int max_val = (1 << bd_) - 1; + SetArray(y_src, width, height, y_stride, max_val); + SetArray(y_pre, width, height, y_stride, 0); + SetArray(u_src, uv_width, uv_height, uv_stride, max_val); + SetArray(u_pre, uv_width, uv_height, uv_stride, 0); + SetArray(v_src, uv_width, uv_height, uv_stride, max_val); + SetArray(v_pre, uv_width, uv_height, uv_stride, 0); + } else { + const int max_val = 7 << (bd_ - 8); + SetArray(y_src, width, height, y_stride, &rnd_, 0, max_val); + SetArray(y_pre, width, height, y_stride, &rnd_, 0, max_val); + SetArray(u_src, uv_width, uv_height, uv_stride, &rnd_, 0, max_val); + SetArray(u_pre, uv_width, uv_height, uv_stride, &rnd_, 0, max_val); + SetArray(v_src, uv_width, uv_height, uv_stride, &rnd_, 0, max_val); + SetArray(v_pre, uv_width, uv_height, uv_stride, &rnd_, 0, max_val); + } + + ApplyReferenceFilter<PixelType>( + y_src, y_pre, u_src, v_src, u_pre, v_pre, width, height, ss_x, ss_y, + filter_strength, filter_weight, use_32x32, y_accum_ref, y_count_ref, + u_accum_ref, u_count_ref, v_accum_ref, v_count_ref); + + ApplyTestFilter(y_src, y_stride, y_pre, y_stride, u_src, v_src, uv_stride, + u_pre, v_pre, uv_stride, width, height, ss_x, ss_y, + filter_strength, filter_weight, use_32x32, y_accum_tst, + y_count_tst, u_accum_tst, u_count_tst, v_accum_tst, + v_count_tst); + + EXPECT_TRUE(CheckArrayEqual(y_accum_tst, y_accum_ref, width, height, + y_stride, y_stride)); + EXPECT_TRUE(CheckArrayEqual(y_count_tst, y_count_ref, width, height, + y_stride, y_stride)); + EXPECT_TRUE(CheckArrayEqual(u_accum_tst, u_accum_ref, uv_width, uv_height, + uv_stride, uv_stride)); + EXPECT_TRUE(CheckArrayEqual(u_count_tst, u_count_ref, uv_width, uv_height, + uv_stride, uv_stride)); + EXPECT_TRUE(CheckArrayEqual(v_accum_tst, v_accum_ref, uv_width, uv_height, + uv_stride, uv_stride)); + EXPECT_TRUE(CheckArrayEqual(v_count_tst, v_count_ref, uv_width, uv_height, + uv_stride, uv_stride)); + + if (HasFailure()) { + if (use_32x32) { + printf("SS_X: %d, SS_Y: %d, Strength: %d, Weight: %d\n", ss_x, ss_y, + filter_strength, *filter_weight); + } else { + printf("SS_X: %d, SS_Y: %d, Strength: %d, Weights: %d,%d,%d,%d\n", ss_x, + ss_y, filter_strength, filter_weight[0], filter_weight[1], + filter_weight[2], filter_weight[3]); + } + + PrintArrayDiff(y_accum_ref, y_accum_tst, width, height, y_stride, + y_stride); + PrintArrayDiff(y_count_ref, y_count_tst, width, height, y_stride, + y_stride); + PrintArrayDiff(u_accum_ref, v_accum_tst, uv_width, uv_height, uv_stride, + uv_stride); + PrintArrayDiff(u_count_ref, v_count_tst, uv_width, uv_height, uv_stride, + uv_stride); + PrintArrayDiff(u_accum_ref, v_accum_tst, uv_width, uv_height, uv_stride, + uv_stride); + PrintArrayDiff(u_count_ref, v_count_tst, uv_width, uv_height, uv_stride, + uv_stride); + + return; + } + } +} + +template <typename PixelType> +void TemporalFilterYUVTest::RunTestFilterWithParam(int width, int height, + int ss_x, int ss_y, + int filter_strength, + int use_32x32, + const int *filter_weight) { + PixelType y_src[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + PixelType y_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint16_t y_count[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint32_t y_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + + PixelType u_src[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + PixelType u_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint16_t u_count[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint32_t u_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + + PixelType v_src[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + PixelType v_pre[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint16_t v_count[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + uint32_t v_accum[MAX_WIDTH * MAX_HEIGHT] = { 0 }; + + SetArray(y_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + SetArray(y_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + SetArray(u_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + SetArray(u_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + SetArray(v_src, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + SetArray(v_pre, width, height, MAX_WIDTH, &rnd_, 0, 7 << (bd_ = 8)); + + for (int repeats = 0; repeats < num_repeats_; repeats++) { + ApplyTestFilter(y_src, MAX_WIDTH, y_pre, MAX_WIDTH, u_src, v_src, MAX_WIDTH, + u_pre, v_pre, MAX_WIDTH, width, height, ss_x, ss_y, + filter_strength, filter_weight, use_32x32, y_accum, y_count, + u_accum, u_count, v_accum, v_count); + } +} + +TEST_P(TemporalFilterYUVTest, Use32x32) { + const int width = 32, height = 32; + const int use_32x32 = 1; + + for (int ss_x = 0; ss_x <= 1; ss_x++) { + for (int ss_y = 0; ss_y <= 1; ss_y++) { + for (int filter_strength = 0; filter_strength <= 6; + filter_strength += 2) { + for (int filter_weight = 0; filter_weight <= 2; filter_weight++) { + if (use_highbd_) { + const int adjusted_strength = filter_strength + 2 * (bd_ - 8); + CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y, + adjusted_strength, use_32x32, + &filter_weight); + } else { + CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y, + filter_strength, use_32x32, + &filter_weight); + } + ASSERT_FALSE(HasFailure()); + } + } + } + } +} + +TEST_P(TemporalFilterYUVTest, Use16x16) { + const int width = 32, height = 32; + const int use_32x32 = 0; + + for (int ss_x = 0; ss_x <= 1; ss_x++) { + for (int ss_y = 0; ss_y <= 1; ss_y++) { + for (int filter_idx = 0; filter_idx < 3 * 3 * 3 * 3; filter_idx++) { + // Set up the filter + int filter_weight[4]; + int filter_idx_cp = filter_idx; + for (int idx = 0; idx < 4; idx++) { + filter_weight[idx] = filter_idx_cp % 3; + filter_idx_cp /= 3; + } + + // Test each parameter + for (int filter_strength = 0; filter_strength <= 6; + filter_strength += 2) { + if (use_highbd_) { + const int adjusted_strength = filter_strength + 2 * (bd_ - 8); + CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y, + adjusted_strength, use_32x32, + filter_weight); + } else { + CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y, + filter_strength, use_32x32, + filter_weight); + } + + ASSERT_FALSE(HasFailure()); + } + } + } + } +} + +TEST_P(TemporalFilterYUVTest, SaturationTest) { + const int width = 32, height = 32; + const int use_32x32 = 1; + const int filter_weight = 1; + saturate_test_ = 1; + + for (int ss_x = 0; ss_x <= 1; ss_x++) { + for (int ss_y = 0; ss_y <= 1; ss_y++) { + for (int filter_strength = 0; filter_strength <= 6; + filter_strength += 2) { + if (use_highbd_) { + const int adjusted_strength = filter_strength + 2 * (bd_ - 8); + CompareTestWithParam<uint16_t>(width, height, ss_x, ss_y, + adjusted_strength, use_32x32, + &filter_weight); + } else { + CompareTestWithParam<uint8_t>(width, height, ss_x, ss_y, + filter_strength, use_32x32, + &filter_weight); + } + + ASSERT_FALSE(HasFailure()); + } + } + } +} + +TEST_P(TemporalFilterYUVTest, DISABLED_Speed) { + const int width = 32, height = 32; + num_repeats_ = 1000; + + for (int use_32x32 = 0; use_32x32 <= 1; use_32x32++) { + const int num_filter_weights = use_32x32 ? 3 : 3 * 3 * 3 * 3; + for (int ss_x = 0; ss_x <= 1; ss_x++) { + for (int ss_y = 0; ss_y <= 1; ss_y++) { + for (int filter_idx = 0; filter_idx < num_filter_weights; + filter_idx++) { + // Set up the filter + int filter_weight[4]; + int filter_idx_cp = filter_idx; + for (int idx = 0; idx < 4; idx++) { + filter_weight[idx] = filter_idx_cp % 3; + filter_idx_cp /= 3; + } + + // Test each parameter + for (int filter_strength = 0; filter_strength <= 6; + filter_strength += 2) { + aom_usec_timer timer; + aom_usec_timer_start(&timer); + + if (use_highbd_) { + RunTestFilterWithParam<uint16_t>(width, height, ss_x, ss_y, + filter_strength, use_32x32, + filter_weight); + } else { + RunTestFilterWithParam<uint8_t>(width, height, ss_x, ss_y, + filter_strength, use_32x32, + filter_weight); + } + + aom_usec_timer_mark(&timer); + const int elapsed_time = + static_cast<int>(aom_usec_timer_elapsed(&timer)); + + printf( + "Bitdepth: %d, Use 32X32: %d, SS_X: %d, SS_Y: %d, Weight Idx: " + "%d, Strength: %d, Time: %5d\n", + bd_, use_32x32, ss_x, ss_y, filter_idx, filter_strength, + elapsed_time); + } + } + } + } + } +} + +INSTANTIATE_TEST_SUITE_P( + C, TemporalFilterYUVTest, + ::testing::Values( + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_c, 8), + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_c, 10), + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_c, 12))); + +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P( + SSE4_1, TemporalFilterYUVTest, + ::testing::Values( + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_sse4_1, 8), + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_sse4_1, 10), + TemporalFilterWithBd(&av1_apply_temporal_filter_yuv_sse4_1, 12))); +#endif // HAVE_SSE4_1 + +} // namespace diff --git a/media/libaom/src/test/test-data.sha1 b/media/libaom/src/test/test-data.sha1 index b6ee34701..383ae79c1 100644 --- a/media/libaom/src/test/test-data.sha1 +++ b/media/libaom/src/test/test-data.sha1 @@ -2,14 +2,47 @@ d5dfb0151c9051f8c85999255645d7a23916d3c0 *hantro_collage_w352h288.yuv b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv 26b7f64399b84db4b4c9c915d743ec5c2619d4b9 *invalid-bug-1814.ivf d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-bug-1814.ivf.res +09aa07e5325b3bb5462182eb30b8ecc914630740 *invalid-chromium-906381.ivf +09d2af8dd22201dd8d48e5dcfcaed281ff9422c7 *invalid-chromium-906381.ivf.res +f7c83c14aa35b928ba8b70f3eaa3b92070be4519 *invalid-google-142530197-1.ivf +d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-google-142530197-1.ivf.res +703c05720d5d67053bcee44987635cd78af2f971 *invalid-google-142530197.ivf +d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-google-142530197.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 +b2d0a29a65879436bf483d04865faca7d11cc2ee *invalid-oss-fuzz-10389.ivf +9655e6275888547ecd1f14e20e08ce4891372e76 *invalid-oss-fuzz-10389.ivf.res +e5fe0e8984c42d53d4ff734c3fbfd57d5c5c25cf *invalid-oss-fuzz-10389.ivf.res.2 +11df8e9a068669c678097d460b63609d3da73828 *invalid-oss-fuzz-10555.ivf +b055f06b9a95aaa5697fa26497b592a47843a7c8 *invalid-oss-fuzz-10555.ivf.res +cf5945085fe85456a1f74bf4cc7998b88b3f4b62 *invalid-oss-fuzz-10705.ivf +758671858368ffd2a2c0727898de5661f7cf7d68 *invalid-oss-fuzz-10705.ivf.res +88e29851122cca3f336824f7fa4d9f757f91110c *invalid-oss-fuzz-10723.ivf +1af486cd2cc83ebeddc76ca7a1c512cc0ec568d5 *invalid-oss-fuzz-10723.ivf.res +64f8a208dec7f1580fbe0371aa15e62bb1262715 *invalid-oss-fuzz-10723.ivf.res.2 +0784acc8931090ec24eba752d6c27e359e68fe7d *invalid-oss-fuzz-10779.ivf +5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-oss-fuzz-10779.ivf.res +7d37be9357f89a100ced694aee1ca5a6fad35ba9 *invalid-oss-fuzz-11477.ivf +15932651aacfc4622f0910f728f3f95e08e1753d *invalid-oss-fuzz-11477.ivf.res +1674787c38ddf82a2e5c804203f04f56a304e8e0 *invalid-oss-fuzz-11479.ivf +1af486cd2cc83ebeddc76ca7a1c512cc0ec568d5 *invalid-oss-fuzz-11479.ivf.res +64f8a208dec7f1580fbe0371aa15e62bb1262715 *invalid-oss-fuzz-11479.ivf.res.2 +b1a45514f0c59be03c9991cd04882426b9b930fa *invalid-oss-fuzz-11523.ivf +7c44ac1723c14d98bcb888fbf118c959511519ba *invalid-oss-fuzz-11523.ivf.res +3198c7af55a7d50173ce3c369c0cf2d9cdfface6 *invalid-oss-fuzz-11523.ivf.res.2 +cb445173be760c3554f1740ce4d119f57a7be043 *invalid-oss-fuzz-15363.ivf +d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-oss-fuzz-15363.ivf.res +5b697360bf0f02de31bae9b8da78e93570958fa4 *invalid-oss-fuzz-16437.ivf +09d2af8dd22201dd8d48e5dcfcaed281ff9422c7 *invalid-oss-fuzz-16437.ivf.res +ccbe4081557eb44820a0e6337c4a094421826b9a *invalid-oss-fuzz-9288.ivf +67c54283fe1a26ccf02cc991e4f9a1eea3ac5e78 *invalid-oss-fuzz-9288.ivf.res c0960f032484579f967881cc025b71cfd7a79ee1 *invalid-oss-fuzz-9463.ivf d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-oss-fuzz-9463.ivf.res +5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-oss-fuzz-9463.ivf.res.2 f448caf378e250b7eea4fa2d1c3cd7ef4a3211ce *invalid-oss-fuzz-9482.ivf b055f06b9a95aaa5697fa26497b592a47843a7c8 *invalid-oss-fuzz-9482.ivf.res a686989de79af89136f631fd630df639c7861851 *invalid-oss-fuzz-9720.ivf @@ -41,6 +74,7 @@ e7d315dbf4f3928779e0dc624311196d44491d32 *niklas_1280_720_30.yuv 9cfc855459e7549fd015c79e8eca512b2f2cb7e3 *niklas_1280_720_30.y4m 5b5763b388b1b52a81bb82b39f7ec25c4bd3d0e1 *desktop_credits.y4m 36ddab9b99eb7545aa0bf362d6f498212d596516 *vase10x10.yuv +c542890ac929749000f7b3883174f2202070d834 *pixel_capture_w320h240.yuv c2e1ec9936b95254187a359e94aa32a9f3dad1b7 *av1-1-b8-00-quantizer-00.ivf 26cd2a0321d01d9db5f6dace8b43a40cd5b9d58d *av1-1-b8-00-quantizer-00.ivf.md5 a56dd02c0258d4afea1ee358a22b54e99e39d5e1 *av1-1-b8-00-quantizer-01.ivf @@ -505,3 +539,21 @@ e69e41fee40b408b6eebcc79f266a95f2ee24f9e *av1-1-b8-03-sizedown.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 +caf8b6a5f1a5bcb38afae8a54a08c4f4459aafa3 *vase10x10_tiles.txt +e14825f50ff845b8a6932c64cb254007a0b5e3a1 *av1-1-b8-22-svc-L2T1.ivf +0f75f2ac44e61fc83be70c955410fa378e433237 *av1-1-b8-22-svc-L2T1.ivf.md5 +e94687eb0e90179b3800b6d5e11eb7e9bfb34eec *av1-1-b8-22-svc-L1T2.ivf +2bc12b16385ea14323bc79607fb8dfbd7edaf8ef *av1-1-b8-22-svc-L1T2.ivf.md5 +32ef2f14ee9cb11a24a22934f4c065e926e5d236 *av1-1-b8-22-svc-L2T2.ivf +f476a10ff06d750129f8229755d51e17ff141b2a *av1-1-b8-22-svc-L2T2.ivf.md5 +afca5502a489692b0a3c120370b0f43b8fc572a1 *av1-1-b8-04-cdfupdate.ivf +13b9423155a08d5e3a2fd9ae4a973bb046718cdf *av1-1-b8-04-cdfupdate.ivf.md5 +f064290d7fcd3b3de19020e8aec6c43c88d3a505 *av1-1-b8-05-mv.ivf +bff316e63ded5559116bdc2fa4aa97ad7b1a1761 *av1-1-b8-05-mv.ivf.md5 +b48a717c7c003b8dd23c3c2caed1ac673380fdb3 *av1-1-b8-06-mfmv.ivf +1424e3cb53e00eb56b94f4c725826274212c42b6 *av1-1-b8-06-mfmv.ivf.md5 +f8724ed96272ddbc35776908f2df7cb9955766a9 *paris_352_288_30.y4m +11bb40026103182c23a88133edafca369e5575e2 *av1-1-b8-23-film_grain-50.ivf +c58ccf7ff04711acc559c06f0bfce3c5b14800c3 *av1-1-b8-23-film_grain-50.ivf.md5 +2f883c7e11c21a31f79bd9c809541be90b0c7c4a *av1-1-b10-23-film_grain-50.ivf +83f2094fca597ad38b4fd623b807de1774c53ffb *av1-1-b10-23-film_grain-50.ivf.md5 diff --git a/media/libaom/src/test/test.cmake b/media/libaom/src/test/test.cmake index b16ae14c3..d4d3b298d 100644 --- a/media/libaom/src/test/test.cmake +++ b/media/libaom/src/test/test.cmake @@ -35,6 +35,7 @@ list(APPEND AOM_UNIT_TEST_COMMON_SOURCES "${AOM_ROOT}/test/function_equivalence_test.h" "${AOM_ROOT}/test/log2_test.cc" "${AOM_ROOT}/test/md5_helper.h" + "${AOM_ROOT}/test/metadata_test.cc" "${AOM_ROOT}/test/register_state_check.h" "${AOM_ROOT}/test/test_vectors.cc" "${AOM_ROOT}/test/test_vectors.h" @@ -60,14 +61,20 @@ list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES "${AOM_ROOT}/test/borders_test.cc" "${AOM_ROOT}/test/cpu_speed_test.cc" "${AOM_ROOT}/test/datarate_test.cc" + "${AOM_ROOT}/test/datarate_test.h" + "${AOM_ROOT}/test/svc_datarate_test.cc" "${AOM_ROOT}/test/encode_api_test.cc" "${AOM_ROOT}/test/encode_test_driver.cc" "${AOM_ROOT}/test/encode_test_driver.h" "${AOM_ROOT}/test/end_to_end_test.cc" + "${AOM_ROOT}/test/fwd_kf_test.cc" + "${AOM_ROOT}/test/gf_pyr_height_test.cc" + "${AOM_ROOT}/test/rt_end_to_end_test.cc" "${AOM_ROOT}/test/error_resilience_test.cc" "${AOM_ROOT}/test/frame_size_tests.cc" "${AOM_ROOT}/test/horz_superres_test.cc" "${AOM_ROOT}/test/i420_video_source.h" + "${AOM_ROOT}/test/level_test.cc" "${AOM_ROOT}/test/lossless_test.cc" "${AOM_ROOT}/test/monochrome_test.cc" "${AOM_ROOT}/test/qm_test.cc" @@ -75,7 +82,8 @@ list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES "${AOM_ROOT}/test/scalability_test.cc" "${AOM_ROOT}/test/y4m_test.cc" "${AOM_ROOT}/test/y4m_video_source.h" - "${AOM_ROOT}/test/yuv_video_source.h") + "${AOM_ROOT}/test/yuv_video_source.h" + "${AOM_ROOT}/test/time_stamp_test.cc") 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") @@ -85,6 +93,7 @@ list(APPEND AOM_TEST_INTRA_PRED_SPEED_SOURCES "${AOM_GEN_SRC_DIR}/usage_exit.c" if(NOT BUILD_SHARED_LIBS) list(APPEND AOM_UNIT_TEST_COMMON_SOURCES + "${AOM_ROOT}/test/av1_common_int_test.cc" "${AOM_ROOT}/test/cdef_test.cc" "${AOM_ROOT}/test/cfl_test.cc" "${AOM_ROOT}/test/convolve_test.cc" @@ -94,7 +103,6 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/intrabc_test.cc" "${AOM_ROOT}/test/intrapred_test.cc" "${AOM_ROOT}/test/lpf_test.cc" - "${AOM_ROOT}/test/onyxc_int_test.cc" "${AOM_ROOT}/test/scan_test.cc" "${AOM_ROOT}/test/selfguided_filter_test.cc" "${AOM_ROOT}/test/simd_cmp_impl.h" @@ -111,6 +119,7 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/av1_ext_tile_test.cc" "${AOM_ROOT}/test/binary_codes_test.cc" "${AOM_ROOT}/test/boolcoder_test.cc" + "${AOM_ROOT}/test/cnn_test.cc" "${AOM_ROOT}/test/coding_path_sync.cc" "${AOM_ROOT}/test/decode_multithreaded_test.cc" "${AOM_ROOT}/test/divu_small_test.cc" @@ -118,9 +127,21 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/ec_test.cc" "${AOM_ROOT}/test/ethread_test.cc" "${AOM_ROOT}/test/film_grain_table_test.cc" + "${AOM_ROOT}/test/sb_multipass_test.cc" "${AOM_ROOT}/test/segment_binarization_sync.cc" "${AOM_ROOT}/test/superframe_test.cc" - "${AOM_ROOT}/test/tile_independence_test.cc") + "${AOM_ROOT}/test/tile_independence_test.cc" + "${AOM_ROOT}/test/temporal_filter_planewise_test.cc" + "${AOM_ROOT}/test/temporal_filter_yuv_test.cc") + if(CONFIG_REALTIME_ONLY) + list(REMOVE_ITEM AOM_UNIT_TEST_COMMON_SOURCES + "${AOM_ROOT}/test/cnn_test.cc" + "${AOM_ROOT}/test/temporal_filter_yuv_test.cc") + endif() + if(NOT CONFIG_AV1_HIGHBITDEPTH) + list(REMOVE_ITEM AOM_UNIT_TEST_COMMON_SOURCES + "${AOM_ROOT}/test/coding_path_sync.cc") + endif() endif() list(APPEND AOM_UNIT_TEST_COMMON_INTRIN_NEON @@ -170,19 +191,25 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/av1_fwd_txfm2d_test.cc" "${AOM_ROOT}/test/av1_inv_txfm1d_test.cc" "${AOM_ROOT}/test/av1_inv_txfm2d_test.cc" + "${AOM_ROOT}/test/av1_nn_predict_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/avg_test.cc" "${AOM_ROOT}/test/blend_a64_mask_1d_test.cc" "${AOM_ROOT}/test/blend_a64_mask_test.cc" "${AOM_ROOT}/test/comp_avg_pred_test.cc" "${AOM_ROOT}/test/comp_avg_pred_test.h" "${AOM_ROOT}/test/comp_mask_variance_test.cc" + "${AOM_ROOT}/test/edge_detect_test.cc" "${AOM_ROOT}/test/encodetxb_test.cc" "${AOM_ROOT}/test/error_block_test.cc" "${AOM_ROOT}/test/fft_test.cc" "${AOM_ROOT}/test/fwht4x4_test.cc" + "${AOM_ROOT}/test/fdct4x4_test.cc" + "${AOM_ROOT}/test/hadamard_test.cc" + "${AOM_ROOT}/test/horver_correlation_test.cc" "${AOM_ROOT}/test/masked_sad_test.cc" "${AOM_ROOT}/test/masked_variance_test.cc" "${AOM_ROOT}/test/motion_vector_test.cc" @@ -190,12 +217,14 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/obmc_sad_test.cc" "${AOM_ROOT}/test/obmc_variance_test.cc" "${AOM_ROOT}/test/pickrst_test.cc" + "${AOM_ROOT}/test/quantize_func_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/wiener_test.cc" + "${AOM_ROOT}/test/frame_error_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") @@ -204,9 +233,18 @@ if(NOT BUILD_SHARED_LIBS) "${AOM_ROOT}/test/av1_highbd_iht_test.cc" "${AOM_ROOT}/test/av1_quantize_test.cc" "${AOM_ROOT}/test/corner_match_test.cc" - "${AOM_ROOT}/test/quantize_func_test.cc" "${AOM_ROOT}/test/simd_cmp_sse4.cc") + if(NOT CONFIG_AV1_HIGHBITDEPTH) + list(REMOVE_ITEM AOM_UNIT_TEST_ENCODER_INTRIN_SSE4_1 + "${AOM_ROOT}/test/av1_quantize_test.cc") + endif() + + if(NOT (HAVE_SSE2 OR HAVE_NEON)) + list(REMOVE_ITEM AOM_UNIT_TEST_ENCODER_SOURCES + "${AOM_ROOT}/test/quantize_func_test.cc") + endif() + if(HAVE_SSE4_1) list(APPEND AOM_UNIT_TEST_ENCODER_SOURCES "${AOM_ROOT}/test/av1_convolve_scale_test.cc" @@ -224,17 +262,10 @@ endif() if(ENABLE_TESTS) find_package(PythonInterp) if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR - "--- Unit tests require Python, rerun cmake with " - "-DENABLE_TESTS=0 to avoid this error, or install Python and " - "make sure it's in your PATH.") - endif() - - 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() + message( + FATAL_ERROR "--- Unit tests require Python, rerun cmake with " + "-DENABLE_TESTS=0 to avoid this error, or install Python and " + "make sure it's in your PATH.") endif() if(BUILD_SHARED_LIBS AND APPLE) # Silence an RPATH warning. @@ -244,15 +275,16 @@ if(ENABLE_TESTS) include_directories( "${AOM_ROOT}/third_party/googletest/src/googletest/include") - if(AOM_DISABLE_GTEST_CMAKE) - include_directories("${AOM_ROOT}/third_party/googletest/src/googletest") - add_library( - gtest - STATIC - "${AOM_ROOT}/third_party/googletest/src/googletest/src/gtest-all.cc") + include_directories("${AOM_ROOT}/third_party/googletest/src/googletest") + add_library( + aom_gtest STATIC + "${AOM_ROOT}/third_party/googletest/src/googletest/src/gtest-all.cc") + if(MSVC OR WIN32) + target_compile_definitions(aom_gtest PRIVATE GTEST_OS_WINDOWS=1) + elseif(CONFIG_MULTITHREAD AND CMAKE_USE_PTHREADS_INIT) + target_compile_definitions(aom_gtest PRIVATE GTEST_HAS_PTHREAD=1) else() - add_subdirectory("${AOM_ROOT}/third_party/googletest/src/googletest" - EXCLUDE_FROM_ALL) + target_compile_definitions(aom_gtest PRIVATE GTEST_HAS_PTHREAD=0) endif() endif() @@ -279,8 +311,8 @@ function(setup_aom_test_targets) endif() add_executable(test_libaom ${AOM_UNIT_TEST_WRAPPER_SOURCES} - $<TARGET_OBJECTS:aom_common_app_util> - $<TARGET_OBJECTS:test_aom_common>) + $<TARGET_OBJECTS:aom_common_app_util> + $<TARGET_OBJECTS:test_aom_common>) list(APPEND AOM_APP_TARGETS test_libaom) if(CONFIG_AV1_DECODER) @@ -301,15 +333,16 @@ function(setup_aom_test_targets) endif() if(NOT BUILD_SHARED_LIBS) - add_executable(test_intra_pred_speed ${AOM_TEST_INTRA_PRED_SPEED_SOURCES} + add_executable(test_intra_pred_speed + ${AOM_TEST_INTRA_PRED_SPEED_SOURCES} $<TARGET_OBJECTS:aom_common_app_util>) target_link_libraries(test_intra_pred_speed ${AOM_LIB_LINK_TYPE} aom - gtest) + aom_gtest) list(APPEND AOM_APP_TARGETS test_intra_pred_speed) endif() endif() - target_link_libraries(test_libaom ${AOM_LIB_LINK_TYPE} aom gtest) + target_link_libraries(test_libaom ${AOM_LIB_LINK_TYPE} aom aom_gtest) if(CONFIG_LIBYUV) target_sources(test_libaom PRIVATE $<TARGET_OBJECTS:yuv>) @@ -354,13 +387,13 @@ function(setup_aom_test_targets) foreach(test_index RANGE ${max_file_index}) list(GET test_files ${test_index} test_file) list(GET test_file_checksums ${test_index} test_file_checksum) - add_custom_target(testdata_${test_index} - COMMAND - ${CMAKE_COMMAND} -DAOM_CONFIG_DIR="${AOM_CONFIG_DIR}" - -DAOM_ROOT="${AOM_ROOT}" - -DAOM_TEST_FILE="${test_file}" - -DAOM_TEST_CHECKSUM=${test_file_checksum} -P - "${AOM_ROOT}/test/test_data_download_worker.cmake") + add_custom_target( + testdata_${test_index} + COMMAND ${CMAKE_COMMAND} + -DAOM_CONFIG_DIR="${AOM_CONFIG_DIR}" -DAOM_ROOT="${AOM_ROOT}" + -DAOM_TEST_FILE="${test_file}" + -DAOM_TEST_CHECKSUM=${test_file_checksum} -P + "${AOM_ROOT}/test/test_data_download_worker.cmake") list(APPEND testdata_targets testdata_${test_index}) endforeach() @@ -404,7 +437,7 @@ function(setup_aom_test_targets) foreach(var ${all_cmake_vars}) # https://github.com/cheshirekow/cmake_format/issues/34 -# cmake-format: off + # cmake-format: off if (("${var}" MATCHES "_TEST_" AND NOT "${var}" MATCHES "_DATA_\|_CMAKE_\|INTRA_PRED\|_COMPILED\|_HOSTING\|_PERF_\|CODER_") @@ -422,7 +455,7 @@ function(setup_aom_test_targets) # Libaom_test_srcs.txt generation. set(libaom_test_srcs_txt_file "${AOM_CONFIG_DIR}/libaom_test_srcs.txt") file(WRITE "${libaom_test_srcs_txt_file}" - "# This file is generated. DO NOT EDIT.\n") + "# This file is generated. DO NOT EDIT.\n") # Static source file list first. foreach(aom_test_source_var ${aom_test_source_vars}) diff --git a/media/libaom/src/test/test_data_download_worker.cmake b/media/libaom/src/test/test_data_download_worker.cmake index dc803497d..a49038888 100644 --- a/media/libaom/src/test/test_data_download_worker.cmake +++ b/media/libaom/src/test/test_data_download_worker.cmake @@ -20,15 +20,15 @@ if (NOT AOM_ROOT OR NOT AOM_CONFIG_DIR OR NOT AOM_TEST_FILE endif () # cmake-format: on -set(AOM_TEST_DATA_URL "http://storage.googleapis.com/aom-test-data") +set(AOM_TEST_DATA_URL "https://storage.googleapis.com/aom-test-data") if(NOT AOM_TEST_DATA_PATH) set(AOM_TEST_DATA_PATH "$ENV{LIBAOM_TEST_DATA_PATH}") endif() if("${AOM_TEST_DATA_PATH}" STREQUAL "") - message(WARNING - "Writing test data to ${AOM_CONFIG_DIR}, set " + message( + WARNING "Writing test data to ${AOM_CONFIG_DIR}, set " "$LIBAOM_TEST_DATA_PATH in your environment to avoid this warning.") set(AOM_TEST_DATA_PATH "${AOM_CONFIG_DIR}") endif() diff --git a/media/libaom/src/test/test_data_util.cmake b/media/libaom/src/test/test_data_util.cmake index 45c951478..050600e13 100644 --- a/media/libaom/src/test/test_data_util.cmake +++ b/media/libaom/src/test/test_data_util.cmake @@ -12,20 +12,7 @@ list(APPEND AOM_TEST_DATA_FILE_NAMES "hantro_collage_w352h288.yuv" "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" + "paris_352_288_30.y4m" "park_joy_90p_10_420.y4m" "park_joy_90p_10_422.y4m" "park_joy_90p_10_444.y4m" @@ -38,12 +25,14 @@ list(APPEND AOM_TEST_DATA_FILE_NAMES "park_joy_90p_8_420_vertical_csp.y4m" "park_joy_90p_8_422.y4m" "park_joy_90p_8_444.y4m" + "pixel_capture_w320h240.yuv" "desktop_credits.y4m" "niklas_1280_720_30.y4m" "rush_hour_444.y4m" "screendata.y4m" "niklas_640_480_30.yuv" - "vase10x10.yuv") + "vase10x10.yuv" + "vase10x10_tiles.txt") if(ENABLE_DECODE_PERF_TESTS AND CONFIG_AV1_ENCODER) list(APPEND AOM_TEST_DATA_FILE_NAMES "niklas_1280_720_30.yuv") @@ -307,6 +296,8 @@ if(CONFIG_AV1_DECODER) "av1-1-b10-00-quantizer-62.ivf.md5" "av1-1-b10-00-quantizer-63.ivf" "av1-1-b10-00-quantizer-63.ivf.md5" + "av1-1-b10-23-film_grain-50.ivf" + "av1-1-b10-23-film_grain-50.ivf.md5" "av1-1-b8-01-size-16x16.ivf" "av1-1-b8-01-size-16x16.ivf.md5" "av1-1-b8-01-size-16x18.ivf" @@ -512,7 +503,68 @@ if(CONFIG_AV1_DECODER) "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") + "av1-1-b8-03-sizedown.mkv.md5" + "av1-1-b8-04-cdfupdate.ivf" + "av1-1-b8-04-cdfupdate.ivf.md5" + "av1-1-b8-05-mv.ivf" + "av1-1-b8-05-mv.ivf.md5" + "av1-1-b8-06-mfmv.ivf" + "av1-1-b8-06-mfmv.ivf.md5" + "av1-1-b8-22-svc-L2T1.ivf" + "av1-1-b8-22-svc-L2T1.ivf.md5" + "av1-1-b8-22-svc-L1T2.ivf" + "av1-1-b8-22-svc-L1T2.ivf.md5" + "av1-1-b8-22-svc-L2T2.ivf" + "av1-1-b8-22-svc-L2T2.ivf.md5" + "av1-1-b8-23-film_grain-50.ivf" + "av1-1-b8-23-film_grain-50.ivf.md5" + "invalid-bug-1814.ivf" + "invalid-bug-1814.ivf.res" + "invalid-chromium-906381.ivf" + "invalid-chromium-906381.ivf.res" + "invalid-google-142530197-1.ivf" + "invalid-google-142530197-1.ivf.res" + "invalid-google-142530197.ivf" + "invalid-google-142530197.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-10389.ivf" + "invalid-oss-fuzz-10389.ivf.res" + "invalid-oss-fuzz-10389.ivf.res.2" + "invalid-oss-fuzz-10555.ivf" + "invalid-oss-fuzz-10555.ivf.res" + "invalid-oss-fuzz-10705.ivf" + "invalid-oss-fuzz-10705.ivf.res" + "invalid-oss-fuzz-10723.ivf" + "invalid-oss-fuzz-10723.ivf.res" + "invalid-oss-fuzz-10723.ivf.res.2" + "invalid-oss-fuzz-10779.ivf" + "invalid-oss-fuzz-10779.ivf.res" + "invalid-oss-fuzz-11477.ivf" + "invalid-oss-fuzz-11477.ivf.res" + "invalid-oss-fuzz-11479.ivf" + "invalid-oss-fuzz-11479.ivf.res" + "invalid-oss-fuzz-11479.ivf.res.2" + "invalid-oss-fuzz-11523.ivf" + "invalid-oss-fuzz-11523.ivf.res" + "invalid-oss-fuzz-11523.ivf.res.2" + "invalid-oss-fuzz-15363.ivf" + "invalid-oss-fuzz-15363.ivf.res" + "invalid-oss-fuzz-16437.ivf" + "invalid-oss-fuzz-16437.ivf.res" + "invalid-oss-fuzz-9288.ivf" + "invalid-oss-fuzz-9288.ivf.res" + "invalid-oss-fuzz-9463.ivf" + "invalid-oss-fuzz-9463.ivf.res" + "invalid-oss-fuzz-9463.ivf.res.2" + "invalid-oss-fuzz-9482.ivf" + "invalid-oss-fuzz-9482.ivf.res" + "invalid-oss-fuzz-9720.ivf" + "invalid-oss-fuzz-9720.ivf.res") endif() if(ENABLE_ENCODE_PERF_TESTS AND CONFIG_AV1_ENCODER) @@ -592,7 +644,7 @@ endfunction() # writes it to $local_path. function(download_test_file file_url file_checksum local_path) message("Downloading ${file_url} ...") - file(DOWNLOAD "${file_url}" "${local_path}" SHOW_PROGRESS - EXPECTED_HASH SHA1=${file_checksum}) + file(DOWNLOAD "${file_url}" "${local_path}" SHOW_PROGRESS EXPECTED_HASH + SHA1=${file_checksum}) message("Download of ${file_url} complete.") endfunction() diff --git a/media/libaom/src/test/test_intra_pred_speed.cc b/media/libaom/src/test/test_intra_pred_speed.cc index b72ac1167..25c50d022 100644 --- a/media/libaom/src/test/test_intra_pred_speed.cc +++ b/media/libaom/src/test/test_intra_pred_speed.cc @@ -878,6 +878,8 @@ INTRA_PRED_TEST(AVX2_6, TX_64X16, aom_dc_predictor_64x16_avx2, aom_dc_128_predictor_64x16_avx2, aom_v_predictor_64x16_avx2, NULL, aom_paeth_predictor_64x16_avx2, NULL, NULL, NULL) #endif + +#if CONFIG_AV1_HIGHBITDEPTH // ----------------------------------------------------------------------------- // High Bitdepth namespace { @@ -1460,5 +1462,6 @@ HIGHBD_INTRA_PRED_TEST( aom_highbd_smooth_h_predictor_64x16_c) // ----------------------------------------------------------------------------- +#endif // CONFIG_AV1_HIGHBITDEPTH #include "test/test_libaom.cc" diff --git a/media/libaom/src/test/test_runner.cmake b/media/libaom/src/test/test_runner.cmake index d3747b1e3..f0648d16b 100644 --- a/media/libaom/src/test/test_runner.cmake +++ b/media/libaom/src/test/test_runner.cmake @@ -8,13 +8,13 @@ # License 1.0 was not distributed with this source code in the PATENTS file, you # can obtain it at www.aomedia.org/license/patent. # -if(NOT GTEST_TOTAL_SHARDS OR "${GTEST_SHARD_INDEX}" STREQUAL "" OR NOT - TEST_LIBAOM) +if(NOT GTEST_TOTAL_SHARDS + OR "${GTEST_SHARD_INDEX}" STREQUAL "" + OR NOT TEST_LIBAOM) message( FATAL_ERROR "The variables GTEST_SHARD_INDEX, GTEST_TOTAL_SHARDS and TEST_LIBAOM - must be defined." - ) + must be defined.") endif() set($ENV{GTEST_SHARD_INDEX} ${GTEST_SHARD_INDEX}) diff --git a/media/libaom/src/test/test_vector_test.cc b/media/libaom/src/test/test_vector_test.cc index 286988b17..eab92b685 100644 --- a/media/libaom/src/test/test_vector_test.cc +++ b/media/libaom/src/test/test_vector_test.cc @@ -11,8 +11,10 @@ #include <cstdio> #include <cstdlib> +#include <memory> #include <set> #include <string> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "common/tools_common.h" #include "config/aom_config.h" @@ -32,7 +34,7 @@ const int kThreads = 0; const int kFileName = 1; const int kRowMT = 2; -typedef ::testing::tuple<int, const char *, int> DecodeParam; +typedef std::tuple<int, const char *, int> DecodeParam; class TestVectorTest : public ::libaom_test::DecoderTest, public ::libaom_test::CodecTestWithParam<DecodeParam> { @@ -67,7 +69,7 @@ class TestVectorTest : public ::libaom_test::DecoderTest, expected_md5[32] = '\0'; ::libaom_test::MD5 md5_res; -#if !CONFIG_LOWBITDEPTH +#if FORCE_HIGHBITDEPTH_DECODING const aom_img_fmt_t shifted_fmt = (aom_img_fmt)(img.fmt & ~AOM_IMG_FMT_HIGHBITDEPTH); if (img.bit_depth == 8 && shifted_fmt != img.fmt) { @@ -81,7 +83,7 @@ class TestVectorTest : public ::libaom_test::DecoderTest, } else { #endif md5_res.Add(&img); -#if !CONFIG_LOWBITDEPTH +#if FORCE_HIGHBITDEPTH_DECODING } #endif @@ -103,20 +105,20 @@ class TestVectorTest : public ::libaom_test::DecoderTest, // the test failed. TEST_P(TestVectorTest, MD5Match) { const DecodeParam input = GET_PARAM(1); - const std::string filename = ::testing::get<kFileName>(input); + const std::string filename = std::get<kFileName>(input); aom_codec_flags_t flags = 0; aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t(); char str[256]; - cfg.threads = ::testing::get<kThreads>(input); - row_mt_ = ::testing::get<kRowMT>(input); + cfg.threads = std::get<kThreads>(input); + row_mt_ = std::get<kRowMT>(input); snprintf(str, sizeof(str) / sizeof(str[0]) - 1, "file: %s threads: %d", filename.c_str(), cfg.threads); SCOPED_TRACE(str); // Open compressed video file. - testing::internal::scoped_ptr<libaom_test::CompressedVideoSource> video; + std::unique_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" || @@ -137,7 +139,7 @@ TEST_P(TestVectorTest, MD5Match) { OpenMD5File(md5_filename); // Set decode config and flags. - cfg.allow_lowbitdepth = CONFIG_LOWBITDEPTH; + cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING; set_cfg(cfg); set_flags(flags); @@ -155,7 +157,7 @@ AV1_INSTANTIATE_TEST_CASE( ::testing::Values(0))); // Test AV1 decode in with different numbers of threads. -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AV1MultiThreaded, TestVectorTest, ::testing::Combine( ::testing::Values( diff --git a/media/libaom/src/test/test_vectors.cc b/media/libaom/src/test/test_vectors.cc index 71e431e18..991667a08 100644 --- a/media/libaom/src/test/test_vectors.cc +++ b/media/libaom/src/test/test_vectors.cc @@ -16,124 +16,247 @@ namespace libaom_test { #define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0])) #if CONFIG_AV1_DECODER -const char *const kAV1TestVectors[] = { - "av1-1-b8-00-quantizer-00.ivf", "av1-1-b8-00-quantizer-01.ivf", - "av1-1-b8-00-quantizer-02.ivf", "av1-1-b8-00-quantizer-03.ivf", - "av1-1-b8-00-quantizer-04.ivf", "av1-1-b8-00-quantizer-05.ivf", - "av1-1-b8-00-quantizer-06.ivf", "av1-1-b8-00-quantizer-07.ivf", - "av1-1-b8-00-quantizer-08.ivf", "av1-1-b8-00-quantizer-09.ivf", - "av1-1-b8-00-quantizer-10.ivf", "av1-1-b8-00-quantizer-11.ivf", - "av1-1-b8-00-quantizer-12.ivf", "av1-1-b8-00-quantizer-13.ivf", - "av1-1-b8-00-quantizer-14.ivf", "av1-1-b8-00-quantizer-15.ivf", - "av1-1-b8-00-quantizer-16.ivf", "av1-1-b8-00-quantizer-17.ivf", - "av1-1-b8-00-quantizer-18.ivf", "av1-1-b8-00-quantizer-19.ivf", - "av1-1-b8-00-quantizer-20.ivf", "av1-1-b8-00-quantizer-21.ivf", - "av1-1-b8-00-quantizer-22.ivf", "av1-1-b8-00-quantizer-23.ivf", - "av1-1-b8-00-quantizer-24.ivf", "av1-1-b8-00-quantizer-25.ivf", - "av1-1-b8-00-quantizer-26.ivf", "av1-1-b8-00-quantizer-27.ivf", - "av1-1-b8-00-quantizer-28.ivf", "av1-1-b8-00-quantizer-29.ivf", - "av1-1-b8-00-quantizer-30.ivf", "av1-1-b8-00-quantizer-31.ivf", - "av1-1-b8-00-quantizer-32.ivf", "av1-1-b8-00-quantizer-33.ivf", - "av1-1-b8-00-quantizer-34.ivf", "av1-1-b8-00-quantizer-35.ivf", - "av1-1-b8-00-quantizer-36.ivf", "av1-1-b8-00-quantizer-37.ivf", - "av1-1-b8-00-quantizer-38.ivf", "av1-1-b8-00-quantizer-39.ivf", - "av1-1-b8-00-quantizer-40.ivf", "av1-1-b8-00-quantizer-41.ivf", - "av1-1-b8-00-quantizer-42.ivf", "av1-1-b8-00-quantizer-43.ivf", - "av1-1-b8-00-quantizer-44.ivf", "av1-1-b8-00-quantizer-45.ivf", - "av1-1-b8-00-quantizer-46.ivf", "av1-1-b8-00-quantizer-47.ivf", - "av1-1-b8-00-quantizer-48.ivf", "av1-1-b8-00-quantizer-49.ivf", - "av1-1-b8-00-quantizer-50.ivf", "av1-1-b8-00-quantizer-51.ivf", - "av1-1-b8-00-quantizer-52.ivf", "av1-1-b8-00-quantizer-53.ivf", - "av1-1-b8-00-quantizer-54.ivf", "av1-1-b8-00-quantizer-55.ivf", - "av1-1-b8-00-quantizer-56.ivf", "av1-1-b8-00-quantizer-57.ivf", - "av1-1-b8-00-quantizer-58.ivf", "av1-1-b8-00-quantizer-59.ivf", - "av1-1-b8-00-quantizer-60.ivf", "av1-1-b8-00-quantizer-61.ivf", - "av1-1-b8-00-quantizer-62.ivf", "av1-1-b8-00-quantizer-63.ivf", - "av1-1-b10-00-quantizer-00.ivf", "av1-1-b10-00-quantizer-01.ivf", - "av1-1-b10-00-quantizer-02.ivf", "av1-1-b10-00-quantizer-03.ivf", - "av1-1-b10-00-quantizer-04.ivf", "av1-1-b10-00-quantizer-05.ivf", - "av1-1-b10-00-quantizer-06.ivf", "av1-1-b10-00-quantizer-07.ivf", - "av1-1-b10-00-quantizer-08.ivf", "av1-1-b10-00-quantizer-09.ivf", - "av1-1-b10-00-quantizer-10.ivf", "av1-1-b10-00-quantizer-11.ivf", - "av1-1-b10-00-quantizer-12.ivf", "av1-1-b10-00-quantizer-13.ivf", - "av1-1-b10-00-quantizer-14.ivf", "av1-1-b10-00-quantizer-15.ivf", - "av1-1-b10-00-quantizer-16.ivf", "av1-1-b10-00-quantizer-17.ivf", - "av1-1-b10-00-quantizer-18.ivf", "av1-1-b10-00-quantizer-19.ivf", - "av1-1-b10-00-quantizer-20.ivf", "av1-1-b10-00-quantizer-21.ivf", - "av1-1-b10-00-quantizer-22.ivf", "av1-1-b10-00-quantizer-23.ivf", - "av1-1-b10-00-quantizer-24.ivf", "av1-1-b10-00-quantizer-25.ivf", - "av1-1-b10-00-quantizer-26.ivf", "av1-1-b10-00-quantizer-27.ivf", - "av1-1-b10-00-quantizer-28.ivf", "av1-1-b10-00-quantizer-29.ivf", - "av1-1-b10-00-quantizer-30.ivf", "av1-1-b10-00-quantizer-31.ivf", - "av1-1-b10-00-quantizer-32.ivf", "av1-1-b10-00-quantizer-33.ivf", - "av1-1-b10-00-quantizer-34.ivf", "av1-1-b10-00-quantizer-35.ivf", - "av1-1-b10-00-quantizer-36.ivf", "av1-1-b10-00-quantizer-37.ivf", - "av1-1-b10-00-quantizer-38.ivf", "av1-1-b10-00-quantizer-39.ivf", - "av1-1-b10-00-quantizer-40.ivf", "av1-1-b10-00-quantizer-41.ivf", - "av1-1-b10-00-quantizer-42.ivf", "av1-1-b10-00-quantizer-43.ivf", - "av1-1-b10-00-quantizer-44.ivf", "av1-1-b10-00-quantizer-45.ivf", - "av1-1-b10-00-quantizer-46.ivf", "av1-1-b10-00-quantizer-47.ivf", - "av1-1-b10-00-quantizer-48.ivf", "av1-1-b10-00-quantizer-49.ivf", - "av1-1-b10-00-quantizer-50.ivf", "av1-1-b10-00-quantizer-51.ivf", - "av1-1-b10-00-quantizer-52.ivf", "av1-1-b10-00-quantizer-53.ivf", - "av1-1-b10-00-quantizer-54.ivf", "av1-1-b10-00-quantizer-55.ivf", - "av1-1-b10-00-quantizer-56.ivf", "av1-1-b10-00-quantizer-57.ivf", - "av1-1-b10-00-quantizer-58.ivf", "av1-1-b10-00-quantizer-59.ivf", - "av1-1-b10-00-quantizer-60.ivf", "av1-1-b10-00-quantizer-61.ivf", - "av1-1-b10-00-quantizer-62.ivf", "av1-1-b10-00-quantizer-63.ivf", - "av1-1-b8-01-size-16x16.ivf", "av1-1-b8-01-size-16x18.ivf", - "av1-1-b8-01-size-16x32.ivf", "av1-1-b8-01-size-16x34.ivf", - "av1-1-b8-01-size-16x64.ivf", "av1-1-b8-01-size-16x66.ivf", - "av1-1-b8-01-size-18x16.ivf", "av1-1-b8-01-size-18x18.ivf", - "av1-1-b8-01-size-18x32.ivf", "av1-1-b8-01-size-18x34.ivf", - "av1-1-b8-01-size-18x64.ivf", "av1-1-b8-01-size-18x66.ivf", - "av1-1-b8-01-size-196x196.ivf", "av1-1-b8-01-size-196x198.ivf", - "av1-1-b8-01-size-196x200.ivf", "av1-1-b8-01-size-196x202.ivf", - "av1-1-b8-01-size-196x208.ivf", "av1-1-b8-01-size-196x210.ivf", - "av1-1-b8-01-size-196x224.ivf", "av1-1-b8-01-size-196x226.ivf", - "av1-1-b8-01-size-198x196.ivf", "av1-1-b8-01-size-198x198.ivf", - "av1-1-b8-01-size-198x200.ivf", "av1-1-b8-01-size-198x202.ivf", - "av1-1-b8-01-size-198x208.ivf", "av1-1-b8-01-size-198x210.ivf", - "av1-1-b8-01-size-198x224.ivf", "av1-1-b8-01-size-198x226.ivf", - "av1-1-b8-01-size-200x196.ivf", "av1-1-b8-01-size-200x198.ivf", - "av1-1-b8-01-size-200x200.ivf", "av1-1-b8-01-size-200x202.ivf", - "av1-1-b8-01-size-200x208.ivf", "av1-1-b8-01-size-200x210.ivf", - "av1-1-b8-01-size-200x224.ivf", "av1-1-b8-01-size-200x226.ivf", - "av1-1-b8-01-size-202x196.ivf", "av1-1-b8-01-size-202x198.ivf", - "av1-1-b8-01-size-202x200.ivf", "av1-1-b8-01-size-202x202.ivf", - "av1-1-b8-01-size-202x208.ivf", "av1-1-b8-01-size-202x210.ivf", - "av1-1-b8-01-size-202x224.ivf", "av1-1-b8-01-size-202x226.ivf", - "av1-1-b8-01-size-208x196.ivf", "av1-1-b8-01-size-208x198.ivf", - "av1-1-b8-01-size-208x200.ivf", "av1-1-b8-01-size-208x202.ivf", - "av1-1-b8-01-size-208x208.ivf", "av1-1-b8-01-size-208x210.ivf", - "av1-1-b8-01-size-208x224.ivf", "av1-1-b8-01-size-208x226.ivf", - "av1-1-b8-01-size-210x196.ivf", "av1-1-b8-01-size-210x198.ivf", - "av1-1-b8-01-size-210x200.ivf", "av1-1-b8-01-size-210x202.ivf", - "av1-1-b8-01-size-210x208.ivf", "av1-1-b8-01-size-210x210.ivf", - "av1-1-b8-01-size-210x224.ivf", "av1-1-b8-01-size-210x226.ivf", - "av1-1-b8-01-size-224x196.ivf", "av1-1-b8-01-size-224x198.ivf", - "av1-1-b8-01-size-224x200.ivf", "av1-1-b8-01-size-224x202.ivf", - "av1-1-b8-01-size-224x208.ivf", "av1-1-b8-01-size-224x210.ivf", - "av1-1-b8-01-size-224x224.ivf", "av1-1-b8-01-size-224x226.ivf", - "av1-1-b8-01-size-226x196.ivf", "av1-1-b8-01-size-226x198.ivf", - "av1-1-b8-01-size-226x200.ivf", "av1-1-b8-01-size-226x202.ivf", - "av1-1-b8-01-size-226x208.ivf", "av1-1-b8-01-size-226x210.ivf", - "av1-1-b8-01-size-226x224.ivf", "av1-1-b8-01-size-226x226.ivf", - "av1-1-b8-01-size-32x16.ivf", "av1-1-b8-01-size-32x18.ivf", - "av1-1-b8-01-size-32x32.ivf", "av1-1-b8-01-size-32x34.ivf", - "av1-1-b8-01-size-32x64.ivf", "av1-1-b8-01-size-32x66.ivf", - "av1-1-b8-01-size-34x16.ivf", "av1-1-b8-01-size-34x18.ivf", - "av1-1-b8-01-size-34x32.ivf", "av1-1-b8-01-size-34x34.ivf", - "av1-1-b8-01-size-34x64.ivf", "av1-1-b8-01-size-34x66.ivf", - "av1-1-b8-01-size-64x16.ivf", "av1-1-b8-01-size-64x18.ivf", - "av1-1-b8-01-size-64x32.ivf", "av1-1-b8-01-size-64x34.ivf", - "av1-1-b8-01-size-64x64.ivf", "av1-1-b8-01-size-64x66.ivf", - "av1-1-b8-01-size-66x16.ivf", "av1-1-b8-01-size-66x18.ivf", - "av1-1-b8-01-size-66x32.ivf", "av1-1-b8-01-size-66x34.ivf", - "av1-1-b8-01-size-66x64.ivf", "av1-1-b8-01-size-66x66.ivf", - "av1-1-b8-02-allintra.ivf", "av1-1-b8-03-sizedown.mkv", - "av1-1-b8-03-sizeup.mkv" -}; +const char *const kAV1TestVectors[] = { "av1-1-b8-00-quantizer-00.ivf", + "av1-1-b8-00-quantizer-01.ivf", + "av1-1-b8-00-quantizer-02.ivf", + "av1-1-b8-00-quantizer-03.ivf", + "av1-1-b8-00-quantizer-04.ivf", + "av1-1-b8-00-quantizer-05.ivf", + "av1-1-b8-00-quantizer-06.ivf", + "av1-1-b8-00-quantizer-07.ivf", + "av1-1-b8-00-quantizer-08.ivf", + "av1-1-b8-00-quantizer-09.ivf", + "av1-1-b8-00-quantizer-10.ivf", + "av1-1-b8-00-quantizer-11.ivf", + "av1-1-b8-00-quantizer-12.ivf", + "av1-1-b8-00-quantizer-13.ivf", + "av1-1-b8-00-quantizer-14.ivf", + "av1-1-b8-00-quantizer-15.ivf", + "av1-1-b8-00-quantizer-16.ivf", + "av1-1-b8-00-quantizer-17.ivf", + "av1-1-b8-00-quantizer-18.ivf", + "av1-1-b8-00-quantizer-19.ivf", + "av1-1-b8-00-quantizer-20.ivf", + "av1-1-b8-00-quantizer-21.ivf", + "av1-1-b8-00-quantizer-22.ivf", + "av1-1-b8-00-quantizer-23.ivf", + "av1-1-b8-00-quantizer-24.ivf", + "av1-1-b8-00-quantizer-25.ivf", + "av1-1-b8-00-quantizer-26.ivf", + "av1-1-b8-00-quantizer-27.ivf", + "av1-1-b8-00-quantizer-28.ivf", + "av1-1-b8-00-quantizer-29.ivf", + "av1-1-b8-00-quantizer-30.ivf", + "av1-1-b8-00-quantizer-31.ivf", + "av1-1-b8-00-quantizer-32.ivf", + "av1-1-b8-00-quantizer-33.ivf", + "av1-1-b8-00-quantizer-34.ivf", + "av1-1-b8-00-quantizer-35.ivf", + "av1-1-b8-00-quantizer-36.ivf", + "av1-1-b8-00-quantizer-37.ivf", + "av1-1-b8-00-quantizer-38.ivf", + "av1-1-b8-00-quantizer-39.ivf", + "av1-1-b8-00-quantizer-40.ivf", + "av1-1-b8-00-quantizer-41.ivf", + "av1-1-b8-00-quantizer-42.ivf", + "av1-1-b8-00-quantizer-43.ivf", + "av1-1-b8-00-quantizer-44.ivf", + "av1-1-b8-00-quantizer-45.ivf", + "av1-1-b8-00-quantizer-46.ivf", + "av1-1-b8-00-quantizer-47.ivf", + "av1-1-b8-00-quantizer-48.ivf", + "av1-1-b8-00-quantizer-49.ivf", + "av1-1-b8-00-quantizer-50.ivf", + "av1-1-b8-00-quantizer-51.ivf", + "av1-1-b8-00-quantizer-52.ivf", + "av1-1-b8-00-quantizer-53.ivf", + "av1-1-b8-00-quantizer-54.ivf", + "av1-1-b8-00-quantizer-55.ivf", + "av1-1-b8-00-quantizer-56.ivf", + "av1-1-b8-00-quantizer-57.ivf", + "av1-1-b8-00-quantizer-58.ivf", + "av1-1-b8-00-quantizer-59.ivf", + "av1-1-b8-00-quantizer-60.ivf", + "av1-1-b8-00-quantizer-61.ivf", + "av1-1-b8-00-quantizer-62.ivf", + "av1-1-b8-00-quantizer-63.ivf", +#if CONFIG_AV1_HIGHBITDEPTH + "av1-1-b10-00-quantizer-00.ivf", + "av1-1-b10-00-quantizer-01.ivf", + "av1-1-b10-00-quantizer-02.ivf", + "av1-1-b10-00-quantizer-03.ivf", + "av1-1-b10-00-quantizer-04.ivf", + "av1-1-b10-00-quantizer-05.ivf", + "av1-1-b10-00-quantizer-06.ivf", + "av1-1-b10-00-quantizer-07.ivf", + "av1-1-b10-00-quantizer-08.ivf", + "av1-1-b10-00-quantizer-09.ivf", + "av1-1-b10-00-quantizer-10.ivf", + "av1-1-b10-00-quantizer-11.ivf", + "av1-1-b10-00-quantizer-12.ivf", + "av1-1-b10-00-quantizer-13.ivf", + "av1-1-b10-00-quantizer-14.ivf", + "av1-1-b10-00-quantizer-15.ivf", + "av1-1-b10-00-quantizer-16.ivf", + "av1-1-b10-00-quantizer-17.ivf", + "av1-1-b10-00-quantizer-18.ivf", + "av1-1-b10-00-quantizer-19.ivf", + "av1-1-b10-00-quantizer-20.ivf", + "av1-1-b10-00-quantizer-21.ivf", + "av1-1-b10-00-quantizer-22.ivf", + "av1-1-b10-00-quantizer-23.ivf", + "av1-1-b10-00-quantizer-24.ivf", + "av1-1-b10-00-quantizer-25.ivf", + "av1-1-b10-00-quantizer-26.ivf", + "av1-1-b10-00-quantizer-27.ivf", + "av1-1-b10-00-quantizer-28.ivf", + "av1-1-b10-00-quantizer-29.ivf", + "av1-1-b10-00-quantizer-30.ivf", + "av1-1-b10-00-quantizer-31.ivf", + "av1-1-b10-00-quantizer-32.ivf", + "av1-1-b10-00-quantizer-33.ivf", + "av1-1-b10-00-quantizer-34.ivf", + "av1-1-b10-00-quantizer-35.ivf", + "av1-1-b10-00-quantizer-36.ivf", + "av1-1-b10-00-quantizer-37.ivf", + "av1-1-b10-00-quantizer-38.ivf", + "av1-1-b10-00-quantizer-39.ivf", + "av1-1-b10-00-quantizer-40.ivf", + "av1-1-b10-00-quantizer-41.ivf", + "av1-1-b10-00-quantizer-42.ivf", + "av1-1-b10-00-quantizer-43.ivf", + "av1-1-b10-00-quantizer-44.ivf", + "av1-1-b10-00-quantizer-45.ivf", + "av1-1-b10-00-quantizer-46.ivf", + "av1-1-b10-00-quantizer-47.ivf", + "av1-1-b10-00-quantizer-48.ivf", + "av1-1-b10-00-quantizer-49.ivf", + "av1-1-b10-00-quantizer-50.ivf", + "av1-1-b10-00-quantizer-51.ivf", + "av1-1-b10-00-quantizer-52.ivf", + "av1-1-b10-00-quantizer-53.ivf", + "av1-1-b10-00-quantizer-54.ivf", + "av1-1-b10-00-quantizer-55.ivf", + "av1-1-b10-00-quantizer-56.ivf", + "av1-1-b10-00-quantizer-57.ivf", + "av1-1-b10-00-quantizer-58.ivf", + "av1-1-b10-00-quantizer-59.ivf", + "av1-1-b10-00-quantizer-60.ivf", + "av1-1-b10-00-quantizer-61.ivf", + "av1-1-b10-00-quantizer-62.ivf", + "av1-1-b10-00-quantizer-63.ivf", + "av1-1-b10-23-film_grain-50.ivf", +#endif // CONFIG_AV1_HIGHBITDEPTH + "av1-1-b8-01-size-16x16.ivf", + "av1-1-b8-01-size-16x18.ivf", + "av1-1-b8-01-size-16x32.ivf", + "av1-1-b8-01-size-16x34.ivf", + "av1-1-b8-01-size-16x64.ivf", + "av1-1-b8-01-size-16x66.ivf", + "av1-1-b8-01-size-18x16.ivf", + "av1-1-b8-01-size-18x18.ivf", + "av1-1-b8-01-size-18x32.ivf", + "av1-1-b8-01-size-18x34.ivf", + "av1-1-b8-01-size-18x64.ivf", + "av1-1-b8-01-size-18x66.ivf", + "av1-1-b8-01-size-196x196.ivf", + "av1-1-b8-01-size-196x198.ivf", + "av1-1-b8-01-size-196x200.ivf", + "av1-1-b8-01-size-196x202.ivf", + "av1-1-b8-01-size-196x208.ivf", + "av1-1-b8-01-size-196x210.ivf", + "av1-1-b8-01-size-196x224.ivf", + "av1-1-b8-01-size-196x226.ivf", + "av1-1-b8-01-size-198x196.ivf", + "av1-1-b8-01-size-198x198.ivf", + "av1-1-b8-01-size-198x200.ivf", + "av1-1-b8-01-size-198x202.ivf", + "av1-1-b8-01-size-198x208.ivf", + "av1-1-b8-01-size-198x210.ivf", + "av1-1-b8-01-size-198x224.ivf", + "av1-1-b8-01-size-198x226.ivf", + "av1-1-b8-01-size-200x196.ivf", + "av1-1-b8-01-size-200x198.ivf", + "av1-1-b8-01-size-200x200.ivf", + "av1-1-b8-01-size-200x202.ivf", + "av1-1-b8-01-size-200x208.ivf", + "av1-1-b8-01-size-200x210.ivf", + "av1-1-b8-01-size-200x224.ivf", + "av1-1-b8-01-size-200x226.ivf", + "av1-1-b8-01-size-202x196.ivf", + "av1-1-b8-01-size-202x198.ivf", + "av1-1-b8-01-size-202x200.ivf", + "av1-1-b8-01-size-202x202.ivf", + "av1-1-b8-01-size-202x208.ivf", + "av1-1-b8-01-size-202x210.ivf", + "av1-1-b8-01-size-202x224.ivf", + "av1-1-b8-01-size-202x226.ivf", + "av1-1-b8-01-size-208x196.ivf", + "av1-1-b8-01-size-208x198.ivf", + "av1-1-b8-01-size-208x200.ivf", + "av1-1-b8-01-size-208x202.ivf", + "av1-1-b8-01-size-208x208.ivf", + "av1-1-b8-01-size-208x210.ivf", + "av1-1-b8-01-size-208x224.ivf", + "av1-1-b8-01-size-208x226.ivf", + "av1-1-b8-01-size-210x196.ivf", + "av1-1-b8-01-size-210x198.ivf", + "av1-1-b8-01-size-210x200.ivf", + "av1-1-b8-01-size-210x202.ivf", + "av1-1-b8-01-size-210x208.ivf", + "av1-1-b8-01-size-210x210.ivf", + "av1-1-b8-01-size-210x224.ivf", + "av1-1-b8-01-size-210x226.ivf", + "av1-1-b8-01-size-224x196.ivf", + "av1-1-b8-01-size-224x198.ivf", + "av1-1-b8-01-size-224x200.ivf", + "av1-1-b8-01-size-224x202.ivf", + "av1-1-b8-01-size-224x208.ivf", + "av1-1-b8-01-size-224x210.ivf", + "av1-1-b8-01-size-224x224.ivf", + "av1-1-b8-01-size-224x226.ivf", + "av1-1-b8-01-size-226x196.ivf", + "av1-1-b8-01-size-226x198.ivf", + "av1-1-b8-01-size-226x200.ivf", + "av1-1-b8-01-size-226x202.ivf", + "av1-1-b8-01-size-226x208.ivf", + "av1-1-b8-01-size-226x210.ivf", + "av1-1-b8-01-size-226x224.ivf", + "av1-1-b8-01-size-226x226.ivf", + "av1-1-b8-01-size-32x16.ivf", + "av1-1-b8-01-size-32x18.ivf", + "av1-1-b8-01-size-32x32.ivf", + "av1-1-b8-01-size-32x34.ivf", + "av1-1-b8-01-size-32x64.ivf", + "av1-1-b8-01-size-32x66.ivf", + "av1-1-b8-01-size-34x16.ivf", + "av1-1-b8-01-size-34x18.ivf", + "av1-1-b8-01-size-34x32.ivf", + "av1-1-b8-01-size-34x34.ivf", + "av1-1-b8-01-size-34x64.ivf", + "av1-1-b8-01-size-34x66.ivf", + "av1-1-b8-01-size-64x16.ivf", + "av1-1-b8-01-size-64x18.ivf", + "av1-1-b8-01-size-64x32.ivf", + "av1-1-b8-01-size-64x34.ivf", + "av1-1-b8-01-size-64x64.ivf", + "av1-1-b8-01-size-64x66.ivf", + "av1-1-b8-01-size-66x16.ivf", + "av1-1-b8-01-size-66x18.ivf", + "av1-1-b8-01-size-66x32.ivf", + "av1-1-b8-01-size-66x34.ivf", + "av1-1-b8-01-size-66x64.ivf", + "av1-1-b8-01-size-66x66.ivf", + "av1-1-b8-02-allintra.ivf", + "av1-1-b8-03-sizedown.mkv", + "av1-1-b8-03-sizeup.mkv", + "av1-1-b8-04-cdfupdate.ivf", + "av1-1-b8-05-mv.ivf", + "av1-1-b8-06-mfmv.ivf", + "av1-1-b8-22-svc-L1T2.ivf", + "av1-1-b8-22-svc-L2T1.ivf", + "av1-1-b8-22-svc-L2T2.ivf", + "av1-1-b8-23-film_grain-50.ivf" }; const int kNumAV1TestVectors = NELEMENTS(kAV1TestVectors); #endif // CONFIG_AV1_DECODER diff --git a/media/libaom/src/test/tile_independence_test.cc b/media/libaom/src/test/tile_independence_test.cc index cf534c0c5..4f7c4a475 100644 --- a/media/libaom/src/test/tile_independence_test.cc +++ b/media/libaom/src/test/tile_independence_test.cc @@ -59,7 +59,7 @@ class TileIndependenceTest virtual void PreEncodeFrameHook(libaom_test::VideoSource *video, libaom_test::Encoder *encoder) { - if (video->frame() == 1) { + if (video->frame() == 0) { encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_); encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_); SetCpuUsed(encoder); diff --git a/media/libaom/src/test/time_stamp_test.cc b/media/libaom/src/test/time_stamp_test.cc new file mode 100644 index 000000000..679e4da29 --- /dev/null +++ b/media/libaom/src/test/time_stamp_test.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +// Test AOM timestamp handling + +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/util.h" +#include "test/video_source.h" +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +namespace { + +const int kVideoSourceWidth = 320; +const int kVideoSourceHeight = 240; +const int kFramesToEncode = 3; + +// A video source that exposes functions to set the timebase, framerate and +// starting pts. +class DummyTimebaseVideoSource : public ::libaom_test::DummyVideoSource { + public: + // Parameters num and den set the timebase for the video source. + DummyTimebaseVideoSource(int num, int den) + : framerate_numerator_(30), framerate_denominator_(1), starting_pts_(0) { + SetSize(kVideoSourceWidth, kVideoSourceHeight); + set_limit(kFramesToEncode); + timebase_.num = num; + timebase_.den = den; + } + + void SetFramerate(int numerator, int denominator) { + framerate_numerator_ = numerator; + framerate_denominator_ = denominator; + } + + // Returns one frames duration in timebase units as a double. + double FrameDuration() const { + return (static_cast<double>(timebase_.den) / timebase_.num) / + (static_cast<double>(framerate_numerator_) / framerate_denominator_); + } + + virtual aom_codec_pts_t pts() const { + return static_cast<aom_codec_pts_t>(frame_ * FrameDuration() + + starting_pts_ + 0.5); + } + + virtual unsigned long duration() const { + return static_cast<unsigned long>(FrameDuration() + 0.5); + } + + virtual aom_rational_t timebase() const { return timebase_; } + + void set_starting_pts(int64_t starting_pts) { starting_pts_ = starting_pts; } + + private: + aom_rational_t timebase_; + int framerate_numerator_; + int framerate_denominator_; + int64_t starting_pts_; +}; + +class TimestampTest + : public ::libaom_test::EncoderTest, + public ::libaom_test::CodecTestWithParam<libaom_test::TestMode> { + protected: + TimestampTest() : EncoderTest(GET_PARAM(0)) {} + virtual ~TimestampTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + } +}; + +// Tests encoding in millisecond timebase. +TEST_P(TimestampTest, EncodeFrames) { + DummyTimebaseVideoSource video(1, 1000); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); +} + +TEST_P(TimestampTest, TestMicrosecondTimebase) { + // Set the timebase to microseconds. + DummyTimebaseVideoSource video(1, 1000000); + video.set_limit(1); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); +} + +TEST_P(TimestampTest, TestAv1Rollover) { + DummyTimebaseVideoSource video(1, 1000); + video.set_starting_pts(922337170351ll); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); +} + +AV1_INSTANTIATE_TEST_CASE(TimestampTest, + ::testing::Values(::libaom_test::kTwoPassGood)); + +} // namespace diff --git a/media/libaom/src/test/transform_test_base.h b/media/libaom/src/test/transform_test_base.h index 8ebcf5ff7..68f5cc74d 100644 --- a/media/libaom/src/test/transform_test_base.h +++ b/media/libaom/src/test/transform_test_base.h @@ -29,20 +29,23 @@ namespace libaom_test { // to a aom header file. const int kDctMaxValue = 16384; -typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, - TxfmParam *txfm_param); +template <typename OutputType> +using FhtFunc = void (*)(const int16_t *in, OutputType *out, int stride, + TxfmParam *txfm_param); -typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, - const TxfmParam *txfm_param); +template <typename OutputType> +using IhtFunc = void (*)(const tran_low_t *in, uint8_t *out, int stride, + const TxfmParam *txfm_param); +template <typename OutType> class TransformTestBase { public: virtual ~TransformTestBase() {} protected: - virtual void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) = 0; + virtual void RunFwdTxfm(const int16_t *in, OutType *out, int stride) = 0; - virtual void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) = 0; + virtual void RunInvTxfm(const OutType *out, uint8_t *dst, int stride) = 0; void RunAccuracyCheck(uint32_t ref_max_error, double ref_avg_error) { ACMRandom rnd(ACMRandom::DeterministicSeed()); @@ -52,8 +55,8 @@ class TransformTestBase { int16_t *test_input_block = reinterpret_cast<int16_t *>( aom_memalign(16, sizeof(int16_t) * num_coeffs_)); - tran_low_t *test_temp_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); + OutType *test_temp_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(test_temp_block[0]) * num_coeffs_)); uint8_t *dst = reinterpret_cast<uint8_t *>( aom_memalign(16, sizeof(uint8_t) * num_coeffs_)); uint8_t *src = reinterpret_cast<uint8_t *>( @@ -123,10 +126,10 @@ class TransformTestBase { int16_t *input_block = reinterpret_cast<int16_t *>( aom_memalign(16, sizeof(int16_t) * stride * height_)); - tran_low_t *output_ref_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); - tran_low_t *output_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); + OutType *output_ref_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(output_ref_block[0]) * num_coeffs_)); + OutType *output_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(output_block[0]) * num_coeffs_)); for (int i = 0; i < count_test_block; ++i) { int j, k; @@ -172,8 +175,8 @@ class TransformTestBase { int16_t *input_block = reinterpret_cast<int16_t *>( aom_memalign(16, sizeof(int16_t) * num_coeffs_)); - tran_low_t *trans_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); + OutType *trans_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(trans_block[0]) * num_coeffs_)); uint8_t *output_block = reinterpret_cast<uint8_t *>( aom_memalign(16, sizeof(uint8_t) * stride * height_)); uint8_t *output_ref_block = reinterpret_cast<uint8_t *>( @@ -218,10 +221,10 @@ class TransformTestBase { int16_t *input_extreme_block = reinterpret_cast<int16_t *>( aom_memalign(16, sizeof(int16_t) * num_coeffs_)); - tran_low_t *output_ref_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); - tran_low_t *output_block = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); + OutType *output_ref_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(output_ref_block[0]) * num_coeffs_)); + OutType *output_block = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(output_block[0]) * num_coeffs_)); for (int i = 0; i < count_test_block; ++i) { // Initialize a test block with input range [-mask_, mask_]. @@ -260,8 +263,8 @@ class TransformTestBase { int16_t *in = reinterpret_cast<int16_t *>( aom_memalign(16, sizeof(int16_t) * num_coeffs_)); - tran_low_t *coeff = reinterpret_cast<tran_low_t *>( - aom_memalign(16, sizeof(tran_low_t) * num_coeffs_)); + OutType *coeff = reinterpret_cast<OutType *>( + aom_memalign(16, sizeof(coeff[0]) * num_coeffs_)); uint8_t *dst = reinterpret_cast<uint8_t *>( aom_memalign(16, sizeof(uint8_t) * num_coeffs_)); uint8_t *src = reinterpret_cast<uint8_t *>( @@ -313,8 +316,8 @@ class TransformTestBase { int pitch_; int height_; - FhtFunc fwd_txfm_ref; - IhtFunc inv_txfm_ref; + FhtFunc<OutType> fwd_txfm_ref; + IhtFunc<OutType> inv_txfm_ref; aom_bit_depth_t bit_depth_; int mask_; int num_coeffs_; diff --git a/media/libaom/src/test/util.h b/media/libaom/src/test/util.h index c3f4e4442..aa4b106e4 100644 --- a/media/libaom/src/test/util.h +++ b/media/libaom/src/test/util.h @@ -20,7 +20,7 @@ #include "aom_ports/aom_timer.h" // Macros -#define GET_PARAM(k) ::testing::get<k>(GetParam()) +#define GET_PARAM(k) std::get<k>(GetParam()) inline double compute_psnr(const aom_image_t *img1, const aom_image_t *img2) { assert((img1->fmt == img2->fmt) && (img1->d_w == img2->d_w) && diff --git a/media/libaom/src/test/variance_test.cc b/media/libaom/src/test/variance_test.cc index 0df314b0f..1458ece28 100644 --- a/media/libaom/src/test/variance_test.cc +++ b/media/libaom/src/test/variance_test.cc @@ -11,6 +11,8 @@ #include <cstdlib> #include <new> +#include <ostream> +#include <tuple> #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -43,10 +45,10 @@ typedef unsigned int (*SubpixAvgVarMxNFunc)(const uint8_t *a, int a_stride, typedef unsigned int (*Get4x4SseFunc)(const uint8_t *a, int a_stride, const uint8_t *b, int b_stride); typedef unsigned int (*SumOfSquaresFunction)(const int16_t *src); -typedef unsigned int (*JntSubpixAvgVarMxNFunc)( +typedef unsigned int (*DistWtdSubpixAvgVarMxNFunc)( const uint8_t *a, int a_stride, int xoffset, int yoffset, const uint8_t *b, int b_stride, uint32_t *sse, const uint8_t *second_pred, - const JNT_COMP_PARAMS *jcp_param); + const DIST_WTD_COMP_PARAMS *jcp_param); typedef uint32_t (*ObmcSubpelVarFunc)(const uint8_t *pre, int pre_stride, int xoffset, int yoffset, const int32_t *wsrc, const int32_t *mask, @@ -115,8 +117,7 @@ static uint32_t variance_ref(const uint8_t *src, const uint8_t *ref, int l2w, /* The subpel reference functions differ from the codec version in one aspect: * they calculate the bilinear factors directly instead of using a lookup table * and therefore upshift xoff and yoff by 1. Only every other calculated value - * is used so the codec version shrinks the table to save space and maintain - * compatibility with vp8. + * is used so the codec version shrinks the table to save space. */ static uint32_t subpel_variance_ref(const uint8_t *ref, const uint8_t *src, int l2w, int l2h, int xoff, int yoff, @@ -216,10 +217,10 @@ static uint32_t subpel_avg_variance_ref(const uint8_t *ref, const uint8_t *src, return static_cast<uint32_t>(sse - ((se * se) >> (l2w + l2h))); } -static uint32_t jnt_subpel_avg_variance_ref( +static uint32_t dist_wtd_subpel_avg_variance_ref( const uint8_t *ref, const uint8_t *src, const uint8_t *second_pred, int l2w, int l2h, int xoff, int yoff, uint32_t *sse_ptr, bool use_high_bit_depth, - aom_bit_depth_t bit_depth, JNT_COMP_PARAMS *jcp_param) { + aom_bit_depth_t bit_depth, DIST_WTD_COMP_PARAMS *jcp_param) { int64_t se = 0; uint64_t sse = 0; const int w = 1 << l2w; @@ -657,9 +658,9 @@ void MainTestClass<FunctionType>::MaxTestSse() { //////////////////////////////////////////////////////////////////////////////// -using ::testing::get; -using ::testing::make_tuple; -using ::testing::tuple; +using std::get; +using std::make_tuple; +using std::tuple; template <typename FunctionType> class SubpelVarianceTest @@ -703,13 +704,14 @@ class SubpelVarianceTest protected: void RefTest(); void ExtremeRefTest(); + void SpeedTest(); ACMRandom rnd_; uint8_t *src_; uint8_t *ref_; uint8_t *sec_; TestParams<FunctionType> params_; - JNT_COMP_PARAMS jcp_param_; + DIST_WTD_COMP_PARAMS jcp_param_; // some relay helpers bool use_high_bit_depth() const { return params_.use_high_bit_depth; } @@ -785,6 +787,57 @@ void SubpelVarianceTest<SubpelVarianceFunctionType>::ExtremeRefTest() { } } +template <typename SubpelVarianceFunctionType> +void SubpelVarianceTest<SubpelVarianceFunctionType>::SpeedTest() { + if (!use_high_bit_depth()) { + for (int j = 0; j < block_size(); j++) { + src_[j] = rnd_.Rand8(); + } + for (int j = 0; j < block_size() + width() + height() + 1; j++) { + ref_[j] = rnd_.Rand8(); + } + } else { + for (int j = 0; j < block_size(); j++) { + CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); + } + for (int j = 0; j < block_size() + width() + height() + 1; j++) { + CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); + } + } + + unsigned int sse1, sse2; + int run_time = 1000000000 / block_size(); + aom_usec_timer timer; + + aom_usec_timer_start(&timer); + for (int i = 0; i < run_time; ++i) { + int x = rnd_(8); + int y = rnd_(8); + params_.func(ref_, width() + 1, x, y, src_, width(), &sse1); + } + aom_usec_timer_mark(&timer); + + const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer)); + + aom_usec_timer timer_c; + + aom_usec_timer_start(&timer_c); + for (int i = 0; i < run_time; ++i) { + int x = rnd_(8); + int y = rnd_(8); + subpel_variance_ref(ref_, src_, params_.log2width, params_.log2height, x, y, + &sse2, use_high_bit_depth(), params_.bit_depth); + } + aom_usec_timer_mark(&timer_c); + + const int elapsed_time_c = static_cast<int>(aom_usec_timer_elapsed(&timer_c)); + + printf( + "sub_pixel_variance_%dx%d_%d: ref_time=%d us opt_time=%d us gain=%d \n", + width(), height(), params_.bit_depth, elapsed_time_c, elapsed_time, + elapsed_time_c / elapsed_time); +} + template <> void SubpelVarianceTest<SubpixAvgVarMxNFunc>::RefTest() { for (int x = 0; x < 8; ++x) { @@ -820,7 +873,7 @@ void SubpelVarianceTest<SubpixAvgVarMxNFunc>::RefTest() { } template <> -void SubpelVarianceTest<JntSubpixAvgVarMxNFunc>::RefTest() { +void SubpelVarianceTest<DistWtdSubpixAvgVarMxNFunc>::RefTest() { for (int x = 0; x < 8; ++x) { for (int y = 0; y < 8; ++y) { if (!use_high_bit_depth()) { @@ -849,7 +902,7 @@ void SubpelVarianceTest<JntSubpixAvgVarMxNFunc>::RefTest() { ASM_REGISTER_STATE_CHECK(var1 = params_.func(ref_, width() + 0, x, y, src_, width(), &sse1, sec_, &jcp_param_)); - var2 = jnt_subpel_avg_variance_ref( + var2 = dist_wtd_subpel_avg_variance_ref( ref_, src_, sec_, params_.log2width, params_.log2height, x, y, &sse2, use_high_bit_depth(), params_.bit_depth, &jcp_param_); EXPECT_EQ(sse1, sse2) << "at position " << x << ", " << y; @@ -1022,7 +1075,8 @@ typedef MainTestClass<VarianceMxNFunc> AvxMseTest; typedef MainTestClass<VarianceMxNFunc> AvxVarianceTest; typedef SubpelVarianceTest<SubpixVarMxNFunc> AvxSubpelVarianceTest; typedef SubpelVarianceTest<SubpixAvgVarMxNFunc> AvxSubpelAvgVarianceTest; -typedef SubpelVarianceTest<JntSubpixAvgVarMxNFunc> AvxJntSubpelAvgVarianceTest; +typedef SubpelVarianceTest<DistWtdSubpixAvgVarMxNFunc> + AvxDistWtdSubpelAvgVarianceTest; typedef ObmcVarianceTest<ObmcSubpelVarFunc> AvxObmcSubpelVarianceTest; TEST_P(AvxSseTest, RefSse) { RefTestSse(); } @@ -1038,29 +1092,30 @@ TEST_P(SumOfSquaresTest, Const) { ConstTest(); } TEST_P(SumOfSquaresTest, Ref) { RefTest(); } TEST_P(AvxSubpelVarianceTest, Ref) { RefTest(); } TEST_P(AvxSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); } +TEST_P(AvxSubpelVarianceTest, DISABLED_Speed) { SpeedTest(); } TEST_P(AvxSubpelAvgVarianceTest, Ref) { RefTest(); } -TEST_P(AvxJntSubpelAvgVarianceTest, Ref) { RefTest(); } +TEST_P(AvxDistWtdSubpelAvgVarianceTest, Ref) { RefTest(); } TEST_P(AvxObmcSubpelVarianceTest, Ref) { RefTest(); } TEST_P(AvxObmcSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); } TEST_P(AvxObmcSubpelVarianceTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_CASE_P(C, SumOfSquaresTest, - ::testing::Values(aom_get_mb_ss_c)); +INSTANTIATE_TEST_SUITE_P(C, SumOfSquaresTest, + ::testing::Values(aom_get_mb_ss_c)); typedef TestParams<Get4x4SseFunc> SseParams; -INSTANTIATE_TEST_CASE_P(C, AvxSseTest, - ::testing::Values(SseParams(2, 2, - &aom_get4x4sse_cs_c))); +INSTANTIATE_TEST_SUITE_P(C, AvxSseTest, + ::testing::Values(SseParams(2, 2, + &aom_get4x4sse_cs_c))); typedef TestParams<VarianceMxNFunc> MseParams; -INSTANTIATE_TEST_CASE_P(C, AvxMseTest, - ::testing::Values(MseParams(4, 4, &aom_mse16x16_c), - MseParams(4, 3, &aom_mse16x8_c), - MseParams(3, 4, &aom_mse8x16_c), - MseParams(3, 3, &aom_mse8x8_c))); +INSTANTIATE_TEST_SUITE_P(C, AvxMseTest, + ::testing::Values(MseParams(4, 4, &aom_mse16x16_c), + MseParams(4, 3, &aom_mse16x8_c), + MseParams(3, 4, &aom_mse8x16_c), + MseParams(3, 3, &aom_mse8x8_c))); typedef TestParams<VarianceMxNFunc> VarianceParams; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AvxVarianceTest, ::testing::Values(VarianceParams(7, 7, &aom_variance128x128_c), VarianceParams(7, 6, &aom_variance128x64_c), @@ -1077,10 +1132,17 @@ INSTANTIATE_TEST_CASE_P( VarianceParams(3, 3, &aom_variance8x8_c), VarianceParams(3, 2, &aom_variance8x4_c), VarianceParams(2, 3, &aom_variance4x8_c), - VarianceParams(2, 2, &aom_variance4x4_c))); + VarianceParams(2, 2, &aom_variance4x4_c), + + VarianceParams(6, 4, &aom_variance64x16_c), + VarianceParams(4, 6, &aom_variance16x64_c), + VarianceParams(5, 3, &aom_variance32x8_c), + VarianceParams(3, 5, &aom_variance8x32_c), + VarianceParams(4, 2, &aom_variance16x4_c), + VarianceParams(2, 4, &aom_variance4x16_c))); typedef TestParams<SubpixVarMxNFunc> SubpelVarianceParams; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(7, 7, &aom_sub_pixel_variance128x128_c, 0), @@ -1098,10 +1160,17 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(3, 3, &aom_sub_pixel_variance8x8_c, 0), SubpelVarianceParams(3, 2, &aom_sub_pixel_variance8x4_c, 0), SubpelVarianceParams(2, 3, &aom_sub_pixel_variance4x8_c, 0), - SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_c, 0))); + SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_c, 0), + + SubpelVarianceParams(6, 4, &aom_sub_pixel_variance64x16_c, 0), + SubpelVarianceParams(4, 6, &aom_sub_pixel_variance16x64_c, 0), + SubpelVarianceParams(5, 3, &aom_sub_pixel_variance32x8_c, 0), + SubpelVarianceParams(3, 5, &aom_sub_pixel_variance8x32_c, 0), + SubpelVarianceParams(4, 2, &aom_sub_pixel_variance16x4_c, 0), + SubpelVarianceParams(2, 4, &aom_sub_pixel_variance4x16_c, 0))); typedef TestParams<SubpixAvgVarMxNFunc> SubpelAvgVarianceParams; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(7, 7, &aom_sub_pixel_avg_variance128x128_c, 0), @@ -1119,40 +1188,60 @@ INSTANTIATE_TEST_CASE_P( SubpelAvgVarianceParams(3, 3, &aom_sub_pixel_avg_variance8x8_c, 0), SubpelAvgVarianceParams(3, 2, &aom_sub_pixel_avg_variance8x4_c, 0), SubpelAvgVarianceParams(2, 3, &aom_sub_pixel_avg_variance4x8_c, 0), - SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_c, 0))); - -typedef TestParams<JntSubpixAvgVarMxNFunc> JntSubpelAvgVarianceParams; -INSTANTIATE_TEST_CASE_P( - C, AvxJntSubpelAvgVarianceTest, - ::testing::Values( - JntSubpelAvgVarianceParams(6, 6, &aom_jnt_sub_pixel_avg_variance64x64_c, - 0), - JntSubpelAvgVarianceParams(6, 5, &aom_jnt_sub_pixel_avg_variance64x32_c, - 0), - JntSubpelAvgVarianceParams(5, 6, &aom_jnt_sub_pixel_avg_variance32x64_c, - 0), - JntSubpelAvgVarianceParams(5, 5, &aom_jnt_sub_pixel_avg_variance32x32_c, - 0), - JntSubpelAvgVarianceParams(5, 4, &aom_jnt_sub_pixel_avg_variance32x16_c, - 0), - JntSubpelAvgVarianceParams(4, 5, &aom_jnt_sub_pixel_avg_variance16x32_c, - 0), - JntSubpelAvgVarianceParams(4, 4, &aom_jnt_sub_pixel_avg_variance16x16_c, - 0), - JntSubpelAvgVarianceParams(4, 3, &aom_jnt_sub_pixel_avg_variance16x8_c, - 0), - JntSubpelAvgVarianceParams(3, 4, &aom_jnt_sub_pixel_avg_variance8x16_c, - 0), - JntSubpelAvgVarianceParams(3, 3, &aom_jnt_sub_pixel_avg_variance8x8_c, - 0), - JntSubpelAvgVarianceParams(3, 2, &aom_jnt_sub_pixel_avg_variance8x4_c, - 0), - JntSubpelAvgVarianceParams(2, 3, &aom_jnt_sub_pixel_avg_variance4x8_c, - 0), - JntSubpelAvgVarianceParams(2, 2, &aom_jnt_sub_pixel_avg_variance4x4_c, - 0))); - -INSTANTIATE_TEST_CASE_P( + SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_c, 0), + + SubpelAvgVarianceParams(6, 4, &aom_sub_pixel_avg_variance64x16_c, 0), + SubpelAvgVarianceParams(4, 6, &aom_sub_pixel_avg_variance16x64_c, 0), + SubpelAvgVarianceParams(5, 3, &aom_sub_pixel_avg_variance32x8_c, 0), + SubpelAvgVarianceParams(3, 5, &aom_sub_pixel_avg_variance8x32_c, 0), + SubpelAvgVarianceParams(4, 2, &aom_sub_pixel_avg_variance16x4_c, 0), + SubpelAvgVarianceParams(2, 4, &aom_sub_pixel_avg_variance4x16_c, 0))); + +typedef TestParams<DistWtdSubpixAvgVarMxNFunc> DistWtdSubpelAvgVarianceParams; +INSTANTIATE_TEST_SUITE_P( + C, AvxDistWtdSubpelAvgVarianceTest, + ::testing::Values(DistWtdSubpelAvgVarianceParams( + 6, 6, &aom_dist_wtd_sub_pixel_avg_variance64x64_c, 0), + DistWtdSubpelAvgVarianceParams( + 6, 5, &aom_dist_wtd_sub_pixel_avg_variance64x32_c, 0), + DistWtdSubpelAvgVarianceParams( + 5, 6, &aom_dist_wtd_sub_pixel_avg_variance32x64_c, 0), + DistWtdSubpelAvgVarianceParams( + 5, 5, &aom_dist_wtd_sub_pixel_avg_variance32x32_c, 0), + DistWtdSubpelAvgVarianceParams( + 5, 4, &aom_dist_wtd_sub_pixel_avg_variance32x16_c, 0), + DistWtdSubpelAvgVarianceParams( + 4, 5, &aom_dist_wtd_sub_pixel_avg_variance16x32_c, 0), + DistWtdSubpelAvgVarianceParams( + 4, 4, &aom_dist_wtd_sub_pixel_avg_variance16x16_c, 0), + DistWtdSubpelAvgVarianceParams( + 4, 3, &aom_dist_wtd_sub_pixel_avg_variance16x8_c, 0), + DistWtdSubpelAvgVarianceParams( + 3, 4, &aom_dist_wtd_sub_pixel_avg_variance8x16_c, 0), + DistWtdSubpelAvgVarianceParams( + 3, 3, &aom_dist_wtd_sub_pixel_avg_variance8x8_c, 0), + DistWtdSubpelAvgVarianceParams( + 3, 2, &aom_dist_wtd_sub_pixel_avg_variance8x4_c, 0), + DistWtdSubpelAvgVarianceParams( + 2, 3, &aom_dist_wtd_sub_pixel_avg_variance4x8_c, 0), + DistWtdSubpelAvgVarianceParams( + 2, 2, &aom_dist_wtd_sub_pixel_avg_variance4x4_c, 0), + + DistWtdSubpelAvgVarianceParams( + 6, 4, &aom_dist_wtd_sub_pixel_avg_variance64x16_c, 0), + DistWtdSubpelAvgVarianceParams( + 4, 6, &aom_dist_wtd_sub_pixel_avg_variance16x64_c, 0), + DistWtdSubpelAvgVarianceParams( + 5, 3, &aom_dist_wtd_sub_pixel_avg_variance32x8_c, 0), + DistWtdSubpelAvgVarianceParams( + 3, 5, &aom_dist_wtd_sub_pixel_avg_variance8x32_c, 0), + DistWtdSubpelAvgVarianceParams( + 4, 2, &aom_dist_wtd_sub_pixel_avg_variance16x4_c, 0), + DistWtdSubpelAvgVarianceParams( + 2, 4, &aom_dist_wtd_sub_pixel_avg_variance4x16_c, + 0))); + +INSTANTIATE_TEST_SUITE_P( C, AvxObmcSubpelVarianceTest, ::testing::Values( ObmcSubpelVarianceParams(7, 7, &aom_obmc_sub_pixel_variance128x128_c, @@ -1171,8 +1260,16 @@ INSTANTIATE_TEST_CASE_P( ObmcSubpelVarianceParams(3, 3, &aom_obmc_sub_pixel_variance8x8_c, 0), ObmcSubpelVarianceParams(3, 2, &aom_obmc_sub_pixel_variance8x4_c, 0), ObmcSubpelVarianceParams(2, 3, &aom_obmc_sub_pixel_variance4x8_c, 0), - ObmcSubpelVarianceParams(2, 2, &aom_obmc_sub_pixel_variance4x4_c, 0))); + ObmcSubpelVarianceParams(2, 2, &aom_obmc_sub_pixel_variance4x4_c, 0), + + ObmcSubpelVarianceParams(6, 4, &aom_obmc_sub_pixel_variance64x16_c, 0), + ObmcSubpelVarianceParams(4, 6, &aom_obmc_sub_pixel_variance16x64_c, 0), + ObmcSubpelVarianceParams(5, 3, &aom_obmc_sub_pixel_variance32x8_c, 0), + ObmcSubpelVarianceParams(3, 5, &aom_obmc_sub_pixel_variance8x32_c, 0), + ObmcSubpelVarianceParams(4, 2, &aom_obmc_sub_pixel_variance16x4_c, 0), + ObmcSubpelVarianceParams(2, 4, &aom_obmc_sub_pixel_variance4x16_c, 0))); +#if CONFIG_AV1_HIGHBITDEPTH typedef MainTestClass<VarianceMxNFunc> AvxHBDMseTest; typedef MainTestClass<VarianceMxNFunc> AvxHBDVarianceTest; typedef SubpelVarianceTest<SubpixVarMxNFunc> AvxHBDSubpelVarianceTest; @@ -1188,10 +1285,11 @@ TEST_P(AvxHBDVarianceTest, OneQuarter) { OneQuarterTest(); } TEST_P(AvxHBDVarianceTest, DISABLED_Speed) { SpeedTest(); } TEST_P(AvxHBDSubpelVarianceTest, Ref) { RefTest(); } TEST_P(AvxHBDSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); } +TEST_P(AvxHBDSubpelVarianceTest, DISABLED_Speed) { SpeedTest(); } TEST_P(AvxHBDSubpelAvgVarianceTest, Ref) { RefTest(); } /* TODO(debargha): This test does not support the highbd version -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AvxHBDMseTest, ::testing::Values(make_tuple(4, 4, &aom_highbd_12_mse16x16_c), make_tuple(4, 4, &aom_highbd_12_mse16x8_c), @@ -1255,13 +1353,32 @@ const VarianceParams kArrayHBDVariance_c[] = { VarianceParams(3, 3, &aom_highbd_8_variance8x8_c, 8), VarianceParams(3, 2, &aom_highbd_8_variance8x4_c, 8), VarianceParams(2, 3, &aom_highbd_8_variance4x8_c, 8), - VarianceParams(2, 2, &aom_highbd_8_variance4x4_c, 8) + VarianceParams(2, 2, &aom_highbd_8_variance4x4_c, 8), + + VarianceParams(6, 4, &aom_highbd_12_variance64x16_c, 12), + VarianceParams(4, 6, &aom_highbd_12_variance16x64_c, 12), + VarianceParams(5, 3, &aom_highbd_12_variance32x8_c, 12), + VarianceParams(3, 5, &aom_highbd_12_variance8x32_c, 12), + VarianceParams(4, 2, &aom_highbd_12_variance16x4_c, 12), + VarianceParams(2, 4, &aom_highbd_12_variance4x16_c, 12), + VarianceParams(6, 4, &aom_highbd_10_variance64x16_c, 10), + VarianceParams(4, 6, &aom_highbd_10_variance16x64_c, 10), + VarianceParams(5, 3, &aom_highbd_10_variance32x8_c, 10), + VarianceParams(3, 5, &aom_highbd_10_variance8x32_c, 10), + VarianceParams(4, 2, &aom_highbd_10_variance16x4_c, 10), + VarianceParams(2, 4, &aom_highbd_10_variance4x16_c, 10), + VarianceParams(6, 4, &aom_highbd_8_variance64x16_c, 8), + VarianceParams(4, 6, &aom_highbd_8_variance16x64_c, 8), + VarianceParams(5, 3, &aom_highbd_8_variance32x8_c, 8), + VarianceParams(3, 5, &aom_highbd_8_variance8x32_c, 8), + VarianceParams(4, 2, &aom_highbd_8_variance16x4_c, 8), + VarianceParams(2, 4, &aom_highbd_8_variance4x16_c, 8), }; -INSTANTIATE_TEST_CASE_P(C, AvxHBDVarianceTest, - ::testing::ValuesIn(kArrayHBDVariance_c)); +INSTANTIATE_TEST_SUITE_P(C, AvxHBDVarianceTest, + ::testing::ValuesIn(kArrayHBDVariance_c)); #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AvxHBDVarianceTest, ::testing::Values( VarianceParams(2, 2, &aom_highbd_8_variance4x4_sse4_1, 8), @@ -1318,9 +1435,28 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_c[] = { SubpelVarianceParams(3, 2, &aom_highbd_12_sub_pixel_variance8x4_c, 12), SubpelVarianceParams(2, 3, &aom_highbd_12_sub_pixel_variance4x8_c, 12), SubpelVarianceParams(2, 2, &aom_highbd_12_sub_pixel_variance4x4_c, 12), + + SubpelVarianceParams(6, 4, &aom_highbd_8_sub_pixel_variance64x16_c, 8), + SubpelVarianceParams(4, 6, &aom_highbd_8_sub_pixel_variance16x64_c, 8), + SubpelVarianceParams(5, 3, &aom_highbd_8_sub_pixel_variance32x8_c, 8), + SubpelVarianceParams(3, 5, &aom_highbd_8_sub_pixel_variance8x32_c, 8), + SubpelVarianceParams(4, 2, &aom_highbd_8_sub_pixel_variance16x4_c, 8), + SubpelVarianceParams(2, 4, &aom_highbd_8_sub_pixel_variance4x16_c, 8), + SubpelVarianceParams(6, 4, &aom_highbd_10_sub_pixel_variance64x16_c, 10), + SubpelVarianceParams(4, 6, &aom_highbd_10_sub_pixel_variance16x64_c, 10), + SubpelVarianceParams(5, 3, &aom_highbd_10_sub_pixel_variance32x8_c, 10), + SubpelVarianceParams(3, 5, &aom_highbd_10_sub_pixel_variance8x32_c, 10), + SubpelVarianceParams(4, 2, &aom_highbd_10_sub_pixel_variance16x4_c, 10), + SubpelVarianceParams(2, 4, &aom_highbd_10_sub_pixel_variance4x16_c, 10), + SubpelVarianceParams(6, 4, &aom_highbd_12_sub_pixel_variance64x16_c, 12), + SubpelVarianceParams(4, 6, &aom_highbd_12_sub_pixel_variance16x64_c, 12), + SubpelVarianceParams(5, 3, &aom_highbd_12_sub_pixel_variance32x8_c, 12), + SubpelVarianceParams(3, 5, &aom_highbd_12_sub_pixel_variance8x32_c, 12), + SubpelVarianceParams(4, 2, &aom_highbd_12_sub_pixel_variance16x4_c, 12), + SubpelVarianceParams(2, 4, &aom_highbd_12_sub_pixel_variance4x16_c, 12), }; -INSTANTIATE_TEST_CASE_P(C, AvxHBDSubpelVarianceTest, - ::testing::ValuesIn(kArrayHBDSubpelVariance_c)); +INSTANTIATE_TEST_SUITE_P(C, AvxHBDSubpelVarianceTest, + ::testing::ValuesIn(kArrayHBDSubpelVariance_c)); const SubpelAvgVarianceParams kArrayHBDSubpelAvgVariance_c[] = { SubpelAvgVarianceParams(7, 7, &aom_highbd_8_sub_pixel_avg_variance128x128_c, @@ -1397,10 +1533,41 @@ const SubpelAvgVarianceParams kArrayHBDSubpelAvgVariance_c[] = { SubpelAvgVarianceParams(3, 3, &aom_highbd_12_sub_pixel_avg_variance8x8_c, 12), SubpelAvgVarianceParams(3, 2, &aom_highbd_12_sub_pixel_avg_variance8x4_c, 12), SubpelAvgVarianceParams(2, 3, &aom_highbd_12_sub_pixel_avg_variance4x8_c, 12), - SubpelAvgVarianceParams(2, 2, &aom_highbd_12_sub_pixel_avg_variance4x4_c, 12) + SubpelAvgVarianceParams(2, 2, &aom_highbd_12_sub_pixel_avg_variance4x4_c, 12), + + SubpelAvgVarianceParams(6, 4, &aom_highbd_8_sub_pixel_avg_variance64x16_c, 8), + SubpelAvgVarianceParams(4, 6, &aom_highbd_8_sub_pixel_avg_variance16x64_c, 8), + SubpelAvgVarianceParams(5, 3, &aom_highbd_8_sub_pixel_avg_variance32x8_c, 8), + SubpelAvgVarianceParams(3, 5, &aom_highbd_8_sub_pixel_avg_variance8x32_c, 8), + SubpelAvgVarianceParams(4, 2, &aom_highbd_8_sub_pixel_avg_variance16x4_c, 8), + SubpelAvgVarianceParams(2, 4, &aom_highbd_8_sub_pixel_avg_variance4x16_c, 8), + SubpelAvgVarianceParams(6, 4, &aom_highbd_10_sub_pixel_avg_variance64x16_c, + 10), + SubpelAvgVarianceParams(4, 6, &aom_highbd_10_sub_pixel_avg_variance16x64_c, + 10), + SubpelAvgVarianceParams(5, 3, &aom_highbd_10_sub_pixel_avg_variance32x8_c, + 10), + SubpelAvgVarianceParams(3, 5, &aom_highbd_10_sub_pixel_avg_variance8x32_c, + 10), + SubpelAvgVarianceParams(4, 2, &aom_highbd_10_sub_pixel_avg_variance16x4_c, + 10), + SubpelAvgVarianceParams(2, 4, &aom_highbd_10_sub_pixel_avg_variance4x16_c, + 10), + SubpelAvgVarianceParams(6, 4, &aom_highbd_12_sub_pixel_avg_variance64x16_c, + 12), + SubpelAvgVarianceParams(4, 6, &aom_highbd_12_sub_pixel_avg_variance16x64_c, + 12), + SubpelAvgVarianceParams(5, 3, &aom_highbd_12_sub_pixel_avg_variance32x8_c, + 12), + SubpelAvgVarianceParams(3, 5, &aom_highbd_12_sub_pixel_avg_variance8x32_c, + 12), + SubpelAvgVarianceParams(4, 2, &aom_highbd_12_sub_pixel_avg_variance16x4_c, + 12), + SubpelAvgVarianceParams(2, 4, &aom_highbd_12_sub_pixel_avg_variance4x16_c, + 12), }; -INSTANTIATE_TEST_CASE_P(C, AvxHBDSubpelAvgVarianceTest, - ::testing::ValuesIn(kArrayHBDSubpelAvgVariance_c)); +INSTANTIATE_TEST_SUITE_P(C, AvxHBDSubpelAvgVarianceTest, + ::testing::ValuesIn(kArrayHBDSubpelAvgVariance_c)); const ObmcSubpelVarianceParams kArrayHBDObmcSubpelVariance_c[] = { ObmcSubpelVarianceParams(7, 7, &aom_highbd_obmc_sub_pixel_variance128x128_c, @@ -1485,22 +1652,54 @@ const ObmcSubpelVarianceParams kArrayHBDObmcSubpelVariance_c[] = { ObmcSubpelVarianceParams(2, 3, &aom_highbd_12_obmc_sub_pixel_variance4x8_c, 12), ObmcSubpelVarianceParams(2, 2, &aom_highbd_12_obmc_sub_pixel_variance4x4_c, - 12) + 12), + + ObmcSubpelVarianceParams(6, 4, &aom_highbd_obmc_sub_pixel_variance64x16_c, 8), + ObmcSubpelVarianceParams(4, 6, &aom_highbd_obmc_sub_pixel_variance16x64_c, 8), + ObmcSubpelVarianceParams(5, 3, &aom_highbd_obmc_sub_pixel_variance32x8_c, 8), + ObmcSubpelVarianceParams(3, 5, &aom_highbd_obmc_sub_pixel_variance8x32_c, 8), + ObmcSubpelVarianceParams(4, 2, &aom_highbd_obmc_sub_pixel_variance16x4_c, 8), + ObmcSubpelVarianceParams(2, 4, &aom_highbd_obmc_sub_pixel_variance4x16_c, 8), + ObmcSubpelVarianceParams(6, 4, &aom_highbd_10_obmc_sub_pixel_variance64x16_c, + 10), + ObmcSubpelVarianceParams(4, 6, &aom_highbd_10_obmc_sub_pixel_variance16x64_c, + 10), + ObmcSubpelVarianceParams(5, 3, &aom_highbd_10_obmc_sub_pixel_variance32x8_c, + 10), + ObmcSubpelVarianceParams(3, 5, &aom_highbd_10_obmc_sub_pixel_variance8x32_c, + 10), + ObmcSubpelVarianceParams(4, 2, &aom_highbd_10_obmc_sub_pixel_variance16x4_c, + 10), + ObmcSubpelVarianceParams(2, 4, &aom_highbd_10_obmc_sub_pixel_variance4x16_c, + 10), + ObmcSubpelVarianceParams(6, 4, &aom_highbd_12_obmc_sub_pixel_variance64x16_c, + 12), + ObmcSubpelVarianceParams(4, 6, &aom_highbd_12_obmc_sub_pixel_variance16x64_c, + 12), + ObmcSubpelVarianceParams(5, 3, &aom_highbd_12_obmc_sub_pixel_variance32x8_c, + 12), + ObmcSubpelVarianceParams(3, 5, &aom_highbd_12_obmc_sub_pixel_variance8x32_c, + 12), + ObmcSubpelVarianceParams(4, 2, &aom_highbd_12_obmc_sub_pixel_variance16x4_c, + 12), + ObmcSubpelVarianceParams(2, 4, &aom_highbd_12_obmc_sub_pixel_variance4x16_c, + 12), }; -INSTANTIATE_TEST_CASE_P(C, AvxHBDObmcSubpelVarianceTest, - ::testing::ValuesIn(kArrayHBDObmcSubpelVariance_c)); +INSTANTIATE_TEST_SUITE_P(C, AvxHBDObmcSubpelVarianceTest, + ::testing::ValuesIn(kArrayHBDObmcSubpelVariance_c)); +#endif // CONFIG_AV1_HIGHBITDEPTH #if HAVE_SSE2 -INSTANTIATE_TEST_CASE_P(SSE2, SumOfSquaresTest, - ::testing::Values(aom_get_mb_ss_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, SumOfSquaresTest, + ::testing::Values(aom_get_mb_ss_sse2)); -INSTANTIATE_TEST_CASE_P(SSE2, AvxMseTest, - ::testing::Values(MseParams(4, 4, &aom_mse16x16_sse2), - MseParams(4, 3, &aom_mse16x8_sse2), - MseParams(3, 4, &aom_mse8x16_sse2), - MseParams(3, 3, &aom_mse8x8_sse2))); +INSTANTIATE_TEST_SUITE_P(SSE2, AvxMseTest, + ::testing::Values(MseParams(4, 4, &aom_mse16x16_sse2), + MseParams(4, 3, &aom_mse16x8_sse2), + MseParams(3, 4, &aom_mse8x16_sse2), + MseParams(3, 3, &aom_mse8x8_sse2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AvxVarianceTest, ::testing::Values(VarianceParams(7, 7, &aom_variance128x128_sse2), VarianceParams(7, 6, &aom_variance128x64_sse2), @@ -1525,7 +1724,7 @@ INSTANTIATE_TEST_CASE_P( VarianceParams(2, 3, &aom_variance4x8_sse2), VarianceParams(2, 2, &aom_variance4x4_sse2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(7, 7, &aom_sub_pixel_variance128x128_sse2, 0), @@ -1543,9 +1742,16 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(3, 3, &aom_sub_pixel_variance8x8_sse2, 0), SubpelVarianceParams(3, 2, &aom_sub_pixel_variance8x4_sse2, 0), SubpelVarianceParams(2, 3, &aom_sub_pixel_variance4x8_sse2, 0), - SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_sse2, 0))); + SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_sse2, 0), + + SubpelVarianceParams(6, 4, &aom_sub_pixel_variance64x16_sse2, 0), + SubpelVarianceParams(4, 6, &aom_sub_pixel_variance16x64_sse2, 0), + SubpelVarianceParams(5, 3, &aom_sub_pixel_variance32x8_sse2, 0), + SubpelVarianceParams(3, 5, &aom_sub_pixel_variance8x32_sse2, 0), + SubpelVarianceParams(4, 2, &aom_sub_pixel_variance16x4_sse2, 0), + SubpelVarianceParams(2, 4, &aom_sub_pixel_variance4x16_sse2, 0))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(7, 7, &aom_sub_pixel_avg_variance128x128_sse2, @@ -1566,10 +1772,19 @@ INSTANTIATE_TEST_CASE_P( SubpelAvgVarianceParams(3, 3, &aom_sub_pixel_avg_variance8x8_sse2, 0), SubpelAvgVarianceParams(3, 2, &aom_sub_pixel_avg_variance8x4_sse2, 0), SubpelAvgVarianceParams(2, 3, &aom_sub_pixel_avg_variance4x8_sse2, 0), - SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_sse2, 0))); + SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_sse2, 0), + + SubpelAvgVarianceParams(6, 4, &aom_sub_pixel_avg_variance64x16_sse2, 0), + SubpelAvgVarianceParams(4, 6, &aom_sub_pixel_avg_variance16x64_sse2, 0), + SubpelAvgVarianceParams(5, 3, &aom_sub_pixel_avg_variance32x8_sse2, 0), + SubpelAvgVarianceParams(3, 5, &aom_sub_pixel_avg_variance8x32_sse2, 0), + SubpelAvgVarianceParams(4, 2, &aom_sub_pixel_avg_variance16x4_sse2, 0), + SubpelAvgVarianceParams(2, 4, &aom_sub_pixel_avg_variance4x16_sse2, + 0))); +#if CONFIG_AV1_HIGHBITDEPTH #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(2, 2, &aom_highbd_8_sub_pixel_variance4x4_sse4_1, @@ -1579,7 +1794,7 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(2, 2, &aom_highbd_12_sub_pixel_variance4x4_sse4_1, 12))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(2, 2, @@ -1594,7 +1809,7 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_SSE4_1 /* TODO(debargha): This test does not support the highbd version -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE2, AvxHBDMseTest, ::testing::Values(MseParams(4, 4, &aom_highbd_12_mse16x16_sse2), MseParams(4, 3, &aom_highbd_12_mse16x8_sse2), @@ -1649,10 +1864,29 @@ const VarianceParams kArrayHBDVariance_sse2[] = { 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) + VarianceParams(3, 3, &aom_highbd_8_variance8x8_sse2, 8), + + VarianceParams(6, 4, &aom_highbd_12_variance64x16_sse2, 12), + VarianceParams(4, 6, &aom_highbd_12_variance16x64_sse2, 12), + VarianceParams(5, 3, &aom_highbd_12_variance32x8_sse2, 12), + VarianceParams(3, 5, &aom_highbd_12_variance8x32_sse2, 12), + // VarianceParams(4, 2, &aom_highbd_12_variance16x4_sse2, 12), + // VarianceParams(2, 4, &aom_highbd_12_variance4x16_sse2, 12), + VarianceParams(6, 4, &aom_highbd_10_variance64x16_sse2, 10), + VarianceParams(4, 6, &aom_highbd_10_variance16x64_sse2, 10), + VarianceParams(5, 3, &aom_highbd_10_variance32x8_sse2, 10), + VarianceParams(3, 5, &aom_highbd_10_variance8x32_sse2, 10), + // VarianceParams(4, 2, &aom_highbd_10_variance16x4_sse2, 10), + // VarianceParams(2, 4, &aom_highbd_10_variance4x16_sse2, 10), + VarianceParams(6, 4, &aom_highbd_8_variance64x16_sse2, 8), + VarianceParams(4, 6, &aom_highbd_8_variance16x64_sse2, 8), + VarianceParams(5, 3, &aom_highbd_8_variance32x8_sse2, 8), + VarianceParams(3, 5, &aom_highbd_8_variance8x32_sse2, 8), + // VarianceParams(4, 2, &aom_highbd_8_variance16x4_sse2, 8), + // VarianceParams(2, 4, &aom_highbd_8_variance4x16_sse2, 8), }; -INSTANTIATE_TEST_CASE_P(SSE2, AvxHBDVarianceTest, - ::testing::ValuesIn(kArrayHBDVariance_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AvxHBDVarianceTest, + ::testing::ValuesIn(kArrayHBDVariance_sse2)); #if HAVE_AVX2 @@ -1669,14 +1903,17 @@ const VarianceParams kArrayHBDVariance_avx2[] = { 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) + VarianceParams(3, 3, &aom_highbd_10_variance8x8_avx2, 10), }; -INSTANTIATE_TEST_CASE_P(AVX2, AvxHBDVarianceTest, - ::testing::ValuesIn(kArrayHBDVariance_avx2)); +INSTANTIATE_TEST_SUITE_P(AVX2, AvxHBDVarianceTest, + ::testing::ValuesIn(kArrayHBDVariance_avx2)); #endif // HAVE_AVX2 const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = { + SubpelVarianceParams(7, 7, &aom_highbd_12_sub_pixel_variance128x128_sse2, 12), + SubpelVarianceParams(7, 6, &aom_highbd_12_sub_pixel_variance128x64_sse2, 12), + SubpelVarianceParams(6, 7, &aom_highbd_12_sub_pixel_variance64x128_sse2, 12), SubpelVarianceParams(6, 6, &aom_highbd_12_sub_pixel_variance64x64_sse2, 12), SubpelVarianceParams(6, 5, &aom_highbd_12_sub_pixel_variance64x32_sse2, 12), SubpelVarianceParams(5, 6, &aom_highbd_12_sub_pixel_variance32x64_sse2, 12), @@ -1688,6 +1925,9 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = { SubpelVarianceParams(3, 4, &aom_highbd_12_sub_pixel_variance8x16_sse2, 12), SubpelVarianceParams(3, 3, &aom_highbd_12_sub_pixel_variance8x8_sse2, 12), SubpelVarianceParams(3, 2, &aom_highbd_12_sub_pixel_variance8x4_sse2, 12), + SubpelVarianceParams(7, 7, &aom_highbd_10_sub_pixel_variance128x128_sse2, 10), + SubpelVarianceParams(7, 6, &aom_highbd_10_sub_pixel_variance128x64_sse2, 10), + SubpelVarianceParams(6, 7, &aom_highbd_10_sub_pixel_variance64x128_sse2, 10), SubpelVarianceParams(6, 6, &aom_highbd_10_sub_pixel_variance64x64_sse2, 10), SubpelVarianceParams(6, 5, &aom_highbd_10_sub_pixel_variance64x32_sse2, 10), SubpelVarianceParams(5, 6, &aom_highbd_10_sub_pixel_variance32x64_sse2, 10), @@ -1699,6 +1939,9 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = { SubpelVarianceParams(3, 4, &aom_highbd_10_sub_pixel_variance8x16_sse2, 10), SubpelVarianceParams(3, 3, &aom_highbd_10_sub_pixel_variance8x8_sse2, 10), SubpelVarianceParams(3, 2, &aom_highbd_10_sub_pixel_variance8x4_sse2, 10), + SubpelVarianceParams(7, 7, &aom_highbd_8_sub_pixel_variance128x128_sse2, 8), + SubpelVarianceParams(7, 6, &aom_highbd_8_sub_pixel_variance128x64_sse2, 8), + SubpelVarianceParams(6, 7, &aom_highbd_8_sub_pixel_variance64x128_sse2, 8), SubpelVarianceParams(6, 6, &aom_highbd_8_sub_pixel_variance64x64_sse2, 8), SubpelVarianceParams(6, 5, &aom_highbd_8_sub_pixel_variance64x32_sse2, 8), SubpelVarianceParams(5, 6, &aom_highbd_8_sub_pixel_variance32x64_sse2, 8), @@ -1709,11 +1952,29 @@ const SubpelVarianceParams kArrayHBDSubpelVariance_sse2[] = { SubpelVarianceParams(4, 3, &aom_highbd_8_sub_pixel_variance16x8_sse2, 8), SubpelVarianceParams(3, 4, &aom_highbd_8_sub_pixel_variance8x16_sse2, 8), SubpelVarianceParams(3, 3, &aom_highbd_8_sub_pixel_variance8x8_sse2, 8), - SubpelVarianceParams(3, 2, &aom_highbd_8_sub_pixel_variance8x4_sse2, 8) + SubpelVarianceParams(3, 2, &aom_highbd_8_sub_pixel_variance8x4_sse2, 8), + + SubpelVarianceParams(6, 4, &aom_highbd_12_sub_pixel_variance64x16_sse2, 12), + SubpelVarianceParams(4, 6, &aom_highbd_12_sub_pixel_variance16x64_sse2, 12), + SubpelVarianceParams(5, 3, &aom_highbd_12_sub_pixel_variance32x8_sse2, 12), + SubpelVarianceParams(3, 5, &aom_highbd_12_sub_pixel_variance8x32_sse2, 12), + SubpelVarianceParams(4, 2, &aom_highbd_12_sub_pixel_variance16x4_sse2, 12), + // SubpelVarianceParams(2, 4, &aom_highbd_12_sub_pixel_variance4x16_sse2, 12), + SubpelVarianceParams(6, 4, &aom_highbd_10_sub_pixel_variance64x16_sse2, 10), + SubpelVarianceParams(4, 6, &aom_highbd_10_sub_pixel_variance16x64_sse2, 10), + SubpelVarianceParams(5, 3, &aom_highbd_10_sub_pixel_variance32x8_sse2, 10), + SubpelVarianceParams(3, 5, &aom_highbd_10_sub_pixel_variance8x32_sse2, 10), + SubpelVarianceParams(4, 2, &aom_highbd_10_sub_pixel_variance16x4_sse2, 10), + // SubpelVarianceParams(2, 4, &aom_highbd_10_sub_pixel_variance4x16_sse2, 10), + SubpelVarianceParams(6, 4, &aom_highbd_8_sub_pixel_variance64x16_sse2, 8), + SubpelVarianceParams(4, 6, &aom_highbd_8_sub_pixel_variance16x64_sse2, 8), + SubpelVarianceParams(5, 3, &aom_highbd_8_sub_pixel_variance32x8_sse2, 8), + SubpelVarianceParams(3, 5, &aom_highbd_8_sub_pixel_variance8x32_sse2, 8), + SubpelVarianceParams(4, 2, &aom_highbd_8_sub_pixel_variance16x4_sse2, 8), + // SubpelVarianceParams(2, 4, &aom_highbd_8_sub_pixel_variance4x16_sse2, 8), }; - -INSTANTIATE_TEST_CASE_P(SSE2, AvxHBDSubpelVarianceTest, - ::testing::ValuesIn(kArrayHBDSubpelVariance_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AvxHBDSubpelVarianceTest, + ::testing::ValuesIn(kArrayHBDSubpelVariance_sse2)); const SubpelAvgVarianceParams kArrayHBDSubpelAvgVariance_sse2[] = { SubpelAvgVarianceParams(6, 6, &aom_highbd_12_sub_pixel_avg_variance64x64_sse2, @@ -1780,15 +2041,54 @@ const SubpelAvgVarianceParams kArrayHBDSubpelAvgVariance_sse2[] = { 8), SubpelAvgVarianceParams(3, 3, &aom_highbd_8_sub_pixel_avg_variance8x8_sse2, 8), - SubpelAvgVarianceParams(3, 2, &aom_highbd_8_sub_pixel_avg_variance8x4_sse2, 8) + SubpelAvgVarianceParams(3, 2, &aom_highbd_8_sub_pixel_avg_variance8x4_sse2, + 8), + + SubpelAvgVarianceParams(6, 4, &aom_highbd_12_sub_pixel_avg_variance64x16_sse2, + 12), + SubpelAvgVarianceParams(4, 6, &aom_highbd_12_sub_pixel_avg_variance16x64_sse2, + 12), + SubpelAvgVarianceParams(5, 3, &aom_highbd_12_sub_pixel_avg_variance32x8_sse2, + 12), + SubpelAvgVarianceParams(3, 5, &aom_highbd_12_sub_pixel_avg_variance8x32_sse2, + 12), + SubpelAvgVarianceParams(4, 2, &aom_highbd_12_sub_pixel_avg_variance16x4_sse2, + 12), + // SubpelAvgVarianceParams(2, 4, + // &aom_highbd_12_sub_pixel_avg_variance4x16_sse2, 12), + SubpelAvgVarianceParams(6, 4, &aom_highbd_10_sub_pixel_avg_variance64x16_sse2, + 10), + SubpelAvgVarianceParams(4, 6, &aom_highbd_10_sub_pixel_avg_variance16x64_sse2, + 10), + SubpelAvgVarianceParams(5, 3, &aom_highbd_10_sub_pixel_avg_variance32x8_sse2, + 10), + SubpelAvgVarianceParams(3, 5, &aom_highbd_10_sub_pixel_avg_variance8x32_sse2, + 10), + SubpelAvgVarianceParams(4, 2, &aom_highbd_10_sub_pixel_avg_variance16x4_sse2, + 10), + // SubpelAvgVarianceParams(2, 4, + // &aom_highbd_10_sub_pixel_avg_variance4x16_sse2, 10), + SubpelAvgVarianceParams(6, 4, &aom_highbd_8_sub_pixel_avg_variance64x16_sse2, + 8), + SubpelAvgVarianceParams(4, 6, &aom_highbd_8_sub_pixel_avg_variance16x64_sse2, + 8), + SubpelAvgVarianceParams(5, 3, &aom_highbd_8_sub_pixel_avg_variance32x8_sse2, + 8), + SubpelAvgVarianceParams(3, 5, &aom_highbd_8_sub_pixel_avg_variance8x32_sse2, + 8), + SubpelAvgVarianceParams(4, 2, &aom_highbd_8_sub_pixel_avg_variance16x4_sse2, + 8), + // SubpelAvgVarianceParams(2, 4, + // &aom_highbd_8_sub_pixel_avg_variance4x16_sse2, 8), }; -INSTANTIATE_TEST_CASE_P(SSE2, AvxHBDSubpelAvgVarianceTest, - ::testing::ValuesIn(kArrayHBDSubpelAvgVariance_sse2)); +INSTANTIATE_TEST_SUITE_P(SSE2, AvxHBDSubpelAvgVarianceTest, + ::testing::ValuesIn(kArrayHBDSubpelAvgVariance_sse2)); #endif // HAVE_SSE2 +#endif // CONFIG_AV1_HIGHBITDEPTH #if HAVE_SSSE3 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSSE3, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(7, 7, &aom_sub_pixel_variance128x128_ssse3, 0), @@ -1806,9 +2106,16 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(3, 3, &aom_sub_pixel_variance8x8_ssse3, 0), SubpelVarianceParams(3, 2, &aom_sub_pixel_variance8x4_ssse3, 0), SubpelVarianceParams(2, 3, &aom_sub_pixel_variance4x8_ssse3, 0), - SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_ssse3, 0))); + SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_ssse3, 0), -INSTANTIATE_TEST_CASE_P( + SubpelVarianceParams(6, 4, &aom_sub_pixel_variance64x16_ssse3, 0), + SubpelVarianceParams(4, 6, &aom_sub_pixel_variance16x64_ssse3, 0), + SubpelVarianceParams(5, 3, &aom_sub_pixel_variance32x8_ssse3, 0), + SubpelVarianceParams(3, 5, &aom_sub_pixel_variance8x32_ssse3, 0), + SubpelVarianceParams(4, 2, &aom_sub_pixel_variance16x4_ssse3, 0), + SubpelVarianceParams(2, 4, &aom_sub_pixel_variance4x16_ssse3, 0))); + +INSTANTIATE_TEST_SUITE_P( SSSE3, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(7, 7, &aom_sub_pixel_avg_variance128x128_ssse3, @@ -1836,52 +2143,70 @@ INSTANTIATE_TEST_CASE_P( SubpelAvgVarianceParams(3, 3, &aom_sub_pixel_avg_variance8x8_ssse3, 0), SubpelAvgVarianceParams(3, 2, &aom_sub_pixel_avg_variance8x4_ssse3, 0), SubpelAvgVarianceParams(2, 3, &aom_sub_pixel_avg_variance4x8_ssse3, 0), - SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_ssse3, + SubpelAvgVarianceParams(2, 2, &aom_sub_pixel_avg_variance4x4_ssse3, 0), + + SubpelAvgVarianceParams(6, 4, &aom_sub_pixel_avg_variance64x16_ssse3, + 0), + SubpelAvgVarianceParams(4, 6, &aom_sub_pixel_avg_variance16x64_ssse3, + 0), + SubpelAvgVarianceParams(5, 3, &aom_sub_pixel_avg_variance32x8_ssse3, 0), + SubpelAvgVarianceParams(3, 5, &aom_sub_pixel_avg_variance8x32_ssse3, 0), + SubpelAvgVarianceParams(4, 2, &aom_sub_pixel_avg_variance16x4_ssse3, 0), + SubpelAvgVarianceParams(2, 4, &aom_sub_pixel_avg_variance4x16_ssse3, 0))); -INSTANTIATE_TEST_CASE_P( - SSSE3, AvxJntSubpelAvgVarianceTest, +INSTANTIATE_TEST_SUITE_P( + SSSE3, AvxDistWtdSubpelAvgVarianceTest, ::testing::Values( - JntSubpelAvgVarianceParams(6, 6, - &aom_jnt_sub_pixel_avg_variance64x64_ssse3, - 0), - JntSubpelAvgVarianceParams(6, 5, - &aom_jnt_sub_pixel_avg_variance64x32_ssse3, - 0), - JntSubpelAvgVarianceParams(5, 6, - &aom_jnt_sub_pixel_avg_variance32x64_ssse3, - 0), - JntSubpelAvgVarianceParams(5, 5, - &aom_jnt_sub_pixel_avg_variance32x32_ssse3, - 0), - JntSubpelAvgVarianceParams(5, 4, - &aom_jnt_sub_pixel_avg_variance32x16_ssse3, - 0), - JntSubpelAvgVarianceParams(4, 5, - &aom_jnt_sub_pixel_avg_variance16x32_ssse3, - 0), - JntSubpelAvgVarianceParams(4, 4, - &aom_jnt_sub_pixel_avg_variance16x16_ssse3, - 0), - JntSubpelAvgVarianceParams(4, 3, - &aom_jnt_sub_pixel_avg_variance16x8_ssse3, - 0), - JntSubpelAvgVarianceParams(3, 4, - &aom_jnt_sub_pixel_avg_variance8x16_ssse3, - 0), - JntSubpelAvgVarianceParams(3, 3, - &aom_jnt_sub_pixel_avg_variance8x8_ssse3, 0), - JntSubpelAvgVarianceParams(3, 2, - &aom_jnt_sub_pixel_avg_variance8x4_ssse3, 0), - JntSubpelAvgVarianceParams(2, 3, - &aom_jnt_sub_pixel_avg_variance4x8_ssse3, 0), - JntSubpelAvgVarianceParams(2, 2, - &aom_jnt_sub_pixel_avg_variance4x4_ssse3, - 0))); + DistWtdSubpelAvgVarianceParams( + 7, 7, &aom_dist_wtd_sub_pixel_avg_variance128x128_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 7, 6, &aom_dist_wtd_sub_pixel_avg_variance128x64_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 6, 7, &aom_dist_wtd_sub_pixel_avg_variance64x128_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 6, 6, &aom_dist_wtd_sub_pixel_avg_variance64x64_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 6, 5, &aom_dist_wtd_sub_pixel_avg_variance64x32_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 5, 6, &aom_dist_wtd_sub_pixel_avg_variance32x64_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 5, 5, &aom_dist_wtd_sub_pixel_avg_variance32x32_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 5, 4, &aom_dist_wtd_sub_pixel_avg_variance32x16_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 4, 5, &aom_dist_wtd_sub_pixel_avg_variance16x32_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 4, 4, &aom_dist_wtd_sub_pixel_avg_variance16x16_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 4, 3, &aom_dist_wtd_sub_pixel_avg_variance16x8_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 3, 4, &aom_dist_wtd_sub_pixel_avg_variance8x16_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 3, 3, &aom_dist_wtd_sub_pixel_avg_variance8x8_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 3, 2, &aom_dist_wtd_sub_pixel_avg_variance8x4_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 2, 3, &aom_dist_wtd_sub_pixel_avg_variance4x8_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 2, 2, &aom_dist_wtd_sub_pixel_avg_variance4x4_ssse3, 0), + + DistWtdSubpelAvgVarianceParams( + 6, 4, &aom_dist_wtd_sub_pixel_avg_variance64x16_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 4, 6, &aom_dist_wtd_sub_pixel_avg_variance16x64_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 5, 3, &aom_dist_wtd_sub_pixel_avg_variance32x8_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 3, 5, &aom_dist_wtd_sub_pixel_avg_variance8x32_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 4, 2, &aom_dist_wtd_sub_pixel_avg_variance16x4_ssse3, 0), + DistWtdSubpelAvgVarianceParams( + 2, 4, &aom_dist_wtd_sub_pixel_avg_variance4x16_ssse3, 0))); #endif // HAVE_SSSE3 #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AvxObmcSubpelVarianceTest, ::testing::Values( ObmcSubpelVarianceParams(7, 7, @@ -1915,14 +2240,28 @@ INSTANTIATE_TEST_CASE_P( ObmcSubpelVarianceParams(2, 3, &aom_obmc_sub_pixel_variance4x8_sse4_1, 0), ObmcSubpelVarianceParams(2, 2, &aom_obmc_sub_pixel_variance4x4_sse4_1, + 0), + + ObmcSubpelVarianceParams(6, 4, &aom_obmc_sub_pixel_variance64x16_sse4_1, + 0), + ObmcSubpelVarianceParams(4, 6, &aom_obmc_sub_pixel_variance16x64_sse4_1, + 0), + ObmcSubpelVarianceParams(5, 3, &aom_obmc_sub_pixel_variance32x8_sse4_1, + 0), + ObmcSubpelVarianceParams(3, 5, &aom_obmc_sub_pixel_variance8x32_sse4_1, + 0), + ObmcSubpelVarianceParams(4, 2, &aom_obmc_sub_pixel_variance16x4_sse4_1, + 0), + ObmcSubpelVarianceParams(2, 4, &aom_obmc_sub_pixel_variance4x16_sse4_1, 0))); #endif // HAVE_SSE4_1 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, AvxMseTest, - ::testing::Values(MseParams(4, 4, &aom_mse16x16_avx2))); +INSTANTIATE_TEST_SUITE_P(AVX2, AvxMseTest, + ::testing::Values(MseParams(4, 4, + &aom_mse16x16_avx2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AvxVarianceTest, ::testing::Values(VarianceParams(7, 7, &aom_variance128x128_avx2), VarianceParams(7, 6, &aom_variance128x64_avx2), @@ -1940,7 +2279,7 @@ INSTANTIATE_TEST_CASE_P( VarianceParams(4, 3, &aom_variance16x8_avx2), VarianceParams(4, 2, &aom_variance16x4_avx2))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( AVX2, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(7, 7, &aom_sub_pixel_variance128x128_avx2, 0), @@ -1950,9 +2289,14 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(6, 5, &aom_sub_pixel_variance64x32_avx2, 0), SubpelVarianceParams(5, 6, &aom_sub_pixel_variance32x64_avx2, 0), SubpelVarianceParams(5, 5, &aom_sub_pixel_variance32x32_avx2, 0), - SubpelVarianceParams(5, 4, &aom_sub_pixel_variance32x16_avx2, 0))); - -INSTANTIATE_TEST_CASE_P( + SubpelVarianceParams(5, 4, &aom_sub_pixel_variance32x16_avx2, 0), + SubpelVarianceParams(4, 6, &aom_sub_pixel_variance16x64_avx2, 0), + SubpelVarianceParams(4, 5, &aom_sub_pixel_variance16x32_avx2, 0), + SubpelVarianceParams(4, 4, &aom_sub_pixel_variance16x16_avx2, 0), + SubpelVarianceParams(4, 3, &aom_sub_pixel_variance16x8_avx2, 0), + SubpelVarianceParams(4, 2, &aom_sub_pixel_variance16x4_avx2, 0))); + +INSTANTIATE_TEST_SUITE_P( AVX2, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(7, 7, &aom_sub_pixel_avg_variance128x128_avx2, @@ -1970,16 +2314,18 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_AVX2 #if HAVE_NEON -INSTANTIATE_TEST_CASE_P(NEON, AvxSseTest, - ::testing::Values(SseParams(2, 2, - &aom_get4x4sse_cs_neon))); +INSTANTIATE_TEST_SUITE_P(NEON, AvxSseTest, + ::testing::Values(SseParams(2, 2, + &aom_get4x4sse_cs_neon))); -INSTANTIATE_TEST_CASE_P(NEON, AvxMseTest, - ::testing::Values(MseParams(4, 4, &aom_mse16x16_neon))); +INSTANTIATE_TEST_SUITE_P(NEON, AvxMseTest, + ::testing::Values(MseParams(4, 4, + &aom_mse16x16_neon))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AvxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &aom_variance64x64_neon), + ::testing::Values(VarianceParams(7, 7, &aom_variance128x128_neon), + VarianceParams(6, 6, &aom_variance64x64_neon), VarianceParams(6, 5, &aom_variance64x32_neon), VarianceParams(5, 6, &aom_variance32x64_neon), VarianceParams(5, 5, &aom_variance32x32_neon), @@ -1988,7 +2334,7 @@ INSTANTIATE_TEST_CASE_P( VarianceParams(3, 4, &aom_variance8x16_neon), VarianceParams(3, 3, &aom_variance8x8_neon))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(6, 6, &aom_sub_pixel_variance64x64_neon, 0), @@ -1998,20 +2344,20 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_NEON #if HAVE_MSA -INSTANTIATE_TEST_CASE_P(MSA, SumOfSquaresTest, - ::testing::Values(aom_get_mb_ss_msa)); +INSTANTIATE_TEST_SUITE_P(MSA, SumOfSquaresTest, + ::testing::Values(aom_get_mb_ss_msa)); -INSTANTIATE_TEST_CASE_P(MSA, AvxSseTest, - ::testing::Values(SseParams(2, 2, - &aom_get4x4sse_cs_msa))); +INSTANTIATE_TEST_SUITE_P(MSA, AvxSseTest, + ::testing::Values(SseParams(2, 2, + &aom_get4x4sse_cs_msa))); -INSTANTIATE_TEST_CASE_P(MSA, AvxMseTest, - ::testing::Values(MseParams(4, 4, &aom_mse16x16_msa), - MseParams(4, 3, &aom_mse16x8_msa), - MseParams(3, 4, &aom_mse8x16_msa), - MseParams(3, 3, &aom_mse8x8_msa))); +INSTANTIATE_TEST_SUITE_P(MSA, AvxMseTest, + ::testing::Values(MseParams(4, 4, &aom_mse16x16_msa), + MseParams(4, 3, &aom_mse16x8_msa), + MseParams(3, 4, &aom_mse8x16_msa), + MseParams(3, 3, &aom_mse8x8_msa))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( MSA, AvxVarianceTest, ::testing::Values(VarianceParams(6, 6, &aom_variance64x64_msa), VarianceParams(6, 5, &aom_variance64x32_msa), @@ -2027,7 +2373,7 @@ INSTANTIATE_TEST_CASE_P( VarianceParams(2, 3, &aom_variance4x8_msa), VarianceParams(2, 2, &aom_variance4x4_msa))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( MSA, AvxSubpelVarianceTest, ::testing::Values( SubpelVarianceParams(2, 2, &aom_sub_pixel_variance4x4_msa, 0), @@ -2044,7 +2390,7 @@ INSTANTIATE_TEST_CASE_P( SubpelVarianceParams(6, 5, &aom_sub_pixel_variance64x32_msa, 0), SubpelVarianceParams(6, 6, &aom_sub_pixel_variance64x64_msa, 0))); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( MSA, AvxSubpelAvgVarianceTest, ::testing::Values( SubpelAvgVarianceParams(6, 6, &aom_sub_pixel_avg_variance64x64_msa, 0), diff --git a/media/libaom/src/test/warp_filter_test.cc b/media/libaom/src/test/warp_filter_test.cc index 19a4e8b6a..c5e87f085 100644 --- a/media/libaom/src/test/warp_filter_test.cc +++ b/media/libaom/src/test/warp_filter_test.cc @@ -8,47 +8,58 @@ * 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 <tuple> + #include "third_party/googletest/src/googletest/include/gtest/gtest.h" #include "test/warp_filter_test_util.h" -using ::testing::make_tuple; -using ::testing::tuple; using libaom_test::ACMRandom; +#if CONFIG_AV1_HIGHBITDEPTH using libaom_test::AV1HighbdWarpFilter::AV1HighbdWarpFilterTest; +#endif using libaom_test::AV1WarpFilter::AV1WarpFilterTest; +using std::make_tuple; +using std::tuple; namespace { TEST_P(AV1WarpFilterTest, CheckOutput) { - RunCheckOutput(::testing::get<3>(GET_PARAM(0))); + RunCheckOutput(std::get<3>(GET_PARAM(0))); } TEST_P(AV1WarpFilterTest, DISABLED_Speed) { - RunSpeedTest(::testing::get<3>(GET_PARAM(0))); + RunSpeedTest(std::get<3>(GET_PARAM(0))); } -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( C, AV1WarpFilterTest, libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_c)); #if HAVE_SSE4_1 -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( SSE4_1, AV1WarpFilterTest, libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_sse4_1)); +#if CONFIG_AV1_HIGHBITDEPTH TEST_P(AV1HighbdWarpFilterTest, CheckOutput) { - RunCheckOutput(::testing::get<4>(GET_PARAM(0))); + RunCheckOutput(std::get<4>(GET_PARAM(0))); } TEST_P(AV1HighbdWarpFilterTest, DISABLED_Speed) { - RunSpeedTest(::testing::get<4>(GET_PARAM(0))); + RunSpeedTest(std::get<4>(GET_PARAM(0))); } -INSTANTIATE_TEST_CASE_P(SSE4_1, AV1HighbdWarpFilterTest, - libaom_test::AV1HighbdWarpFilter::BuildParams( - av1_highbd_warp_affine_sse4_1)); - +INSTANTIATE_TEST_SUITE_P(SSE4_1, AV1HighbdWarpFilterTest, + libaom_test::AV1HighbdWarpFilter::BuildParams( + av1_highbd_warp_affine_sse4_1)); +#endif // CONFIG_AV1_HIGHBITDEPTH #endif // HAVE_SSE4_1 +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P( + AVX2, AV1WarpFilterTest, + libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_avx2)); +#endif // HAVE_AVX2 + #if HAVE_NEON -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( NEON, AV1WarpFilterTest, libaom_test::AV1WarpFilter::BuildParams(av1_warp_affine_neon)); #endif // HAVE_NEON diff --git a/media/libaom/src/test/warp_filter_test_util.cc b/media/libaom/src/test/warp_filter_test_util.cc index 69b2ed4af..bcb0c1859 100644 --- a/media/libaom/src/test/warp_filter_test_util.cc +++ b/media/libaom/src/test/warp_filter_test_util.cc @@ -11,8 +11,8 @@ #include "aom_ports/aom_timer.h" #include "test/warp_filter_test_util.h" -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; namespace libaom_test { @@ -55,8 +55,9 @@ void generate_warped_model(libaom_test::ACMRandom *rnd, int32_t *mat, 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); + mat[5] = static_cast<int32_t>( + ((static_cast<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 @@ -65,12 +66,14 @@ void generate_warped_model(libaom_test::ACMRandom *rnd, int32_t *mat, *alpha = clamp(mat[2] - (1 << WARPEDMODEL_PREC_BITS), INT16_MIN, INT16_MAX); *beta = clamp(mat[3], INT16_MIN, INT16_MAX); - *gamma = clamp(((int64_t)mat[4] * (1 << WARPEDMODEL_PREC_BITS)) / mat[2], - INT16_MIN, INT16_MAX); - *delta = - clamp(mat[5] - (((int64_t)mat[3] * mat[4] + (mat[2] / 2)) / mat[2]) - - (1 << WARPEDMODEL_PREC_BITS), - INT16_MIN, INT16_MAX); + *gamma = static_cast<int16_t>(clamp64( + (static_cast<int64_t>(mat[4]) * (1 << WARPEDMODEL_PREC_BITS)) / mat[2], + INT16_MIN, INT16_MAX)); + *delta = static_cast<int16_t>(clamp64( + mat[5] - + ((static_cast<int64_t>(mat[3]) * mat[4] + (mat[2] / 2)) / mat[2]) - + (1 << WARPEDMODEL_PREC_BITS), + INT16_MIN, INT16_MAX)); if ((4 * abs(*alpha) + 7 * abs(*beta) >= (1 << WARPEDMODEL_PREC_BITS)) || (4 * abs(*gamma) + 4 * abs(*delta) >= (1 << WARPEDMODEL_PREC_BITS))) @@ -113,8 +116,7 @@ void AV1WarpFilterTest::RunSpeedTest(warp_affine_func test_impl) { const int border = 16; const int stride = w + 2 * border; WarpTestParam params = GET_PARAM(0); - const int out_w = ::testing::get<0>(params), - out_h = ::testing::get<1>(params); + const int out_w = std::get<0>(params), out_h = std::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); @@ -149,7 +151,7 @@ void AV1WarpFilterTest::RunSpeedTest(warp_affine_func test_impl) { int do_average = 0; conv_params = get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd); - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; const int num_loops = 1000000000 / (out_w + out_h); aom_usec_timer timer; @@ -177,9 +179,8 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) { 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); + const int out_w = std::get<0>(params), out_h = std::get<1>(params); + const int num_iters = std::get<2>(params); int i, j, sub_x, sub_y; const int bd = 8; @@ -222,9 +223,9 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) { conv_params = get_conv_params(0, 0, bd); } if (jj >= 4) { - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; } else { - conv_params.use_jnt_comp_avg = 1; + conv_params.use_dist_wtd_comp_avg = 1; conv_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; conv_params.bck_offset = quant_dist_lookup_table[ii][jj][1]; } @@ -236,9 +237,9 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) { get_conv_params_no_round(do_average, 0, dstb, out_w, 1, bd); } if (jj >= 4) { - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; } else { - conv_params.use_jnt_comp_avg = 1; + conv_params.use_dist_wtd_comp_avg = 1; conv_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; conv_params.bck_offset = quant_dist_lookup_table[ii][jj][1]; } @@ -276,6 +277,7 @@ void AV1WarpFilterTest::RunCheckOutput(warp_affine_func test_impl) { } } // namespace AV1WarpFilter +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdWarpFilter { ::testing::internal::ParamGenerator<HighbdWarpTestParams> BuildParams( highbd_warp_affine_func filter) { @@ -310,8 +312,8 @@ void AV1HighbdWarpFilterTest::RunSpeedTest(highbd_warp_affine_func test_impl) { 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 out_w = std::get<0>(param), out_h = std::get<1>(param); + const int bd = std::get<3>(param); const int mask = (1 << bd) - 1; int sub_x, sub_y; @@ -342,7 +344,7 @@ void AV1HighbdWarpFilterTest::RunSpeedTest(highbd_warp_affine_func test_impl) { sub_x = 0; sub_y = 0; int do_average = 0; - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; conv_params = get_conv_params_no_round(do_average, 0, dsta, out_w, 1, bd); const int num_loops = 1000000000 / (out_w + out_h); @@ -373,9 +375,9 @@ void AV1HighbdWarpFilterTest::RunCheckOutput( 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 out_w = std::get<0>(param), out_h = std::get<1>(param); + const int bd = std::get<3>(param); + const int num_iters = std::get<2>(param); const int mask = (1 << bd) - 1; int i, j, sub_x, sub_y; @@ -419,9 +421,9 @@ void AV1HighbdWarpFilterTest::RunCheckOutput( conv_params = get_conv_params(0, 0, bd); } if (jj >= 4) { - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; } else { - conv_params.use_jnt_comp_avg = 1; + conv_params.use_dist_wtd_comp_avg = 1; conv_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; conv_params.bck_offset = quant_dist_lookup_table[ii][jj][1]; } @@ -436,9 +438,9 @@ void AV1HighbdWarpFilterTest::RunCheckOutput( get_conv_params_no_round(do_average, 0, dstb, out_w, 1, bd); } if (jj >= 4) { - conv_params.use_jnt_comp_avg = 0; + conv_params.use_dist_wtd_comp_avg = 0; } else { - conv_params.use_jnt_comp_avg = 1; + conv_params.use_dist_wtd_comp_avg = 1; conv_params.fwd_offset = quant_dist_lookup_table[ii][jj][0]; conv_params.bck_offset = quant_dist_lookup_table[ii][jj][1]; } @@ -477,4 +479,5 @@ void AV1HighbdWarpFilterTest::RunCheckOutput( delete[] dstb; } } // namespace AV1HighbdWarpFilter +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test diff --git a/media/libaom/src/test/warp_filter_test_util.h b/media/libaom/src/test/warp_filter_test_util.h index b8998e5c8..66a6e244b 100644 --- a/media/libaom/src/test/warp_filter_test_util.h +++ b/media/libaom/src/test/warp_filter_test_util.h @@ -12,6 +12,8 @@ #ifndef AOM_TEST_WARP_FILTER_TEST_UTIL_H_ #define AOM_TEST_WARP_FILTER_TEST_UTIL_H_ +#include <tuple> + #include "config/av1_rtcd.h" #include "config/aom_dsp_rtcd.h" @@ -41,8 +43,8 @@ typedef void (*warp_affine_func)(const int32_t *mat, const uint8_t *ref, ConvolveParams *conv_params, int16_t alpha, 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; +typedef std::tuple<int, int, int, warp_affine_func> WarpTestParam; +typedef std::tuple<WarpTestParam, int, int, int, int> WarpTestParams; ::testing::internal::ParamGenerator<WarpTestParams> BuildParams( warp_affine_func filter); @@ -63,6 +65,7 @@ class AV1WarpFilterTest : public ::testing::TestWithParam<WarpTestParams> { } // namespace AV1WarpFilter +#if CONFIG_AV1_HIGHBITDEPTH namespace AV1HighbdWarpFilter { typedef void (*highbd_warp_affine_func)(const int32_t *mat, const uint16_t *ref, int width, int height, int stride, @@ -73,9 +76,9 @@ typedef void (*highbd_warp_affine_func)(const int32_t *mat, const uint16_t *ref, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta); -typedef ::testing::tuple<int, int, int, int, highbd_warp_affine_func> +typedef std::tuple<int, int, int, int, highbd_warp_affine_func> HighbdWarpTestParam; -typedef ::testing::tuple<HighbdWarpTestParam, int, int, int, int> +typedef std::tuple<HighbdWarpTestParam, int, int, int, int> HighbdWarpTestParams; ::testing::internal::ParamGenerator<HighbdWarpTestParams> BuildParams( @@ -97,6 +100,7 @@ class AV1HighbdWarpFilterTest }; } // namespace AV1HighbdWarpFilter +#endif // CONFIG_AV1_HIGHBITDEPTH } // namespace libaom_test diff --git a/media/libaom/src/test/wiener_test.cc b/media/libaom/src/test/wiener_test.cc index dfec09119..81839fd56 100644 --- a/media/libaom/src/test/wiener_test.cc +++ b/media/libaom/src/test/wiener_test.cc @@ -9,36 +9,38 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ +#include <tuple> #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 "test/acm_random.h" +#include "test/util.h" #include "config/aom_config.h" #include "config/aom_dsp_rtcd.h" #include "aom/aom_integer.h" +#include "aom_ports/aom_timer.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 { +// 8-bit-depth tests +namespace wiener_lowbd { 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) { + int src_stride, int64_t *M, int64_t *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); + uint8_t 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)); @@ -75,16 +77,16 @@ static void compute_stats_win_opt_c(int wiener_win, const uint8_t *dgd, } } - const double avg_square_sum = avg * avg * pixel_count; + const int64_t avg_square_sum = (int64_t)avg * (int64_t)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]); + M_int[l][k] + avg_square_sum - (int64_t)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]); + (int64_t)avg * (sumY[k][l] + sumY[n][m]); } } } @@ -93,7 +95,8 @@ static void compute_stats_win_opt_c(int wiener_win, const uint8_t *dgd, 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) { + int dgd_stride, int src_stride, int64_t *M, + int64_t *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); @@ -104,40 +107,47 @@ void compute_stats_opt_c(int wiener_win, const uint8_t *dgd, const uint8_t *src, } 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; + int src_stride, int64_t *M, int64_t *H); //////////////////////////////////////////////////////////////////////////////// // 8 bit //////////////////////////////////////////////////////////////////////////////// -typedef ::testing::tuple<const compute_stats_Func> WienerTestParam; +typedef std::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); + virtual void SetUp() { + src_buf = (uint8_t *)aom_memalign( + 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_buf)); + dgd_buf = (uint8_t *)aom_memalign( + 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_buf)); + target_func_ = GET_PARAM(0); + } + virtual void TearDown() { + aom_free(src_buf); + aom_free(dgd_buf); + } + 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_; + libaom_test::ACMRandom rng_; + uint8_t *src_buf; + uint8_t *dgd_buf; }; -void WienerTest::runWienerTest(const int32_t wiener_win, int32_t run_times) { +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]); + DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, 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; @@ -177,19 +187,18 @@ void WienerTest::runWienerTest(const int32_t wiener_win, int32_t run_times) { } int failed = 0; for (int i = 0; i < wiener_win2; ++i) { - if (fabs(M_ref[i] - M_test[i]) > min_error) { + if (M_ref[i] != M_test[i]) { 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]); + printf("win %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \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) { + if (H_ref[i] != H_test[i]) { 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]); + printf("win %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n", + wiener_win, iter, i, H_ref[i], H_test[i]); break; } } @@ -197,15 +206,13 @@ void WienerTest::runWienerTest(const int32_t wiener_win, int32_t run_times) { } } -void WienerTest::runWienerTest_ExtremeValues(const int32_t wiener_win) { +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]); + DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]); const int h_start = 16; const int h_end = MAX_WIENER_BLOCK; const int v_start = 16; @@ -229,19 +236,18 @@ void WienerTest::runWienerTest_ExtremeValues(const int32_t wiener_win) { int failed = 0; for (int i = 0; i < wiener_win2; ++i) { - if (fabs(M_ref[i] - M_test[i]) > min_error) { + if (M_ref[i] != M_test[i]) { 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]); + printf("win %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \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) { + if (H_ref[i] != H_test[i]) { 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]); + printf("win %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n", + wiener_win, iter, i, H_ref[i], H_test[i]); break; } } @@ -250,31 +256,332 @@ void WienerTest::runWienerTest_ExtremeValues(const int32_t wiener_win) { } TEST_P(WienerTest, RandomValues) { - runWienerTest(WIENER_WIN, 1); - runWienerTest(WIENER_WIN_CHROMA, 1); + RunWienerTest(WIENER_WIN, 1); + RunWienerTest(WIENER_WIN_CHROMA, 1); } TEST_P(WienerTest, ExtremeValues) { - runWienerTest_ExtremeValues(WIENER_WIN); - runWienerTest_ExtremeValues(WIENER_WIN_CHROMA); + RunWienerTest_ExtremeValues(WIENER_WIN); + RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA); } TEST_P(WienerTest, DISABLED_Speed) { - runWienerTest(WIENER_WIN, 200); - runWienerTest(WIENER_WIN_CHROMA, 200); + RunWienerTest(WIENER_WIN, 200); + RunWienerTest(WIENER_WIN_CHROMA, 200); } -INSTANTIATE_TEST_CASE_P(C, WienerTest, ::testing::Values(compute_stats_opt_c)); +INSTANTIATE_TEST_SUITE_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)); +INSTANTIATE_TEST_SUITE_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)); +INSTANTIATE_TEST_SUITE_P(AVX2, WienerTest, + ::testing::Values(av1_compute_stats_avx2)); +#endif // HAVE_AVX2 + +} // namespace wiener_lowbd + +#if CONFIG_AV1_HIGHBITDEPTH +// High bit-depth tests: +namespace wiener_highbd { + +static void compute_stats_highbd_win_opt_c(int wiener_win, const uint8_t *dgd8, + const uint8_t *src8, int h_start, + int h_end, int v_start, int v_end, + int dgd_stride, int src_stride, + int64_t *M, int64_t *H, + aom_bit_depth_t bit_depth) { + 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 uint16_t *src = CONVERT_TO_SHORTPTR(src8); + const uint16_t *dgd = CONVERT_TO_SHORTPTR(dgd8); + const uint16_t avg = + find_average_highbd(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)); + + memset(M, 0, sizeof(*M) * wiener_win2); + memset(H, 0, sizeof(*H) * wiener_win2 * wiener_win2); + + int64_t sumX = 0; + const uint16_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 uint16_t X1 = src[i * src_stride + j]; + const uint16_t X2 = src[i * src_stride + j + 1]; + sumX += X1 + X2; + + const uint16_t *dgd_ij = dgd_win + i * dgd_stride + j; + for (k = 0; k < wiener_win; k++) { + for (l = 0; l < wiener_win; l++) { + const uint16_t *dgd_ijkl = dgd_ij + k * dgd_stride + l; + int64_t *H_int_temp = &H_int[(l * wiener_win + k)][0]; + const uint16_t D1 = dgd_ijkl[0]; + const uint16_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]; + } + } + } + } + } + } + + uint8_t bit_depth_divider = 1; + if (bit_depth == AOM_BITS_12) + bit_depth_divider = 16; + else if (bit_depth == AOM_BITS_10) + bit_depth_divider = 4; + + const int64_t avg_square_sum = (int64_t)avg * (int64_t)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 - (int64_t)avg * (sumX + sumY[k][l]))) / + bit_depth_divider; + 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 - (int64_t)avg * (sumY[k][l] + sumY[n][m]))) / + bit_depth_divider; + } + } + } + } +} + +void compute_stats_highbd_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, int64_t *M, int64_t *H, + aom_bit_depth_t bit_depth) { + if (wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA) { + compute_stats_highbd_win_opt_c(wiener_win, dgd, src, h_start, h_end, + v_start, v_end, dgd_stride, src_stride, M, H, + bit_depth); + } else { + av1_compute_stats_highbd_c(wiener_win, dgd, src, h_start, h_end, v_start, + v_end, dgd_stride, src_stride, M, H, bit_depth); + } +} + +static const int kIterations = 100; +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, int64_t *M, int64_t *H, + aom_bit_depth_t bit_depth); + +typedef std::tuple<const compute_stats_Func> WienerTestParam; + +class WienerTestHighbd : public ::testing::TestWithParam<WienerTestParam> { + public: + virtual void SetUp() { + src_buf = (uint16_t *)aom_memalign( + 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_buf)); + dgd_buf = (uint16_t *)aom_memalign( + 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_buf)); + target_func_ = GET_PARAM(0); + } + virtual void TearDown() { + aom_free(src_buf); + aom_free(dgd_buf); + } + void RunWienerTest(const int32_t wiener_win, int32_t run_times, + aom_bit_depth_t bit_depth); + void RunWienerTest_ExtremeValues(const int32_t wiener_win, + aom_bit_depth_t bit_depth); + + private: + compute_stats_Func target_func_; + libaom_test::ACMRandom rng_; + uint16_t *src_buf; + uint16_t *dgd_buf; +}; + +void WienerTestHighbd::RunWienerTest(const int32_t wiener_win, + int32_t run_times, + aom_bit_depth_t bit_depth) { + const int32_t wiener_halfwin = wiener_win >> 1; + const int32_t wiener_win2 = wiener_win * wiener_win; + DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]); + const int h_start = ((rng_.Rand16() % (MAX_WIENER_BLOCK / 2)) & (~7)); + const 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)); + const 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_.Rand16() % (1 << bit_depth); + src_buf[i] = rng_.Rand16() % (1 << bit_depth); + } + const uint8_t *dgd8 = CONVERT_TO_BYTEPTR( + dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin); + const uint8_t *src8 = CONVERT_TO_BYTEPTR(src_buf); + + aom_usec_timer timer; + aom_usec_timer_start(&timer); + for (int i = 0; i < run_times; ++i) { + av1_compute_stats_highbd_c(wiener_win, dgd8, src8, h_start, h_end, + v_start, v_end, dgd_stride, src_stride, M_ref, + H_ref, 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) { + target_func_(wiener_win, dgd8, src8, h_start, h_end, v_start, v_end, + dgd_stride, src_stride, M_test, H_test, bit_depth); + } + aom_usec_timer_mark(&timer); + const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer)); + if (run_times > 10) { + printf("win %d bd %d %3dx%-3d:%7.2f/%7.2fns", wiener_win, bit_depth, + h_end, v_end, time1, time2); + printf("(%3.2f)\n", time1 / time2); + } + int failed = 0; + for (int i = 0; i < wiener_win2; ++i) { + if (M_ref[i] != M_test[i]) { + failed = 1; + printf("win %d bd %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 + " \n", + wiener_win, bit_depth, iter, i, M_ref[i], M_test[i]); + break; + } + } + for (int i = 0; i < wiener_win2 * wiener_win2; ++i) { + if (H_ref[i] != H_test[i]) { + failed = 1; + printf("win %d bd %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 + " \n", + wiener_win, bit_depth, iter, i, H_ref[i], H_test[i]); + break; + } + } + ASSERT_EQ(failed, 0); + } +} + +void WienerTestHighbd::RunWienerTest_ExtremeValues(const int32_t wiener_win, + aom_bit_depth_t bit_depth) { + const int32_t wiener_halfwin = wiener_win >> 1; + const int32_t wiener_win2 = wiener_win * wiener_win; + DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]); + DECLARE_ALIGNED(32, int64_t, 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] = ((uint16_t)1 << bit_depth) - 1; + src_buf[i] = ((uint16_t)1 << bit_depth) - 1; + } + const uint8_t *dgd8 = CONVERT_TO_BYTEPTR( + dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin); + const uint8_t *src8 = CONVERT_TO_BYTEPTR(src_buf); + + av1_compute_stats_highbd_c(wiener_win, dgd8, src8, h_start, h_end, v_start, + v_end, dgd_stride, src_stride, M_ref, H_ref, + bit_depth); + + target_func_(wiener_win, dgd8, src8, h_start, h_end, v_start, v_end, + dgd_stride, src_stride, M_test, H_test, bit_depth); + + int failed = 0; + for (int i = 0; i < wiener_win2; ++i) { + if (M_ref[i] != M_test[i]) { + failed = 1; + printf("win %d bd %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 + " \n", + wiener_win, bit_depth, iter, i, M_ref[i], M_test[i]); + break; + } + } + for (int i = 0; i < wiener_win2 * wiener_win2; ++i) { + if (H_ref[i] != H_test[i]) { + failed = 1; + printf("win %d bd %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 + " \n", + wiener_win, bit_depth, iter, i, H_ref[i], H_test[i]); + break; + } + } + ASSERT_EQ(failed, 0); + } +} + +TEST_P(WienerTestHighbd, RandomValues) { + RunWienerTest(WIENER_WIN, 1, AOM_BITS_8); + RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_8); + RunWienerTest(WIENER_WIN, 1, AOM_BITS_10); + RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_10); + RunWienerTest(WIENER_WIN, 1, AOM_BITS_12); + RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_12); +} + +TEST_P(WienerTestHighbd, ExtremeValues) { + RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_8); + RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_8); + RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_10); + RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_10); + RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_12); + RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_12); +} + +TEST_P(WienerTestHighbd, DISABLED_Speed) { + RunWienerTest(WIENER_WIN, 200, AOM_BITS_8); + RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_8); + RunWienerTest(WIENER_WIN, 200, AOM_BITS_10); + RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_10); + RunWienerTest(WIENER_WIN, 200, AOM_BITS_12); + RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_12); +} + +INSTANTIATE_TEST_SUITE_P(C, WienerTestHighbd, + ::testing::Values(compute_stats_highbd_opt_c)); + +#if HAVE_SSE4_1 +INSTANTIATE_TEST_SUITE_P(SSE4_1, WienerTestHighbd, + ::testing::Values(av1_compute_stats_highbd_sse4_1)); +#endif // HAVE_SSE4_1 + +#if HAVE_AVX2 +INSTANTIATE_TEST_SUITE_P(AVX2, WienerTestHighbd, + ::testing::Values(av1_compute_stats_highbd_avx2)); #endif // HAVE_AVX2 -} // namespace +} // namespace wiener_highbd +#endif // CONFIG_AV1_HIGHBITDEPTH diff --git a/media/libaom/src/test/y4m_test.cc b/media/libaom/src/test/y4m_test.cc index 6cc75ef5b..5d795fad9 100644 --- a/media/libaom/src/test/y4m_test.cc +++ b/media/libaom/src/test/y4m_test.cc @@ -121,8 +121,8 @@ TEST_P(Y4mVideoSourceTest, SourceTest) { Md5Check(t.md5raw); } -INSTANTIATE_TEST_CASE_P(C, Y4mVideoSourceTest, - ::testing::ValuesIn(kY4mTestVectors)); +INSTANTIATE_TEST_SUITE_P(C, Y4mVideoSourceTest, + ::testing::ValuesIn(kY4mTestVectors)); class Y4mVideoWriteTest : public Y4mVideoSourceTest { protected: @@ -175,6 +175,6 @@ TEST_P(Y4mVideoWriteTest, WriteTest) { Md5Check(t.md5raw); } -INSTANTIATE_TEST_CASE_P(C, Y4mVideoWriteTest, - ::testing::ValuesIn(kY4mTestVectors)); +INSTANTIATE_TEST_SUITE_P(C, Y4mVideoWriteTest, + ::testing::ValuesIn(kY4mTestVectors)); } // namespace diff --git a/media/libaom/src/test/y4m_video_source.h b/media/libaom/src/test/y4m_video_source.h index 3dea901e6..63f74f567 100644 --- a/media/libaom/src/test/y4m_video_source.h +++ b/media/libaom/src/test/y4m_video_source.h @@ -11,6 +11,7 @@ #ifndef AOM_TEST_Y4M_VIDEO_SOURCE_H_ #define AOM_TEST_Y4M_VIDEO_SOURCE_H_ #include <algorithm> +#include <memory> #include <string> #include "common/y4minput.h" @@ -41,7 +42,8 @@ class Y4mVideoSource : public VideoSource { virtual void ReadSourceToStart() { ASSERT_TRUE(input_file_ != NULL); - ASSERT_FALSE(y4m_input_open(&y4m_, input_file_, NULL, 0, 0)); + ASSERT_FALSE( + y4m_input_open(&y4m_, input_file_, NULL, 0, AOM_CSP_UNKNOWN, 0)); framerate_numerator_ = y4m_.fps_n; framerate_denominator_ = y4m_.fps_d; frame_ = 0; @@ -109,7 +111,7 @@ class Y4mVideoSource : public VideoSource { std::string file_name_; FILE *input_file_; - testing::internal::scoped_ptr<aom_image_t> img_; + std::unique_ptr<aom_image_t> img_; unsigned int start_; unsigned int limit_; unsigned int frame_; |