diff options
56 files changed, 618 insertions, 274 deletions
@@ -614,10 +614,6 @@ process_toolchain() { check_add_cflags -Wimplicit-function-declaration check_add_cflags -Wuninitialized check_add_cflags -Wunused - # -Wextra has some tricky cases. Rather than fix them all now, get the - # flag for as many files as possible and fix the remaining issues - # piecemeal. - # https://bugs.chromium.org/p/webm/issues/detail?id=1069 check_add_cflags -Wextra # check_add_cflags also adds to cxxflags. gtest does not do well with # these flags so add them explicitly to CFLAGS only. @@ -112,10 +112,8 @@ ifeq ($(CONFIG_DECODERS),yes) CODEC_DOC_SECTIONS += decoder endif -# Suppress -Wextra warnings in third party code. -$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers # Suppress -Wextra warnings in first party code pending investigation. -# https://bugs.chromium.org/p/webm/issues/detail?id=1069 +# https://bugs.chromium.org/p/webm/issues/detail?id=1246 $(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered $(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered diff --git a/test/acm_random.h b/test/acm_random.h index 5a4e6c392..ccfa20681 100644 --- a/test/acm_random.h +++ b/test/acm_random.h @@ -34,6 +34,18 @@ class ACMRandom { return (value >> 15) & 0xffff; } + int32_t Rand20Signed(void) { + // Use 20 bits: values between 524287 and -524288. + const uint32_t value = random_.Generate(1048576); + return static_cast<int32_t>(value) - 524288; + } + + int16_t Rand16Signed(void) { + // Use 16 bits: values between 32767 and -32768. + const uint32_t value = random_.Generate(65536); + return static_cast<int16_t>(value) - 32768; + } + int16_t Rand13Signed(void) { // Use 13 bits: values between 4095 and -4096. const uint32_t value = random_.Generate(8192); diff --git a/test/add_noise_test.cc b/test/add_noise_test.cc index be56dd77b..0d1893c52 100644 --- a/test/add_noise_test.cc +++ b/test/add_noise_test.cc @@ -8,6 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ #include <math.h> +#include <tuple> + #include "test/clear_system_state.h" #include "test/register_state_check.h" #include "test/util.h" @@ -26,7 +28,7 @@ typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise, int blackclamp, int whiteclamp, int width, int height, int pitch); -typedef ::testing::tuple<double, AddNoiseFunc> AddNoiseTestFPParam; +typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam; class AddNoiseTest : public ::testing::Test, public ::testing::WithParamInterface<AddNoiseTestFPParam> { @@ -125,7 +127,7 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) { vpx_free(s); } -using ::testing::make_tuple; +using std::make_tuple; INSTANTIATE_TEST_CASE_P( C, AddNoiseTest, diff --git a/test/avg_test.cc b/test/avg_test.cc index 5455f05ed..3d24f1cdb 100644 --- a/test/avg_test.cc +++ b/test/avg_test.cc @@ -11,6 +11,7 @@ #include <limits.h> #include <stdio.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -95,7 +96,7 @@ class AverageTestBase : public ::testing::Test { }; typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch); -typedef ::testing::tuple<int, int, int, int, AverageFunction> AvgFunc; +typedef std::tuple<int, int, int, int, AverageFunction> AvgFunc; class AverageTest : public AverageTestBase<uint8_t>, public ::testing::WithParamInterface<AvgFunc> { @@ -154,7 +155,7 @@ class AverageTestHBD : public AverageTestBase<uint16_t>, typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref, const int ref_stride, const int height); -typedef ::testing::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam; +typedef std::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam; class IntProRowTest : public AverageTestBase<uint8_t>, public ::testing::WithParamInterface<IntProRowParam> { @@ -202,7 +203,7 @@ class IntProRowTest : public AverageTestBase<uint8_t>, typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width); -typedef ::testing::tuple<int, IntProColFunc, IntProColFunc> IntProColParam; +typedef std::tuple<int, IntProColFunc, IntProColFunc> IntProColParam; class IntProColTest : public AverageTestBase<uint8_t>, public ::testing::WithParamInterface<IntProColParam> { @@ -227,7 +228,7 @@ class IntProColTest : public AverageTestBase<uint8_t>, }; typedef int (*SatdFunc)(const tran_low_t *coeffs, int length); -typedef ::testing::tuple<int, SatdFunc> SatdTestParam; +typedef std::tuple<int, SatdFunc> SatdTestParam; class SatdTest : public ::testing::Test, public ::testing::WithParamInterface<SatdTestParam> { @@ -250,12 +251,7 @@ class SatdTest : public ::testing::Test, for (int i = 0; i < satd_size_; ++i) src_[i] = val; } - void FillRandom() { - for (int i = 0; i < satd_size_; ++i) { - const int16_t tmp = rnd_.Rand16(); - src_[i] = (tran_low_t)tmp; - } - } + virtual void FillRandom() = 0; void Check(const int expected) { int total; @@ -266,16 +262,26 @@ class SatdTest : public ::testing::Test, tran_low_t *GetCoeff() const { return src_; } int satd_size_; + ACMRandom rnd_; + tran_low_t *src_; private: - tran_low_t *src_; SatdFunc satd_func_; - ACMRandom rnd_; +}; + +class SatdLowbdTest : public SatdTest { + protected: + virtual void FillRandom() { + for (int i = 0; i < satd_size_; ++i) { + const int16_t tmp = rnd_.Rand16Signed(); + src_[i] = (tran_low_t)tmp; + } + } }; typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); -typedef ::testing::tuple<int, BlockErrorFunc> BlockErrorTestFPParam; +typedef std::tuple<int, BlockErrorFunc> BlockErrorTestFPParam; class BlockErrorTestFP : public ::testing::Test, @@ -402,27 +408,82 @@ TEST_P(IntProColTest, Random) { RunComparison(); } -TEST_P(SatdTest, MinValue) { +TEST_P(SatdLowbdTest, MinValue) { const int kMin = -32640; const int expected = -kMin * satd_size_; FillConstant(kMin); Check(expected); } -TEST_P(SatdTest, MaxValue) { +TEST_P(SatdLowbdTest, MaxValue) { const int kMax = 32640; const int expected = kMax * satd_size_; FillConstant(kMax); Check(expected); } -TEST_P(SatdTest, Random) { +TEST_P(SatdLowbdTest, Random) { + int expected; + switch (satd_size_) { + case 16: expected = 263252; break; + case 64: expected = 1105420; break; + case 256: expected = 4252250; break; + case 1024: expected = 16876840; break; + default: + FAIL() << "Invalid satd size (" << satd_size_ + << ") valid: 16/64/256/1024"; + } + FillRandom(); + Check(expected); +} + +TEST_P(SatdLowbdTest, DISABLED_Speed) { + const int kCountSpeedTestBlock = 20000; + vpx_usec_timer timer; + const int blocksize = GET_PARAM(0); + FillRandom(); + tran_low_t *coeff = GetCoeff(); + + vpx_usec_timer_start(&timer); + for (int i = 0; i < kCountSpeedTestBlock; ++i) { + GET_PARAM(1)(coeff, blocksize); + } + vpx_usec_timer_mark(&timer); + const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer)); + printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); +} + +#if CONFIG_VP9_HIGHBITDEPTH +class SatdHighbdTest : public SatdTest { + protected: + virtual void FillRandom() { + for (int i = 0; i < satd_size_; ++i) { + src_[i] = rnd_.Rand20Signed(); + } + } +}; + +TEST_P(SatdHighbdTest, MinValue) { + const int kMin = -524280; + const int expected = -kMin * satd_size_; + FillConstant(kMin); + Check(expected); +} + +TEST_P(SatdHighbdTest, MaxValue) { + const int kMax = 524280; + const int expected = kMax * satd_size_; + FillConstant(kMax); + Check(expected); +} + +TEST_P(SatdHighbdTest, Random) { int expected; switch (satd_size_) { - case 16: expected = 205298; break; - case 64: expected = 1113950; break; - case 256: expected = 4268415; break; - case 1024: expected = 16954082; break; + case 16: expected = 5249712; break; + case 64: expected = 18362120; break; + case 256: expected = 66100520; break; + case 1024: expected = 266094734; break; default: FAIL() << "Invalid satd size (" << satd_size_ << ") valid: 16/64/256/1024"; @@ -431,7 +492,7 @@ TEST_P(SatdTest, Random) { Check(expected); } -TEST_P(SatdTest, DISABLED_Speed) { +TEST_P(SatdHighbdTest, DISABLED_Speed) { const int kCountSpeedTestBlock = 20000; vpx_usec_timer timer; const int blocksize = GET_PARAM(0); @@ -446,6 +507,7 @@ TEST_P(SatdTest, DISABLED_Speed) { const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer)); printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); } +#endif // CONFIG_VP9_HIGHBITDEPTH TEST_P(BlockErrorTestFP, MinValue) { const int64_t kMin = -32640; @@ -493,7 +555,7 @@ TEST_P(BlockErrorTestFP, DISABLED_Speed) { printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); } -using ::testing::make_tuple; +using std::make_tuple; INSTANTIATE_TEST_CASE_P( C, AverageTest, @@ -512,9 +574,15 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_sse2), make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_sse2))); #endif // HAVE_SSE2 + +INSTANTIATE_TEST_CASE_P(C, SatdHighbdTest, + ::testing::Values(make_tuple(16, &vpx_satd_c), + make_tuple(64, &vpx_satd_c), + make_tuple(256, &vpx_satd_c), + make_tuple(1024, &vpx_satd_c))); #endif // CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_CASE_P(C, SatdTest, +INSTANTIATE_TEST_CASE_P(C, SatdLowbdTest, ::testing::Values(make_tuple(16, &vpx_satd_c), make_tuple(64, &vpx_satd_c), make_tuple(256, &vpx_satd_c), @@ -551,7 +619,7 @@ INSTANTIATE_TEST_CASE_P( make_tuple(64, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c))); -INSTANTIATE_TEST_CASE_P(SSE2, SatdTest, +INSTANTIATE_TEST_CASE_P(SSE2, SatdLowbdTest, ::testing::Values(make_tuple(16, &vpx_satd_sse2), make_tuple(64, &vpx_satd_sse2), make_tuple(256, &vpx_satd_sse2), @@ -566,12 +634,21 @@ INSTANTIATE_TEST_CASE_P( #endif // HAVE_SSE2 #if HAVE_AVX2 -INSTANTIATE_TEST_CASE_P(AVX2, SatdTest, +INSTANTIATE_TEST_CASE_P(AVX2, SatdLowbdTest, ::testing::Values(make_tuple(16, &vpx_satd_avx2), make_tuple(64, &vpx_satd_avx2), make_tuple(256, &vpx_satd_avx2), make_tuple(1024, &vpx_satd_avx2))); +#if CONFIG_VP9_HIGHBITDEPTH +INSTANTIATE_TEST_CASE_P( + AVX2, SatdHighbdTest, + ::testing::Values(make_tuple(16, &vpx_highbd_satd_avx2), + make_tuple(64, &vpx_highbd_satd_avx2), + make_tuple(256, &vpx_highbd_satd_avx2), + make_tuple(1024, &vpx_highbd_satd_avx2))); +#endif // CONFIG_VP9_HIGHBITDEPTH + INSTANTIATE_TEST_CASE_P( AVX2, BlockErrorTestFP, ::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2), @@ -604,7 +681,7 @@ INSTANTIATE_TEST_CASE_P( make_tuple(64, &vpx_int_pro_col_neon, &vpx_int_pro_col_c))); -INSTANTIATE_TEST_CASE_P(NEON, SatdTest, +INSTANTIATE_TEST_CASE_P(NEON, SatdLowbdTest, ::testing::Values(make_tuple(16, &vpx_satd_neon), make_tuple(64, &vpx_satd_neon), make_tuple(256, &vpx_satd_neon), @@ -649,7 +726,7 @@ INSTANTIATE_TEST_CASE_P( // TODO(jingning): Remove the highbitdepth flag once the SIMD functions are // in place. #if !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_CASE_P(MSA, SatdTest, +INSTANTIATE_TEST_CASE_P(MSA, SatdLowbdTest, ::testing::Values(make_tuple(16, &vpx_satd_msa), make_tuple(64, &vpx_satd_msa), make_tuple(256, &vpx_satd_msa), diff --git a/test/blockiness_test.cc b/test/blockiness_test.cc index c6a3be1a3..38b4b5886 100644 --- a/test/blockiness_test.cc +++ b/test/blockiness_test.cc @@ -11,6 +11,7 @@ #include <limits.h> #include <stdio.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -141,7 +142,7 @@ class BlockinessTestBase : public ::testing::Test { }; #if CONFIG_VP9_ENCODER -typedef ::testing::tuple<int, int> BlockinessParam; +typedef std::tuple<int, int> BlockinessParam; class BlockinessVP9Test : public BlockinessTestBase, public ::testing::WithParamInterface<BlockinessParam> { @@ -208,7 +209,7 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) { } #endif // CONFIG_VP9_ENCODER -using ::testing::make_tuple; +using std::make_tuple; //------------------------------------------------------------------------------ // C functions diff --git a/test/codec_factory.h b/test/codec_factory.h index 2bfb47360..17c9512ca 100644 --- a/test/codec_factory.h +++ b/test/codec_factory.h @@ -10,6 +10,8 @@ #ifndef VPX_TEST_CODEC_FACTORY_H_ #define VPX_TEST_CODEC_FACTORY_H_ +#include <tuple> + #include "./vpx_config.h" #include "vpx/vpx_decoder.h" #include "vpx/vpx_encoder.h" @@ -53,22 +55,22 @@ class CodecFactory { template <class T1> class CodecTestWithParam : public ::testing::TestWithParam< - ::testing::tuple<const libvpx_test::CodecFactory *, T1> > {}; + std::tuple<const libvpx_test::CodecFactory *, T1> > {}; template <class T1, class T2> class CodecTestWith2Params : public ::testing::TestWithParam< - ::testing::tuple<const libvpx_test::CodecFactory *, T1, T2> > {}; + std::tuple<const libvpx_test::CodecFactory *, T1, T2> > {}; template <class T1, class T2, class T3> class CodecTestWith3Params : public ::testing::TestWithParam< - ::testing::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {}; + std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {}; template <class T1, class T2, class T3, class T4> class CodecTestWith4Params - : public ::testing::TestWithParam< ::testing::tuple< - const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {}; + : public ::testing::TestWithParam< + std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {}; /* * VP8 Codec Definitions diff --git a/test/consistency_test.cc b/test/consistency_test.cc index f6660daaa..61e15f73b 100644 --- a/test/consistency_test.cc +++ b/test/consistency_test.cc @@ -11,6 +11,7 @@ #include <limits.h> #include <stdio.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -127,7 +128,7 @@ class ConsistencyTestBase : public ::testing::Test { }; #if CONFIG_VP9_ENCODER -typedef ::testing::tuple<int, int> ConsistencyParam; +typedef std::tuple<int, int> ConsistencyParam; class ConsistencyVP9Test : public ConsistencyTestBase, public ::testing::WithParamInterface<ConsistencyParam> { @@ -198,7 +199,7 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) { } #endif // CONFIG_VP9_ENCODER -using ::testing::make_tuple; +using std::make_tuple; //------------------------------------------------------------------------------ // C functions diff --git a/test/convolve_test.cc b/test/convolve_test.cc index 0b718a511..02cc7ff5c 100644 --- a/test/convolve_test.cc +++ b/test/convolve_test.cc @@ -9,6 +9,7 @@ */ #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -77,7 +78,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(convolve_fn) \ make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \ @@ -1113,7 +1114,7 @@ TEST_P(ConvolveTest, CheckScalingFiltering) { } #endif -using ::testing::make_tuple; +using std::make_tuple; #if CONFIG_VP9_HIGHBITDEPTH #define WRAP(func, bd) \ diff --git a/test/dct16x16_test.cc b/test/dct16x16_test.cc index 872824188..9ccf2b84f 100644 --- a/test/dct16x16_test.cc +++ b/test/dct16x16_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -229,11 +230,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, int tx_type); -typedef ::testing::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> - Dct16x16Param; -typedef ::testing::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param; -typedef ::testing::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> - Idct16x16Param; +typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param; +typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param; +typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct16x16Param; void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride, int /*tx_type*/) { @@ -745,7 +744,7 @@ TEST_P(InvTrans16x16DCT, CompareReference) { CompareInvReference(ref_txfm_, thresh_); } -using ::testing::make_tuple; +using std::make_tuple; #if CONFIG_VP9_HIGHBITDEPTH INSTANTIATE_TEST_CASE_P( diff --git a/test/dct32x32_test.cc b/test/dct32x32_test.cc index dd902f584..94d6b37fa 100644 --- a/test/dct32x32_test.cc +++ b/test/dct32x32_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -67,7 +68,7 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs], typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride); typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride); -typedef ::testing::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t> +typedef std::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t> Trans32x32Param; #if CONFIG_VP9_HIGHBITDEPTH @@ -313,7 +314,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) { } } -using ::testing::make_tuple; +using std::make_tuple; #if CONFIG_VP9_HIGHBITDEPTH INSTANTIATE_TEST_CASE_P( diff --git a/test/dct_partial_test.cc b/test/dct_partial_test.cc index dd040d52a..c889e92d7 100644 --- a/test/dct_partial_test.cc +++ b/test/dct_partial_test.cc @@ -11,8 +11,8 @@ #include <math.h> #include <stdlib.h> #include <string.h> - #include <limits> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -28,8 +28,8 @@ using libvpx_test::ACMRandom; using libvpx_test::Buffer; -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; namespace { typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride); diff --git a/test/dct_test.cc b/test/dct_test.cc index 5b5ce4001..6053aee54 100644 --- a/test/dct_test.cc +++ b/test/dct_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -28,8 +29,8 @@ using libvpx_test::ACMRandom; using libvpx_test::Buffer; -using ::testing::make_tuple; -using ::testing::tuple; +using std::make_tuple; +using std::tuple; namespace { typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); diff --git a/test/decode_corrupted.cc b/test/decode_corrupted.cc index b44c378b9..b1495ce89 100644 --- a/test/decode_corrupted.cc +++ b/test/decode_corrupted.cc @@ -8,6 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <tuple> + #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/codec_factory.h" @@ -21,7 +23,7 @@ namespace { class DecodeCorruptedFrameTest : public ::libvpx_test::EncoderTest, public ::testing::TestWithParam< - ::testing::tuple<const libvpx_test::CodecFactory *> > { + std::tuple<const libvpx_test::CodecFactory *> > { public: DecodeCorruptedFrameTest() : EncoderTest(GET_PARAM(0)) {} diff --git a/test/decode_perf_test.cc b/test/decode_perf_test.cc index fed09de98..aecdd3e99 100644 --- a/test/decode_perf_test.cc +++ b/test/decode_perf_test.cc @@ -9,6 +9,8 @@ */ #include <string> +#include <tuple> + #include "test/codec_factory.h" #include "test/decode_test_driver.h" #include "test/encode_test_driver.h" @@ -21,7 +23,7 @@ #include "./ivfenc.h" #include "./vpx_version.h" -using ::testing::make_tuple; +using std::make_tuple; namespace { @@ -34,7 +36,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; const DecodePerfParam kVP9DecodePerfVectors[] = { make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1), diff --git a/test/fdct8x8_test.cc b/test/fdct8x8_test.cc index a86d9e33a..244b9740b 100644 --- a/test/fdct8x8_test.cc +++ b/test/fdct8x8_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -43,9 +44,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, int tx_type); -typedef ::testing::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param; -typedef ::testing::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param; -typedef ::testing::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param; +typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param; +typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param; +typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param; void reference_8x8_dct_1d(const double in[8], double out[8]) { const double kInvSqrt2 = 0.707106781186547524400844362104; @@ -628,7 +629,7 @@ TEST_P(InvTrans8x8DCT, CompareReference) { CompareInvReference(ref_txfm_, thresh_); } -using ::testing::make_tuple; +using std::make_tuple; #if CONFIG_VP9_HIGHBITDEPTH INSTANTIATE_TEST_CASE_P( diff --git a/test/lpf_test.cc b/test/lpf_test.cc index 1977623ea..dfdd51599 100644 --- a/test/lpf_test.cc +++ b/test/lpf_test.cc @@ -11,6 +11,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -56,8 +57,8 @@ typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0, const uint8_t *thresh1); #endif // CONFIG_VP9_HIGHBITDEPTH -typedef ::testing::tuple<loop_op_t, loop_op_t, int> loop8_param_t; -typedef ::testing::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t; +typedef std::tuple<loop_op_t, loop_op_t, int> loop8_param_t; +typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t; void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit, const int mask, const int32_t p, const int i) { @@ -402,7 +403,7 @@ TEST_P(Loop8Test9Param, ValueCheck) { << "First failed at test case " << first_failure; } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSE2 #if CONFIG_VP9_HIGHBITDEPTH diff --git a/test/partial_idct_test.cc b/test/partial_idct_test.cc index 6fd4061b5..e66a695eb 100644 --- a/test/partial_idct_test.cc +++ b/test/partial_idct_test.cc @@ -11,8 +11,8 @@ #include <math.h> #include <stdlib.h> #include <string.h> - #include <limits> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -51,8 +51,8 @@ void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) { } #endif -typedef ::testing::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc, - TX_SIZE, int, int, int> +typedef std::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc, TX_SIZE, + int, int, int> PartialInvTxfmParam; const int kMaxNumCoeffs = 1024; const int kCountTestBlock = 1000; @@ -324,7 +324,7 @@ TEST_P(PartialIDctTest, DISABLED_Speed) { << "Error: partial inverse transform produces different results"; } -using ::testing::make_tuple; +using std::make_tuple; const PartialInvTxfmParam c_partial_idct_tests[] = { #if CONFIG_VP9_HIGHBITDEPTH diff --git a/test/predict_test.cc b/test/predict_test.cc index 6420794ff..d40d9c755 100644 --- a/test/predict_test.cc +++ b/test/predict_test.cc @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -27,13 +28,13 @@ namespace { using libvpx_test::ACMRandom; -using ::testing::make_tuple; +using std::make_tuple; typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line, int xoffset, int yoffset, uint8_t *dst_ptr, int dst_pitch); -typedef ::testing::tuple<int, int, PredictFunc> PredictParam; +typedef std::tuple<int, int, PredictFunc> PredictParam; class PredictTestBase : public AbstractBench, public ::testing::TestWithParam<PredictParam> { diff --git a/test/quantize_test.cc b/test/quantize_test.cc index e06241ab8..1415ce18e 100644 --- a/test/quantize_test.cc +++ b/test/quantize_test.cc @@ -9,6 +9,7 @@ */ #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -33,10 +34,10 @@ const int kNumBlockEntries = 16; typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d); -typedef ::testing::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam; +typedef std::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam; using libvpx_test::ACMRandom; -using ::testing::make_tuple; +using std::make_tuple; // Create and populate a VP8_COMP instance which has a complete set of // quantization inputs as well as a second MACROBLOCKD for output. diff --git a/test/sum_squares_test.cc b/test/sum_squares_test.cc index e211fb4d8..d2c70f4d4 100644 --- a/test/sum_squares_test.cc +++ b/test/sum_squares_test.cc @@ -11,6 +11,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -28,7 +29,7 @@ namespace { const int kNumIterations = 10000; typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size); -typedef ::testing::tuple<SSI16Func, SSI16Func> SumSquaresParam; +typedef std::tuple<SSI16Func, SSI16Func> SumSquaresParam; class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> { public: @@ -102,7 +103,7 @@ TEST_P(SumSquaresTest, ExtremeValues) { } } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_NEON INSTANTIATE_TEST_CASE_P( diff --git a/test/superframe_test.cc b/test/superframe_test.cc index d913871c5..8c8d1ae29 100644 --- a/test/superframe_test.cc +++ b/test/superframe_test.cc @@ -8,6 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ #include <climits> +#include <tuple> + #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/codec_factory.h" #include "test/encode_test_driver.h" @@ -18,7 +20,7 @@ namespace { const int kTestMode = 0; -typedef ::testing::tuple<libvpx_test::TestMode, int> SuperframeTestParam; +typedef std::tuple<libvpx_test::TestMode, int> SuperframeTestParam; class SuperframeTest : public ::libvpx_test::EncoderTest, @@ -31,7 +33,7 @@ class SuperframeTest virtual void SetUp() { InitializeConfig(); const SuperframeTestParam input = GET_PARAM(1); - const libvpx_test::TestMode mode = ::testing::get<kTestMode>(input); + const libvpx_test::TestMode mode = std::get<kTestMode>(input); SetMode(mode); sf_count_ = 0; sf_count_max_ = INT_MAX; diff --git a/test/svc_datarate_test.cc b/test/svc_datarate_test.cc index b08666672..024345a4c 100644 --- a/test/svc_datarate_test.cc +++ b/test/svc_datarate_test.cc @@ -19,9 +19,10 @@ #include "vpx/vpx_codec.h" #include "vpx_ports/bitops.h" +namespace svc_test { namespace { -class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { +class DatarateOnePassCbrSvc : public OnePassCbrSvc { public: explicit DatarateOnePassCbrSvc(const ::libvpx_test::CodecFactory *codec) : OnePassCbrSvc(codec) { @@ -498,6 +499,7 @@ class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { } unsigned int GetMismatchFrames() { return mismatch_nframes_; } + unsigned int GetNonRefFrames() { return num_nonref_frames_; } vpx_codec_pts_t last_pts_; double timebase_; @@ -506,7 +508,6 @@ class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { double file_datarate_[VPX_MAX_LAYERS]; size_t bits_in_last_frame_; double mismatch_psnr_; - int mismatch_nframes_; int denoiser_on_; int tune_content_; int spatial_layer_id_; @@ -520,7 +521,6 @@ class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { int middle_bitrate_; int top_bitrate_; int key_frame_spacing_; - unsigned int num_nonref_frames_; int layer_framedrop_; int force_key_; int force_key_test_; @@ -537,7 +537,7 @@ class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { bool denoiser_enable_layers_; private: - void SetConfig(int num_temporal_layer) { + virtual void SetConfig(const int num_temporal_layer) { cfg_.rc_end_usage = VPX_CBR; cfg_.g_lag_in_frames = 0; cfg_.g_error_resilient = 1; @@ -555,6 +555,9 @@ class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc { cfg_.temporal_layering_mode = 0; } } + + unsigned int num_nonref_frames_; + unsigned int mismatch_nframes_; }; // Params: speed setting. @@ -603,7 +606,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TLScreenContent1) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -632,7 +635,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLForceKey) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -665,7 +668,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL2TLDynamicPatternChange) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -701,7 +704,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -739,7 +742,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -774,7 +777,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL_DisableEnableLayers) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -824,7 +827,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TL5x5MultipleRuns) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -875,7 +878,7 @@ TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassCbrSvc2SL3TL) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -926,7 +929,7 @@ TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -957,7 +960,7 @@ TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL3TL4Threads) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1009,7 +1012,7 @@ TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR, OnePassCbrSvc3SL3TL) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1040,7 +1043,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLDynamicBitrateChange) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1097,7 +1100,7 @@ TEST_P(DatarateOnePassCbrSvcDenoiser, OnePassCbrSvc2SL3TLDenoiserOn) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } #endif @@ -1151,7 +1154,7 @@ TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc3SL3TLSmallKf) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1184,7 +1187,7 @@ TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc2SL3TLSmallKf) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1216,7 +1219,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLSyncFrames) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1249,7 +1252,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL1TLSyncWithIntraOnly) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1302,7 +1305,7 @@ TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2QL1TLScreen) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1376,7 +1379,7 @@ TEST_P(DatarateOnePassCbrSvcPostencodeDrop, OnePassCbrSvc2QL1TLScreen) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -1405,3 +1408,4 @@ VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcDenoiser, VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcSmallKF, ::testing::Range(5, 10), ::testing::Range(32, 36)); } // namespace +} // namespace svc_test diff --git a/test/svc_end_to_end_test.cc b/test/svc_end_to_end_test.cc index 96ebbf9d1..eb52b0602 100644 --- a/test/svc_end_to_end_test.cc +++ b/test/svc_end_to_end_test.cc @@ -18,18 +18,97 @@ #include "vpx/vpx_codec.h" #include "vpx_ports/bitops.h" +namespace svc_test { namespace { +class ScalePartitionOnePassCbrSvc + : public OnePassCbrSvc, + public ::testing::TestWithParam<const ::libvpx_test::CodecFactory *> { + public: + ScalePartitionOnePassCbrSvc() + : OnePassCbrSvc(GetParam()), mismatch_nframes_(0), num_nonref_frames_(0) { + SetMode(::libvpx_test::kRealTime); + } + + protected: + virtual ~ScalePartitionOnePassCbrSvc() {} + + virtual void SetUp() { + InitializeConfig(); + speed_setting_ = 7; + } + + virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, + ::libvpx_test::Encoder *encoder) { + PreEncodeFrameHookSetup(video, encoder); + } + + virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { + // Keep track of number of non-reference frames, needed for mismatch check. + // Non-reference frames are top spatial and temporal layer frames, + // for TL > 0. + if (temporal_layer_id_ == number_temporal_layers_ - 1 && + temporal_layer_id_ > 0 && + pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1]) + num_nonref_frames_++; + } + + virtual void MismatchHook(const vpx_image_t * /*img1*/, + const vpx_image_t * /*img2*/) { + ++mismatch_nframes_; + } + + virtual void SetConfig(const int /*num_temporal_layer*/) {} + + unsigned int GetMismatchFrames() const { return mismatch_nframes_; } + unsigned int GetNonRefFrames() const { return num_nonref_frames_; } + + private: + unsigned int mismatch_nframes_; + unsigned int num_nonref_frames_; +}; + +TEST_P(ScalePartitionOnePassCbrSvc, OnePassCbrSvc3SL3TL1080P) { + SetSvcConfig(3, 3); + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.g_threads = 1; + cfg_.rc_dropframe_thresh = 10; + cfg_.rc_target_bitrate = 800; + cfg_.kf_max_dist = 9999; + cfg_.rc_end_usage = VPX_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 1; + cfg_.ts_rate_decimator[0] = 4; + cfg_.ts_rate_decimator[1] = 2; + cfg_.ts_rate_decimator[2] = 1; + cfg_.temporal_layering_mode = 3; + ::libvpx_test::I420VideoSource video( + "slides_code_term_web_plot.1920_1080.yuv", 1920, 1080, 30, 1, 0, 100); + // For this 3 temporal layer case, pattern repeats every 4 frames, so choose + // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2). + AssignLayerBitrates(); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); +#if CONFIG_VP9_DECODER + // The non-reference frames are expected to be mismatched frames as the + // encoder will avoid loopfilter on these frames. + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); +#endif +} + // Params: Inter layer prediction modes. -class SyncFrameOnePassCbrSvc : public ::svc_test::OnePassCbrSvc, +class SyncFrameOnePassCbrSvc : public OnePassCbrSvc, public ::libvpx_test::CodecTestWithParam<int> { public: SyncFrameOnePassCbrSvc() : OnePassCbrSvc(GET_PARAM(0)), current_video_frame_(0), - frame_to_start_decode_(0), frame_to_sync_(0), mismatch_nframes_(0), - num_nonref_frames_(0), inter_layer_pred_mode_(GET_PARAM(1)), - decode_to_layer_before_sync_(-1), decode_to_layer_after_sync_(-1), - denoiser_on_(0), intra_only_test_(false) { + frame_to_start_decode_(0), frame_to_sync_(0), + inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1), + decode_to_layer_after_sync_(-1), denoiser_on_(0), + intra_only_test_(false), mismatch_nframes_(0), num_nonref_frames_(0) { SetMode(::libvpx_test::kRealTime); memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_)); } @@ -109,12 +188,11 @@ class SyncFrameOnePassCbrSvc : public ::svc_test::OnePassCbrSvc, } unsigned int GetMismatchFrames() const { return mismatch_nframes_; } + unsigned int GetNonRefFrames() const { return num_nonref_frames_; } unsigned int current_video_frame_; unsigned int frame_to_start_decode_; unsigned int frame_to_sync_; - unsigned int mismatch_nframes_; - unsigned int num_nonref_frames_; int inter_layer_pred_mode_; int decode_to_layer_before_sync_; int decode_to_layer_after_sync_; @@ -123,7 +201,7 @@ class SyncFrameOnePassCbrSvc : public ::svc_test::OnePassCbrSvc, vpx_svc_spatial_layer_sync_t svc_layer_sync_; private: - void SetConfig(int num_temporal_layer) { + virtual void SetConfig(const int num_temporal_layer) { cfg_.rc_buf_initial_sz = 500; cfg_.rc_buf_optimal_sz = 500; cfg_.rc_buf_sz = 1000; @@ -149,6 +227,9 @@ class SyncFrameOnePassCbrSvc : public ::svc_test::OnePassCbrSvc, cfg_.temporal_layering_mode = 1; } } + + unsigned int mismatch_nframes_; + unsigned int num_nonref_frames_; }; // Test for sync layer for 1 pass CBR SVC: 3 spatial layers and @@ -175,7 +256,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLFullSync) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -202,7 +283,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncToVGA) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -229,7 +310,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToHD) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -256,7 +337,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToVGAHD) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -285,7 +366,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncFrameVGADenoise) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } #endif @@ -315,7 +396,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyQVGA) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -344,7 +425,7 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyVGA) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } @@ -369,10 +450,16 @@ TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc1SL3TLSyncFrameIntraOnlyQVGA) { #if CONFIG_VP9_DECODER // The non-reference frames are expected to be mismatched frames as the // encoder will avoid loopfilter on these frames. - EXPECT_EQ(num_nonref_frames_, GetMismatchFrames()); + EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); #endif } VP9_INSTANTIATE_TEST_CASE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3)); +INSTANTIATE_TEST_CASE_P( + VP9, ScalePartitionOnePassCbrSvc, + ::testing::Values( + static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9))); + } // namespace +} // namespace svc_test diff --git a/test/test-data.mk b/test/test-data.mk index 9f8b7e600..88f3c658f 100644 --- a/test/test-data.mk +++ b/test/test-data.mk @@ -4,6 +4,7 @@ LIBVPX_TEST_SRCS-yes += test-data.mk LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv +LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 75b136c06..cfe4df40d 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -864,3 +864,4 @@ eb198c25f861c3fe2cbd310de11eb96843019345 *invalid-crbug-1558.ivf.res c62b005a9fd32c36a1b3f67de6840330f9915e34 *invalid-crbug-1562.ivf f0cd8389948ad16085714d96567612136f6a46c5 *invalid-crbug-1562.ivf.res bac455906360b45338a16dd626ac5f19bc36a307 *desktop_office1.1280_720-020.yuv +094be4b80fa30bd227149ea16ab6476d549ea092 *slides_code_term_web_plot.1920_1080.yuv diff --git a/test/test_vector_test.cc b/test/test_vector_test.cc index c4a6359eb..f3e585dc9 100644 --- a/test/test_vector_test.cc +++ b/test/test_vector_test.cc @@ -13,6 +13,8 @@ #include <memory> #include <set> #include <string> +#include <tuple> + #include "third_party/googletest/src/include/gtest/gtest.h" #include "../tools_common.h" #include "./vpx_config.h" @@ -32,7 +34,7 @@ namespace { const int kThreads = 0; const int kFileName = 1; -typedef ::testing::tuple<int, const char *> DecodeParam; +typedef std::tuple<int, const char *> DecodeParam; class TestVectorTest : public ::libvpx_test::DecoderTest, public ::libvpx_test::CodecTestWithParam<DecodeParam> { @@ -89,12 +91,12 @@ class TestVectorTest : public ::libvpx_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); vpx_codec_flags_t flags = 0; vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); char str[256]; - cfg.threads = ::testing::get<kThreads>(input); + cfg.threads = std::get<kThreads>(input); snprintf(str, sizeof(str) / sizeof(str[0]) - 1, "file: %s threads: %d", filename.c_str(), cfg.threads); diff --git a/test/util.h b/test/util.h index 4392188d7..985f48709 100644 --- a/test/util.h +++ b/test/util.h @@ -13,11 +13,13 @@ #include <stdio.h> #include <math.h> +#include <tuple> + #include "third_party/googletest/src/include/gtest/gtest.h" #include "vpx/vpx_image.h" // Macros -#define GET_PARAM(k) ::testing::get<k>(GetParam()) +#define GET_PARAM(k) std::get<k>(GetParam()) inline double compute_psnr(const vpx_image_t *img1, const vpx_image_t *img2) { assert((img1->fmt == img2->fmt) && (img1->d_w == img2->d_w) && diff --git a/test/vp9_block_error_test.cc b/test/vp9_block_error_test.cc index fa9b6a660..71a0686d7 100644 --- a/test/vp9_block_error_test.cc +++ b/test/vp9_block_error_test.cc @@ -11,6 +11,7 @@ #include <cmath> #include <cstdlib> #include <string> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -35,7 +36,7 @@ typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff, intptr_t block_size, int64_t *ssz, int bps); -typedef ::testing::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t> +typedef std::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t> BlockErrorParam; typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff, @@ -168,7 +169,7 @@ TEST_P(BlockErrorTest, ExtremeValues) { << "First failed at test case " << first_failure; } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSE2 const BlockErrorParam sse2_block_error_tests[] = { diff --git a/test/vp9_denoiser_test.cc b/test/vp9_denoiser_test.cc index e3a057bff..47fa587fc 100644 --- a/test/vp9_denoiser_test.cc +++ b/test/vp9_denoiser_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/acm_random.h" @@ -35,8 +36,7 @@ typedef int (*Vp9DenoiserFilterFunc)(const uint8_t *sig, int sig_stride, uint8_t *avg, int avg_stride, int increase_denoising, BLOCK_SIZE bs, int motion_magnitude); -typedef ::testing::tuple<Vp9DenoiserFilterFunc, BLOCK_SIZE> - VP9DenoiserTestParam; +typedef std::tuple<Vp9DenoiserFilterFunc, BLOCK_SIZE> VP9DenoiserTestParam; class VP9DenoiserTest : public ::testing::Test, @@ -100,7 +100,7 @@ TEST_P(VP9DenoiserTest, BitexactCheck) { } } -using ::testing::make_tuple; +using std::make_tuple; // Test for all block size. #if HAVE_SSE2 diff --git a/test/vp9_quantize_test.cc b/test/vp9_quantize_test.cc index 280d55847..cce6b6f19 100644 --- a/test/vp9_quantize_test.cc +++ b/test/vp9_quantize_test.cc @@ -11,6 +11,7 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <tuple> #include "third_party/googletest/src/include/gtest/gtest.h" @@ -43,8 +44,8 @@ typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count, tran_low_t *dqcoeff, const int16_t *dequant, uint16_t *eob, const int16_t *scan, const int16_t *iscan); -typedef ::testing::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t, - int /*max_size*/, bool /*is_fp*/> +typedef std::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t, + int /*max_size*/, bool /*is_fp*/> QuantizeParam; // Wrapper for FP version which does not use zbin or quant_shift. @@ -462,7 +463,7 @@ TEST_P(VP9QuantizeTest, DISABLED_Speed) { } } -using ::testing::make_tuple; +using std::make_tuple; #if HAVE_SSE2 #if CONFIG_VP9_HIGHBITDEPTH diff --git a/third_party/libwebm/AUTHORS.TXT b/third_party/libwebm/AUTHORS.TXT index 8ab6f794c..9686ac13e 100644 --- a/third_party/libwebm/AUTHORS.TXT +++ b/third_party/libwebm/AUTHORS.TXT @@ -1,4 +1,4 @@ -# Names should be added to this file like so:
-# Name or Organization <email address>
-
-Google Inc.
+# Names should be added to this file like so: +# Name or Organization <email address> + +Google Inc. diff --git a/third_party/libwebm/README.libvpx b/third_party/libwebm/README.libvpx index 6d8b0b4cc..17b2f4715 100644 --- a/third_party/libwebm/README.libvpx +++ b/third_party/libwebm/README.libvpx @@ -1,5 +1,5 @@ URL: https://chromium.googlesource.com/webm/libwebm -Version: af81f26025b7435fa9a14ad07c58b44cf9280430 +Version: 9f23fbc50e7a76c815b1d3f0309abe1066301331 License: BSD License File: LICENSE.txt diff --git a/third_party/libwebm/common/file_util.cc b/third_party/libwebm/common/file_util.cc index 618ffc087..e6109d5a0 100644 --- a/third_party/libwebm/common/file_util.cc +++ b/third_party/libwebm/common/file_util.cc @@ -46,7 +46,7 @@ std::string GetTempFileName() { errno_t err = tmpnam_s(tmp_file_name); #else char* fname_pointer = tmpnam(tmp_file_name); - errno_t err = (fname_pointer == &tmp_file_name[0]) ? 0 : -1; + int err = (fname_pointer == &tmp_file_name[0]) ? 0 : -1; #endif if (err == 0) { return std::string(tmp_file_name); diff --git a/third_party/libwebm/common/webmids.h b/third_party/libwebm/common/webmids.h index 89d722a71..fc0c20814 100644 --- a/third_party/libwebm/common/webmids.h +++ b/third_party/libwebm/common/webmids.h @@ -93,6 +93,7 @@ enum MkvId { kMkvDisplayHeight = 0x54BA, kMkvDisplayUnit = 0x54B2, kMkvAspectRatioType = 0x54B3, + kMkvColourSpace = 0x2EB524, kMkvFrameRate = 0x2383E3, // end video // colour diff --git a/third_party/libwebm/mkvmuxer/mkvmuxer.cc b/third_party/libwebm/mkvmuxer/mkvmuxer.cc index 481771db2..512031211 100644 --- a/third_party/libwebm/mkvmuxer/mkvmuxer.cc +++ b/third_party/libwebm/mkvmuxer/mkvmuxer.cc @@ -773,6 +773,14 @@ bool Track::Write(IMkvWriter* writer) const { if (!type_ || !codec_id_) return false; + // AV1 tracks require a CodecPrivate. See + // https://github.com/Matroska-Org/matroska-specification/blob/av1-mappin/codec/av1.md + // TODO(tomfinegan): Update the above link to the AV1 Matroska mappings to + // point to a stable version once it is finalized, or our own WebM mappings + // page on webmproject.org should we decide to release them. + if (!strcmp(codec_id_, Tracks::kAv1CodecId) && !codec_private_) + return false; + // |size| may be bigger than what is written out in this function because // derived classes may write out more data in the Track element. const uint64_t payload_size = PayloadSize(); @@ -1027,19 +1035,16 @@ bool MasteringMetadata::Write(IMkvWriter* writer) const { !WriteEbmlElement(writer, libwebm::kMkvLuminanceMin, luminance_min_)) { return false; } - if (r_ && - !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX, - libwebm::kMkvPrimaryRChromaticityY)) { + if (r_ && !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX, + libwebm::kMkvPrimaryRChromaticityY)) { return false; } - if (g_ && - !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX, - libwebm::kMkvPrimaryGChromaticityY)) { + if (g_ && !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX, + libwebm::kMkvPrimaryGChromaticityY)) { return false; } - if (b_ && - !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX, - libwebm::kMkvPrimaryBChromaticityY)) { + if (b_ && !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX, + libwebm::kMkvPrimaryBChromaticityY)) { return false; } if (white_point_ && @@ -1421,6 +1426,7 @@ VideoTrack::VideoTrack(unsigned int* seed) stereo_mode_(0), alpha_mode_(0), width_(0), + colour_space_(NULL), colour_(NULL), projection_(NULL) {} @@ -1518,6 +1524,10 @@ bool VideoTrack::Write(IMkvWriter* writer) const { static_cast<uint64>(alpha_mode_))) return false; } + if (colour_space_) { + if (!WriteEbmlElement(writer, libwebm::kMkvColourSpace, colour_space_)) + return false; + } if (frame_rate_ > 0.0) { if (!WriteEbmlElement(writer, libwebm::kMkvFrameRate, static_cast<float>(frame_rate_))) { @@ -1542,6 +1552,22 @@ bool VideoTrack::Write(IMkvWriter* writer) const { return true; } +void VideoTrack::set_colour_space(const char* colour_space) { + if (colour_space) { + delete[] colour_space_; + + const size_t length = strlen(colour_space) + 1; + colour_space_ = new (std::nothrow) char[length]; // NOLINT + if (colour_space_) { +#ifdef _MSC_VER + strcpy_s(colour_space_, length, colour_space); +#else + strcpy(colour_space_, colour_space); +#endif + } + } +} + bool VideoTrack::SetColour(const Colour& colour) { std::unique_ptr<Colour> colour_ptr(new Colour()); if (!colour_ptr.get()) @@ -1625,6 +1651,8 @@ uint64_t VideoTrack::VideoPayloadSize() const { if (frame_rate_ > 0.0) size += EbmlElementSize(libwebm::kMkvFrameRate, static_cast<float>(frame_rate_)); + if (colour_space_) + size += EbmlElementSize(libwebm::kMkvColourSpace, colour_space_); if (colour_) size += colour_->ColourSize(); if (projection_) @@ -1702,9 +1730,9 @@ bool AudioTrack::Write(IMkvWriter* writer) const { const char Tracks::kOpusCodecId[] = "A_OPUS"; const char Tracks::kVorbisCodecId[] = "A_VORBIS"; +const char Tracks::kAv1CodecId[] = "V_AV1"; const char Tracks::kVp8CodecId[] = "V_VP8"; const char Tracks::kVp9CodecId[] = "V_VP9"; -const char Tracks::kVp10CodecId[] = "V_VP10"; const char Tracks::kWebVttCaptionsId[] = "D_WEBVTT/CAPTIONS"; const char Tracks::kWebVttDescriptionsId[] = "D_WEBVTT/DESCRIPTIONS"; const char Tracks::kWebVttMetadataId[] = "D_WEBVTT/METADATA"; @@ -4165,8 +4193,8 @@ bool Segment::DocTypeIsWebm() const { // TODO(vigneshv): Tweak .clang-format. const char* kWebmCodecIds[kNumCodecIds] = { Tracks::kOpusCodecId, Tracks::kVorbisCodecId, - Tracks::kVp8CodecId, Tracks::kVp9CodecId, - Tracks::kVp10CodecId, Tracks::kWebVttCaptionsId, + Tracks::kAv1CodecId, Tracks::kVp8CodecId, + Tracks::kVp9CodecId, Tracks::kWebVttCaptionsId, Tracks::kWebVttDescriptionsId, Tracks::kWebVttMetadataId, Tracks::kWebVttSubtitlesId}; diff --git a/third_party/libwebm/mkvmuxer/mkvmuxer.h b/third_party/libwebm/mkvmuxer/mkvmuxer.h index 46b0029dc..f2db37714 100644 --- a/third_party/libwebm/mkvmuxer/mkvmuxer.h +++ b/third_party/libwebm/mkvmuxer/mkvmuxer.h @@ -795,6 +795,8 @@ class VideoTrack : public Track { uint64_t alpha_mode() { return alpha_mode_; } void set_width(uint64_t width) { width_ = width; } uint64_t width() const { return width_; } + void set_colour_space(const char* colour_space); + const char* colour_space() const { return colour_space_; } Colour* colour() { return colour_; } @@ -824,6 +826,7 @@ class VideoTrack : public Track { uint64_t stereo_mode_; uint64_t alpha_mode_; uint64_t width_; + char* colour_space_; Colour* colour_; Projection* projection_; @@ -871,9 +874,9 @@ class Tracks { static const char kOpusCodecId[]; static const char kVorbisCodecId[]; + static const char kAv1CodecId[]; static const char kVp8CodecId[]; static const char kVp9CodecId[]; - static const char kVp10CodecId[]; static const char kWebVttCaptionsId[]; static const char kWebVttDescriptionsId[]; static const char kWebVttMetadataId[]; diff --git a/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc b/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc index 355d4e22b..3bff7cd51 100644 --- a/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc +++ b/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc @@ -136,9 +136,8 @@ uint64 WriteBlock(IMkvWriter* writer, const Frame* const frame, int64 timecode, return false; } - if (!frame->is_key() && - !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock, - reference_block_timestamp)) { + if (!frame->is_key() && !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock, + reference_block_timestamp)) { return false; } diff --git a/third_party/libwebm/mkvmuxer/mkvwriter.cc b/third_party/libwebm/mkvmuxer/mkvwriter.cc index 84655d802..d668384d8 100644 --- a/third_party/libwebm/mkvmuxer/mkvwriter.cc +++ b/third_party/libwebm/mkvmuxer/mkvwriter.cc @@ -78,6 +78,8 @@ int32 MkvWriter::Position(int64 position) { #ifdef _MSC_VER return _fseeki64(file_, position, SEEK_SET); +#elif defined(_WIN32) + return fseeko64(file_, static_cast<off_t>(position), SEEK_SET); #else return fseeko(file_, static_cast<off_t>(position), SEEK_SET); #endif diff --git a/third_party/libwebm/mkvparser/mkvparser.cc b/third_party/libwebm/mkvparser/mkvparser.cc index e7b76f7da..9c78ead2b 100644 --- a/third_party/libwebm/mkvparser/mkvparser.cc +++ b/third_party/libwebm/mkvparser/mkvparser.cc @@ -36,8 +36,6 @@ inline bool isnan(double val) { return std::isnan(val); } inline bool isinf(double val) { return std::isinf(val); } #endif // MSC_COMPAT -IMkvReader::~IMkvReader() {} - template <typename Type> Type* SafeArrayAlloc(unsigned long long num_elements, unsigned long long element_size) { @@ -5274,6 +5272,7 @@ bool Projection::Parse(IMkvReader* reader, long long start, long long size, VideoTrack::VideoTrack(Segment* pSegment, long long element_start, long long element_size) : Track(pSegment, element_start, element_size), + m_colour_space(NULL), m_colour(NULL), m_projection(NULL) {} @@ -5299,6 +5298,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, long long stereo_mode = 0; double rate = 0.0; + char* colour_space = NULL; IMkvReader* const pReader = pSegment->m_pReader; @@ -5312,7 +5312,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, const long long stop = pos + s.size; Colour* colour = NULL; - Projection* projection = NULL; + std::unique_ptr<Projection> projection_ptr; while (pos < stop) { long long id, size; @@ -5364,8 +5364,16 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, if (!Colour::Parse(pReader, pos, size, &colour)) return E_FILE_FORMAT_INVALID; } else if (id == libwebm::kMkvProjection) { - if (!Projection::Parse(pReader, pos, size, &projection)) + Projection* projection = NULL; + if (!Projection::Parse(pReader, pos, size, &projection)) { return E_FILE_FORMAT_INVALID; + } else { + projection_ptr.reset(projection); + } + } else if (id == libwebm::kMkvColourSpace) { + const long status = UnserializeString(pReader, pos, size, colour_space); + if (status < 0) + return status; } pos += size; // consume payload @@ -5397,7 +5405,8 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, pTrack->m_stereo_mode = stereo_mode; pTrack->m_rate = rate; pTrack->m_colour = colour; - pTrack->m_projection = projection; + pTrack->m_colour_space = colour_space; + pTrack->m_projection = projection_ptr.release(); pResult = pTrack; return 0; // success diff --git a/third_party/libwebm/mkvparser/mkvparser.h b/third_party/libwebm/mkvparser/mkvparser.h index 26c2b7e5e..848d01f03 100644 --- a/third_party/libwebm/mkvparser/mkvparser.h +++ b/third_party/libwebm/mkvparser/mkvparser.h @@ -22,7 +22,7 @@ class IMkvReader { virtual int Length(long long* total, long long* available) = 0; protected: - virtual ~IMkvReader(); + virtual ~IMkvReader() {} }; template <typename Type> @@ -527,6 +527,8 @@ class VideoTrack : public Track { Projection* GetProjection() const; + const char* GetColourSpace() const { return m_colour_space; } + private: long long m_width; long long m_height; @@ -534,7 +536,7 @@ class VideoTrack : public Track { long long m_display_height; long long m_display_unit; long long m_stereo_mode; - + char* m_colour_space; double m_rate; Colour* m_colour; diff --git a/third_party/libwebm/mkvparser/mkvreader.cc b/third_party/libwebm/mkvparser/mkvreader.cc index 23d68f508..9d19c1be5 100644 --- a/third_party/libwebm/mkvparser/mkvreader.cc +++ b/third_party/libwebm/mkvparser/mkvreader.cc @@ -118,6 +118,8 @@ int MkvReader::Read(long long offset, long len, unsigned char* buffer) { if (status) return -1; // error +#elif defined(_WIN32) + fseeko64(m_file, static_cast<off_t>(offset), SEEK_SET); #else fseeko(m_file, static_cast<off_t>(offset), SEEK_SET); #endif diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 425db009e..df4223a23 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2377,6 +2377,19 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf, #endif // TODO(jingning): Reduce the actual memory use for tpl model build up. for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) { +#if CONFIG_NON_GREEDY_MV + int sqr_bsize; + int rf_idx; + for (rf_idx = 0; rf_idx < 3; ++rf_idx) { + for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) { + CHECK_MEM_ERROR( + cm, cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize], + vpx_calloc(mi_rows * mi_cols, + sizeof(*cpi->tpl_stats[frame] + .pyramid_mv_arr[rf_idx][sqr_bsize]))); + } + } +#endif CHECK_MEM_ERROR(cm, cpi->tpl_stats[frame].tpl_stats_ptr, vpx_calloc(mi_rows * mi_cols, sizeof(*cpi->tpl_stats[frame].tpl_stats_ptr))); @@ -3873,6 +3886,9 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, set_size_independent_vars(cpi); set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); + // search method and step parameter might be changed in speed settings. + init_motion_estimation(cpi); + if (cpi->sf.copy_partition_flag) alloc_copy_partition_data(cpi); if (cpi->sf.svc_use_lowres_part && @@ -5583,39 +5599,12 @@ void init_tpl_stats(VP9_COMP *cpi) { } #if CONFIG_NON_GREEDY_MV -static void prepare_nb_full_mvs(const TplDepFrame *tpl_frame, int mi_row, - int mi_col, int rf_idx, BLOCK_SIZE bsize, - int_mv *nb_full_mvs) { - const int mi_unit = num_8x8_blocks_wide_lookup[bsize]; - const int dirs[NB_MVS_NUM][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; - int i; - for (i = 0; i < NB_MVS_NUM; ++i) { - int r = dirs[i][0] * mi_unit; - int c = dirs[i][1] * mi_unit; - if (mi_row + r >= 0 && mi_row + r < tpl_frame->mi_rows && mi_col + c >= 0 && - mi_col + c < tpl_frame->mi_cols) { - const TplDepStats *tpl_ptr = - &tpl_frame - ->tpl_stats_ptr[(mi_row + r) * tpl_frame->stride + mi_col + c]; - if (tpl_ptr->ready[rf_idx]) { - nb_full_mvs[i].as_mv = get_full_mv(&tpl_ptr->mv_arr[rf_idx].as_mv); - } else { - nb_full_mvs[i].as_int = INVALID_MV; - } - } else { - nb_full_mvs[i].as_int = INVALID_MV; - } - } -} -#endif - -#if CONFIG_NON_GREEDY_MV uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td, int frame_idx, uint8_t *cur_frame_buf, uint8_t *ref_frame_buf, int stride, BLOCK_SIZE bsize, int mi_row, int mi_col, - TplDepStats *tpl_stats, int rf_idx) { - MV *mv = &tpl_stats->mv_arr[rf_idx].as_mv; + MV *mv, int rf_idx, double *mv_dist, + double *mv_cost) { #else // CONFIG_NON_GREEDY_MV uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td, int frame_idx, uint8_t *cur_frame_buf, @@ -5661,12 +5650,11 @@ uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td, #if CONFIG_NON_GREEDY_MV (void)search_method; (void)sadpb; - prepare_nb_full_mvs(&cpi->tpl_stats[frame_idx], mi_row, mi_col, rf_idx, bsize, - nb_full_mvs); - vp9_full_pixel_diamond_new( - cpi, x, &best_ref_mv1_full, step_param, lambda, 1, &cpi->fn_ptr[bsize], - nb_full_mvs, NB_MVS_NUM, &tpl_stats->mv_arr[rf_idx].as_mv, - &tpl_stats->mv_dist[rf_idx], &tpl_stats->mv_cost[rf_idx]); + vp9_prepare_nb_full_mvs(&cpi->tpl_stats[frame_idx], mi_row, mi_col, rf_idx, + bsize, nb_full_mvs); + vp9_full_pixel_diamond_new(cpi, x, &best_ref_mv1_full, step_param, lambda, 1, + &cpi->fn_ptr[bsize], nb_full_mvs, NB_MVS_NUM, mv, + mv_dist, mv_cost); #else (void)frame_idx; (void)mi_row; @@ -5972,8 +5960,7 @@ void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, vpx_highbd_subtract_block(bh, bw, src_diff, bw, src, src_stride, dst, dst_stride, xd->bd); highbd_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - // TODO(sdeng): Implement SIMD based high bit-depth satd. - intra_cost = vpx_satd_c(coeff, pix_num); + intra_cost = vpx_highbd_satd(coeff, pix_num); } else { vpx_subtract_block(bh, bw, src_diff, bw, src, src_stride, dst, dst_stride); @@ -6000,7 +5987,8 @@ void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, #if CONFIG_NON_GREEDY_MV (void)td; - mv.as_int = tpl_stats->mv_arr[rf_idx].as_int; + mv.as_int = + get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col)->as_int; #else motion_compensated_prediction( cpi, td, frame_idx, xd->cur_buf->y_buffer + mb_y_offset, @@ -6019,7 +6007,7 @@ void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, bh, bw, src_diff, bw, xd->cur_buf->y_buffer + mb_y_offset, xd->cur_buf->y_stride, &predictor[0], bw, xd->bd); highbd_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - inter_cost = vpx_satd_c(coeff, pix_num); + inter_cost = vpx_highbd_satd(coeff, pix_num); } else { vp9_build_inter_predictor( ref_frame[rf_idx]->y_buffer + mb_y_offset, @@ -6102,6 +6090,7 @@ static void do_motion_search(VP9_COMP *cpi, ThreadData *td, int frame_idx, set_mv_limits(cm, x, mi_row, mi_col); for (rf_idx = 0; rf_idx < 3; ++rf_idx) { + int_mv *mv = get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col); if (ref_frame[rf_idx] == NULL) { tpl_stats->ready[rf_idx] = 0; continue; @@ -6111,7 +6100,8 @@ static void do_motion_search(VP9_COMP *cpi, ThreadData *td, int frame_idx, motion_compensated_prediction( cpi, td, frame_idx, xd->cur_buf->y_buffer + mb_y_offset, ref_frame[rf_idx]->y_buffer + mb_y_offset, xd->cur_buf->y_stride, bsize, - mi_row, mi_col, tpl_stats, rf_idx); + mi_row, mi_col, &mv->as_mv, rf_idx, &tpl_stats->mv_dist[rf_idx], + &tpl_stats->mv_cost[rf_idx]); } } @@ -6353,12 +6343,14 @@ void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx, &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; for (rf_idx = 0; rf_idx < 3; ++rf_idx) { #if RE_COMPUTE_MV_INCONSISTENCY + MV this_mv = + get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row, mi_col)->as_mv; MV full_mv; int_mv nb_full_mvs[NB_MVS_NUM]; - prepare_nb_full_mvs(tpl_frame, mi_row, mi_col, rf_idx, bsize, - nb_full_mvs); - full_mv.row = this_tpl_stats->mv_arr[rf_idx].as_mv.row >> 3; - full_mv.col = this_tpl_stats->mv_arr[rf_idx].as_mv.col >> 3; + vp9_prepare_nb_full_mvs(tpl_frame, mi_row, mi_col, rf_idx, bsize, + nb_full_mvs); + full_mv.row = this_mv.row >> 3; + full_mv.col = this_mv.col >> 3; this_tpl_stats->mv_cost[rf_idx] = vp9_nb_mvs_inconsistency(&full_mv, nb_full_mvs, NB_MVS_NUM); #endif // RE_COMPUTE_MV_INCONSISTENCY @@ -6412,7 +6404,7 @@ static void dump_tpl_stats(const VP9_COMP *cpi, int tpl_group_frames, if ((mi_row % mi_height) == 0 && (mi_col % mi_width) == 0) { const TplDepStats *tpl_ptr = &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; - int_mv mv = tpl_ptr->mv_arr[idx]; + int_mv mv = *get_pyramid_mv(tpl_frame, idx, bsize, mi_row, mi_col); printf("%d %d %d %d\n", mi_row, mi_col, mv.as_mv.row, mv.as_mv.col); } } diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 02814599d..5974750cf 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -297,11 +297,14 @@ typedef struct TplDepStats { int64_t inter_cost_arr[3]; int64_t recon_error_arr[3]; int64_t sse_arr[3]; - int_mv mv_arr[3]; double feature_score; #endif } TplDepStats; +#if CONFIG_NON_GREEDY_MV +#define SQUARE_BLOCK_SIZES 4 +#endif + typedef struct TplDepFrame { uint8_t is_valid; TplDepStats *tpl_stats_ptr; @@ -315,9 +318,36 @@ typedef struct TplDepFrame { double lambda; double mv_dist_sum[3]; double mv_cost_sum[3]; + int_mv *pyramid_mv_arr[3][SQUARE_BLOCK_SIZES]; #endif } TplDepFrame; +#if CONFIG_NON_GREEDY_MV +static INLINE int get_square_block_idx(BLOCK_SIZE bsize) { + if (bsize == BLOCK_4X4) { + return 0; + } + if (bsize == BLOCK_8X8) { + return 1; + } + if (bsize == BLOCK_16X16) { + return 2; + } + if (bsize == BLOCK_32X32) { + return 3; + } + printf("ERROR: non-square block size\n"); + assert(0); + return -1; +} + +static INLINE int_mv *get_pyramid_mv(const TplDepFrame *tpl_frame, int rf_idx, + BLOCK_SIZE bsize, int mi_row, int mi_col) { + return &tpl_frame->pyramid_mv_arr[rf_idx][get_square_block_idx(bsize)] + [mi_row * tpl_frame->stride + mi_col]; +} +#endif + #define TPL_DEP_COST_SCALE_LOG2 4 // TODO(jingning) All spatially adaptive variables should go to TileDataEnc. diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index e29e86576..03ac93463 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1037,23 +1037,28 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, // Other than for the first frame do a motion search. if (cm->current_video_frame > 0) { - int tmp_err, motion_error, raw_motion_error; + int tmp_err, motion_error, this_motion_error, raw_motion_error; // Assume 0,0 motion with no mv overhead. MV mv = { 0, 0 }, tmp_mv = { 0, 0 }; struct buf_2d unscaled_last_source_buf_2d; + vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; #if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { motion_error = highbd_get_prediction_error( bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd); + this_motion_error = highbd_get_prediction_error( + bsize, &x->plane[0].src, &xd->plane[0].pre[0], 8); } else { motion_error = get_prediction_error(bsize, &x->plane[0].src, &xd->plane[0].pre[0]); + this_motion_error = motion_error; } #else motion_error = get_prediction_error(bsize, &x->plane[0].src, &xd->plane[0].pre[0]); + this_motion_error = motion_error; #endif // CONFIG_VP9_HIGHBITDEPTH // Compute the motion error of the 0,0 motion using the last source @@ -1080,6 +1085,15 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, // starting point (best reference) for the search. first_pass_motion_search(cpi, x, best_ref_mv, &mv, &motion_error); + v_fn_ptr.vf = get_block_variance_fn(bsize); +#if CONFIG_VP9_HIGHBITDEPTH + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { + v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, 8); + } +#endif // CONFIG_VP9_HIGHBITDEPTH + this_motion_error = + vp9_get_mvpred_var(x, &mv, best_ref_mv, &v_fn_ptr, 0); + // If the current best reference mv is not centered on 0,0 then do a // 0,0 based search as well. if (!is_zero_mv(best_ref_mv)) { @@ -1089,6 +1103,8 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, if (tmp_err < motion_error) { motion_error = tmp_err; mv = tmp_mv; + this_motion_error = + vp9_get_mvpred_var(x, &tmp_mv, &zero_mv, &v_fn_ptr, 0); } } @@ -1275,7 +1291,7 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, int scaled_low_intra_thresh = scale_sse_threshold(cm, LOW_I_THRESH); if (this_intra_error < scaled_low_intra_thresh) { fp_acc_data->frame_noise_energy += fp_estimate_block_noise(x, bsize); - if (motion_error < scaled_low_intra_thresh) { + if (this_motion_error < scaled_low_intra_thresh) { fp_acc_data->intra_count_low += 1.0; } else { fp_acc_data->intra_count_high += 1.0; @@ -2301,9 +2317,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, for (idx = 2; idx < MAX_ARF_LAYERS; ++idx) { if (arf_depth_boost[idx] == 0) break; - arf_depth_bits[idx] = - calculate_boost_bits(rc->baseline_gf_interval - total_arfs, - arf_depth_boost[idx], total_group_bits); + arf_depth_bits[idx] = calculate_boost_bits( + rc->baseline_gf_interval - total_arfs - arf_depth_count[idx], + arf_depth_boost[idx], total_group_bits); total_group_bits -= arf_depth_bits[idx]; total_arfs += arf_depth_count[idx]; @@ -2675,8 +2691,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { } // Calculate the extra bits to be used for boosted frame(s) - gf_arf_bits = calculate_boost_bits(rc->baseline_gf_interval, rc->gfu_boost, - gf_group_bits); + gf_arf_bits = calculate_boost_bits((rc->baseline_gf_interval - 1), + rc->gfu_boost, gf_group_bits); // Adjust KF group bits and error remaining. twopass->kf_group_error_left -= gf_group_err; diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index 316227e3c..5a6717ab2 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -1879,6 +1879,34 @@ double vp9_diamond_search_sad_new(const MACROBLOCK *x, } return bestsad; } + +void vp9_prepare_nb_full_mvs(const TplDepFrame *tpl_frame, int mi_row, + int mi_col, int rf_idx, BLOCK_SIZE bsize, + int_mv *nb_full_mvs) { + const int mi_width = num_8x8_blocks_wide_lookup[bsize]; + const int mi_height = num_8x8_blocks_high_lookup[bsize]; + const int dirs[NB_MVS_NUM][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; + int i; + for (i = 0; i < NB_MVS_NUM; ++i) { + int r = dirs[i][0] * mi_height; + int c = dirs[i][1] * mi_width; + if (mi_row + r >= 0 && mi_row + r < tpl_frame->mi_rows && mi_col + c >= 0 && + mi_col + c < tpl_frame->mi_cols) { + const TplDepStats *tpl_ptr = + &tpl_frame + ->tpl_stats_ptr[(mi_row + r) * tpl_frame->stride + mi_col + c]; + int_mv *mv = + get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row + r, mi_col + c); + if (tpl_ptr->ready[rf_idx]) { + nb_full_mvs[i].as_mv = get_full_mv(&mv->as_mv); + } else { + nb_full_mvs[i].as_int = INVALID_MV; + } + } else { + nb_full_mvs[i].as_int = INVALID_MV; + } + } +} #endif // CONFIG_NON_GREEDY_MV int vp9_diamond_search_sad_c(const MACROBLOCK *x, const search_site_config *cfg, diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h index 6d89fdfdd..ab69afdcd 100644 --- a/vp9/encoder/vp9_mcomp.h +++ b/vp9/encoder/vp9_mcomp.h @@ -143,6 +143,11 @@ static INLINE MV get_full_mv(const MV *mv) { out_mv.col = mv->col >> 3; return out_mv; } + +struct TplDepFrame; +void vp9_prepare_nb_full_mvs(const struct TplDepFrame *tpl_frame, int mi_row, + int mi_col, int rf_idx, BLOCK_SIZE bsize, + int_mv *nb_full_mvs); #endif // CONFIG_NON_GREEDY_MV #ifdef __cplusplus } // extern "C" diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index fe8f24444..babfe4a33 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -233,10 +233,10 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x, } if (rv && search_subpel) { - int subpel_force_stop = cpi->sf.mv.subpel_force_stop; - if (use_base_mv && cpi->sf.base_mv_aggressive) subpel_force_stop = 2; + SUBPEL_FORCE_STOP subpel_force_stop = cpi->sf.mv.subpel_force_stop; + if (use_base_mv && cpi->sf.base_mv_aggressive) subpel_force_stop = HALF_PEL; if (cpi->sf.mv.enable_adaptive_subpel_force_stop) { - int mv_thresh = cpi->sf.mv.adapt_subpel_force_stop.mv_thresh; + const int mv_thresh = cpi->sf.mv.adapt_subpel_force_stop.mv_thresh; if (abs(tmp_mv->as_mv.row) >= mv_thresh || abs(tmp_mv->as_mv.col) >= mv_thresh) subpel_force_stop = cpi->sf.mv.adapt_subpel_force_stop.force_stop_above; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index b5c002aea..5ad68e2e5 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -417,6 +417,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { rc->rate_correction_factors[i] = 1.0; + rc->damped_adjustment[i] = 0; } rc->min_gf_interval = oxcf->min_gf_interval; @@ -720,6 +721,8 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) { int correction_factor = 100; double rate_correction_factor = get_rate_correction_factor(cpi); double adjustment_limit; + RATE_FACTOR_LEVEL rf_lvl = + cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index]; int projected_size_based_on_q = 0; @@ -746,10 +749,16 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) { correction_factor = (int)((100 * (int64_t)cpi->rc.projected_frame_size) / projected_size_based_on_q); - // More heavily damped adjustment used if we have been oscillating either side - // of target. - adjustment_limit = - 0.25 + 0.5 * VPXMIN(1, fabs(log10(0.01 * correction_factor))); + // Do not use damped adjustment for the first frame of each frame type + if (!cpi->rc.damped_adjustment[rf_lvl]) { + adjustment_limit = 1.0; + cpi->rc.damped_adjustment[rf_lvl] = 1; + } else { + // More heavily damped adjustment used if we have been oscillating either + // side of target. + adjustment_limit = + 0.25 + 0.5 * VPXMIN(1, fabs(log10(0.01 * correction_factor))); + } cpi->rc.q_2_frame = cpi->rc.q_1_frame; cpi->rc.q_1_frame = cm->base_qindex; @@ -1403,6 +1412,10 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index, int active_worst_quality = cpi->twopass.active_worst_quality; int q; int *inter_minq; + const int boost_frame = + !rc->is_src_frame_alt_ref && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame); + ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); if (oxcf->rc_mode == VPX_Q) @@ -1410,8 +1423,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index, if (frame_is_intra_only(cm)) { pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality); - } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + } else if (boost_frame) { // Use the lower of active_worst_quality and recent // average Q as basis for GF/ARF best Q limit unless last frame was // a key frame. @@ -1455,9 +1467,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index, // Extension to max or min Q if undershoot or overshoot is outside // the permitted range. - if (frame_is_intra_only(cm) || - (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { + if (frame_is_intra_only(cm) || boost_frame) { active_best_quality -= (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast); active_worst_quality += (cpi->twopass.extend_maxq / 2); @@ -1465,13 +1475,9 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index, active_best_quality -= (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast) / 2; active_worst_quality += cpi->twopass.extend_maxq; - } - // For normal frames do not allow an active minq lower than the q used for - // the last boosted frame. - if (!frame_is_intra_only(cm) && - (!(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) || - rc->is_src_frame_alt_ref)) { + // For normal frames do not allow an active minq lower than the q used for + // the last boosted frame. active_best_quality = VPXMAX(active_best_quality, rc->last_boosted_qindex); } diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index a343bd34b..a5c1f4cf0 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -195,6 +195,8 @@ typedef struct { int use_post_encode_drop; // External flag to enable post encode frame dropping, controlled by user. int ext_use_post_encode_drop; + + int damped_adjustment[RATE_FACTOR_LEVELS]; } RATE_CONTROL; struct VP9_COMP; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index b0983281d..e4a5f3e18 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -532,7 +532,7 @@ static void set_rt_speed_feature_framesize_independent( sf->adjust_partitioning_from_last_frame = cm->last_frame_type != cm->frame_type || (0 == (frames_since_key + 1) % sf->last_partitioning_redo_frequency); - sf->mv.subpel_force_stop = 1; + sf->mv.subpel_force_stop = QUARTER_PEL; for (i = 0; i < TX_SIZES; i++) { sf->intra_y_mode_mask[i] = INTRA_DC_H_V; sf->intra_uv_mode_mask[i] = INTRA_DC; @@ -709,7 +709,6 @@ static void set_rt_speed_feature_framesize_independent( // For SVC: enable use of lower resolution partition for higher resolution, // only for 3 spatial layers and when config/top resolution is above VGA. // Enable only for non-base temporal layer frames. - // TODO(jianj): Investigate webm:1578 if (cpi->use_svc && cpi->svc.use_partition_reuse && cpi->svc.number_spatial_layers == 3 && cpi->svc.temporal_layer_id > 0 && cpi->oxcf.width * cpi->oxcf.height > 640 * 480) @@ -730,7 +729,7 @@ static void set_rt_speed_feature_framesize_independent( if (cpi->row_mt && cpi->oxcf.max_threads > 1) sf->adaptive_rd_thresh_row_mt = 1; - if (content == VP9E_CONTENT_SCREEN) sf->mv.subpel_force_stop = 3; + if (content == VP9E_CONTENT_SCREEN) sf->mv.subpel_force_stop = FULL_PEL; if (content == VP9E_CONTENT_SCREEN) sf->lpf_pick = LPF_PICK_MINIMAL_LPF; // Only keep INTRA_DC mode for speed 8. if (!is_keyframe) { @@ -766,8 +765,8 @@ static void set_rt_speed_feature_framesize_independent( sf->mv.adapt_subpel_force_stop.mv_thresh = 2; if (cpi->rc.avg_frame_low_motion < 40) sf->mv.adapt_subpel_force_stop.mv_thresh = 1; - sf->mv.adapt_subpel_force_stop.force_stop_below = 1; - sf->mv.adapt_subpel_force_stop.force_stop_above = 2; + sf->mv.adapt_subpel_force_stop.force_stop_below = QUARTER_PEL; + sf->mv.adapt_subpel_force_stop.force_stop_above = HALF_PEL; // Disable partition blocks below 16x16, except for low-resolutions. if (cm->frame_type != KEY_FRAME && cm->width >= 320 && cm->height >= 240) sf->disable_16x16part_nonkey = 1; @@ -796,18 +795,11 @@ static void set_rt_speed_feature_framesize_independent( } // Special case for screen content: increase motion search on base spatial // layer when high motion is detected or previous SL0 frame was dropped. - // Avoid speed 5 for as there is an issue with SVC datarate test. - // TODO(marpan/jianj): Investigate issue at speed 5. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && cpi->oxcf.speed > 5 && + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && cpi->oxcf.speed >= 5 && cpi->svc.spatial_layer_id == 0 && (cpi->rc.high_num_blocks_with_motion || cpi->svc.last_layer_dropped[0])) { sf->mv.search_method = NSTEP; sf->mv.fullpel_search_step_param = 2; - // TODO(marpan/jianj): Investigate issue for lower setting of step_param - // for spatial layers (namely on lower layers). - if (cpi->use_svc && cm->width != cpi->oxcf.width && - cm->height != cpi->oxcf.height) - sf->mv.fullpel_search_step_param = 4; } } @@ -854,12 +846,6 @@ void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) { if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact && oxcf->max_threads > 1) sf->adaptive_rd_thresh = 0; - - // This is only used in motion vector unit test. - if (cpi->oxcf.motion_vector_unit_test == 1) - cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv; - else if (cpi->oxcf.motion_vector_unit_test == 2) - cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv; } void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { @@ -875,7 +861,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { sf->recode_loop = ALLOW_RECODE_FIRST; sf->mv.subpel_search_method = SUBPEL_TREE; sf->mv.subpel_search_level = 2; - sf->mv.subpel_force_stop = 0; + sf->mv.subpel_force_stop = EIGHTH_PEL; sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf); sf->mv.reduce_first_step_size = 0; sf->coeff_prob_appx_step = 1; @@ -992,7 +978,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { sf->optimize_coefficients = 0; } - if (sf->mv.subpel_force_stop == 3) { + if (sf->mv.subpel_force_stop == FULL_PEL) { // Whole pel only cpi->find_fractional_mv_step = vp9_skip_sub_pixel_tree; } else if (sf->mv.subpel_search_method == SUBPEL_TREE) { @@ -1005,6 +991,12 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned_evenmore; } + // This is only used in motion vector unit test. + if (cpi->oxcf.motion_vector_unit_test == 1) + cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv; + else if (cpi->oxcf.motion_vector_unit_test == 2) + cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv; + x->optimize = sf->optimize_coefficients == 1 && oxcf->pass != 1; x->min_partition_size = sf->default_min_partition_size; @@ -1022,10 +1014,4 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact && oxcf->max_threads > 1) sf->adaptive_rd_thresh = 0; - - // This is only used in motion vector unit test. - if (cpi->oxcf.motion_vector_unit_test == 1) - cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv; - else if (cpi->oxcf.motion_vector_unit_test == 2) - cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv; } diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index 02673e602..9b09ec474 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -167,15 +167,17 @@ typedef enum { ONE_LOOP_REDUCED = 1 } FAST_COEFF_UPDATE; +typedef enum { EIGHTH_PEL, QUARTER_PEL, HALF_PEL, FULL_PEL } SUBPEL_FORCE_STOP; + typedef struct ADAPT_SUBPEL_FORCE_STOP { // Threshold for full pixel motion vector; int mv_thresh; // subpel_force_stop if full pixel MV is below the threshold. - int force_stop_below; + SUBPEL_FORCE_STOP force_stop_below; // subpel_force_stop if full pixel MV is equal to or above the threshold. - int force_stop_above; + SUBPEL_FORCE_STOP force_stop_above; } ADAPT_SUBPEL_FORCE_STOP; typedef struct MV_SPEED_FEATURES { @@ -200,12 +202,8 @@ typedef struct MV_SPEED_FEATURES { // extensive subpel search. int subpel_search_level; - // Control when to stop subpel search: - // 0: Full subpel search. - // 1: Stop at quarter pixel. - // 2: Stop at half pixel. - // 3: Stop at full pixel. - int subpel_force_stop; + // When to stop subpel motion search. + SUBPEL_FORCE_STOP subpel_force_stop; // If it's enabled, different subpel_force_stop will be used for different MV. int enable_adaptive_subpel_force_stop; @@ -70,12 +70,7 @@ enum vp8_postproc_level { VP8_DEBLOCK = 1 << 0, VP8_DEMACROBLOCK = 1 << 1, VP8_ADDNOISE = 1 << 2, - VP8_DEBUG_TXT_FRAME_INFO = 1 << 3, /**< print frame information */ - VP8_DEBUG_TXT_MBLK_MODES = - 1 << 4, /**< print macro block modes over each macro block */ - VP8_DEBUG_TXT_DC_DIFF = 1 << 5, /**< print dc diff for each macro block */ - VP8_DEBUG_TXT_RATE_INFO = 1 << 6, /**< print video rate info (encoder only) */ - VP8_MFQE = 1 << 10 + VP8_MFQE = 1 << 3 }; /*!\brief post process flags diff --git a/vpx_dsp/avg.c b/vpx_dsp/avg.c index 41a6fd828..1c45e8a73 100644 --- a/vpx_dsp/avg.c +++ b/vpx_dsp/avg.c @@ -314,6 +314,19 @@ void vpx_hadamard_32x32_c(const int16_t *src_diff, ptrdiff_t src_stride, } } +#if CONFIG_VP9_HIGHBITDEPTH +// coeff: dynamic range 20 bit. +// length: value range {16, 64, 256, 1024}. +int vpx_highbd_satd_c(const tran_low_t *coeff, int length) { + int i; + int satd = 0; + for (i = 0; i < length; ++i) satd += abs(coeff[i]); + + // satd: 30 bits + return satd; +} +#endif // CONFIG_VP9_HIGHBITDEPTH + // coeff: 16 bits, dynamic range [-32640, 32640]. // length: value range {16, 64, 256, 1024}. int vpx_satd_c(const tran_low_t *coeff, int length) { diff --git a/vpx_dsp/vpx_dsp_rtcd_defs.pl b/vpx_dsp/vpx_dsp_rtcd_defs.pl index 6dc317630..7e2d922ab 100644 --- a/vpx_dsp/vpx_dsp_rtcd_defs.pl +++ b/vpx_dsp/vpx_dsp_rtcd_defs.pl @@ -796,6 +796,9 @@ if (vpx_config("CONFIG_VP9_ENCODER") eq "yes") { add_proto qw/int vpx_satd/, "const tran_low_t *coeff, int length"; specialize qw/vpx_satd avx2 sse2 neon/; + + add_proto qw/int vpx_highbd_satd/, "const tran_low_t *coeff, int length"; + specialize qw/vpx_highbd_satd avx2/; } else { add_proto qw/void vpx_hadamard_8x8/, "const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff"; specialize qw/vpx_hadamard_8x8 sse2 neon msa vsx/, "$ssse3_x86_64"; diff --git a/vpx_dsp/x86/avg_intrin_avx2.c b/vpx_dsp/x86/avg_intrin_avx2.c index f39210b6a..3f4f577a2 100644 --- a/vpx_dsp/x86/avg_intrin_avx2.c +++ b/vpx_dsp/x86/avg_intrin_avx2.c @@ -457,3 +457,26 @@ int vpx_satd_avx2(const tran_low_t *coeff, int length) { return _mm_cvtsi128_si32(accum_128); } } + +#if CONFIG_VP9_HIGHBITDEPTH +int vpx_highbd_satd_avx2(const tran_low_t *coeff, int length) { + __m256i accum = _mm256_setzero_si256(); + int i; + + for (i = 0; i < length; i += 8, coeff += 8) { + const __m256i src_line = _mm256_loadu_si256((const __m256i *)coeff); + const __m256i abs = _mm256_abs_epi32(src_line); + accum = _mm256_add_epi32(accum, abs); + } + + { // 32 bit horizontal add + const __m256i a = _mm256_srli_si256(accum, 8); + const __m256i b = _mm256_add_epi32(accum, a); + const __m256i c = _mm256_srli_epi64(b, 32); + const __m256i d = _mm256_add_epi32(b, c); + const __m128i accum_128 = _mm_add_epi32(_mm256_castsi256_si128(d), + _mm256_extractf128_si256(d, 1)); + return _mm_cvtsi128_si32(accum_128); + } +} +#endif // CONFIG_VP9_HIGHBITDEPTH |