diff options
54 files changed, 1631 insertions, 685 deletions
diff --git a/build/make/gen_msvs_proj.sh b/build/make/gen_msvs_proj.sh index 947cc6274..cff27c83f 100755 --- a/build/make/gen_msvs_proj.sh +++ b/build/make/gen_msvs_proj.sh @@ -260,12 +260,15 @@ uses_asm=${uses_asm:-false} case "${vs_ver:-8}" in 7) vs_ver_id="7.10" asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=true' ;; 8) vs_ver_id="8.00" asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=true' ;; 9) vs_ver_id="9.00" asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=false' ;; esac @@ -362,8 +365,8 @@ generate_vcproj() { PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \ RuntimeLibrary="$debug_runtime" \ WarningLevel="3" \ - Detect64BitPortabilityProblems="true" \ DebugInformationFormat="1" \ + $warn_64bit \ ;; vpx) tag Tool \ @@ -379,7 +382,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="1" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true" ;; @@ -393,7 +396,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="1" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true" ;; @@ -470,8 +473,8 @@ generate_vcproj() { RuntimeLibrary="$release_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ - Detect64BitPortabilityProblems="true" \ DebugInformationFormat="0" \ + $warn_64bit \ ;; vpx) tag Tool \ @@ -488,7 +491,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" ;; @@ -503,7 +506,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" ;; @@ -683,7 +683,7 @@ process_toolchain() { # x86 targets. ;; *) - enabled pthread_h && check_cxx "$@" <<EOF && soft_enable unit_tests + check_cxx "$@" <<EOF && soft_enable unit_tests int z; EOF ;; @@ -442,6 +442,7 @@ else include $(SRC_PATH_BARE)/third_party/googletest/gtest.mk GTEST_SRCS := $(addprefix third_party/googletest/src/,$(call enabled,GTEST_SRCS)) GTEST_OBJS=$(call objs,$(GTEST_SRCS)) +$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0 $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS) @@ -466,7 +467,7 @@ $(foreach bin,$(LIBVPX_TEST_BINS),\ lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a ))\ $(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\ $(LIBVPX_TEST_OBJS) \ - -L. -lvpx -lgtest -lpthread -lm)\ + -L. -lvpx -lgtest $(extralibs) -lm)\ )))\ $(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\ diff --git a/test/clear_system_state.h b/test/clear_system_state.h new file mode 100644 index 000000000..e24098151 --- /dev/null +++ b/test/clear_system_state.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef TEST_CLEAR_SYSTEM_STATE_H_ +#define TEST_CLEAR_SYSTEM_STATE_H_ + +#include "vpx_config.h" +extern "C" { +#if ARCH_X86 || ARCH_X86_64 +# include "vpx_ports/x86.h" +#endif +} + +namespace libvpx_test { + +// Reset system to a known state. This function should be used for all non-API +// test cases. +inline void ClearSystemState() { +#if ARCH_X86 || ARCH_X86_64 + vpx_reset_mmx_state(); +#endif +} + +} // namespace libvpx_test +#endif // TEST_CLEAR_SYSTEM_STATE_H_ diff --git a/test/convolve_test.cc b/test/convolve_test.cc index f5e0cf736..fd2bd36c1 100644 --- a/test/convolve_test.cc +++ b/test/convolve_test.cc @@ -253,7 +253,7 @@ TEST_P(ConvolveTest, GuardBlocks) { TEST_P(ConvolveTest, CopyHoriz) { uint8_t* const in = input(); uint8_t* const out = output(); - const int16_t filter8[8] = {0, 0, 0, 128, 0, 0, 0, 0}; + DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0}; REGISTER_STATE_CHECK( UUT_->h8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16, @@ -270,7 +270,7 @@ TEST_P(ConvolveTest, CopyHoriz) { TEST_P(ConvolveTest, CopyVert) { uint8_t* const in = input(); uint8_t* const out = output(); - const int16_t filter8[8] = {0, 0, 0, 128, 0, 0, 0, 0}; + DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0}; REGISTER_STATE_CHECK( UUT_->v8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16, @@ -287,7 +287,7 @@ TEST_P(ConvolveTest, CopyVert) { TEST_P(ConvolveTest, Copy2D) { uint8_t* const in = input(); uint8_t* const out = output(); - const int16_t filter8[8] = {0, 0, 0, 128, 0, 0, 0, 0}; + DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0}; REGISTER_STATE_CHECK( UUT_->hv8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16, diff --git a/test/idct_test.cc b/test/idct_test.cc index 51fb65a43..659cce05f 100644 --- a/test/idct_test.cc +++ b/test/idct_test.cc @@ -13,6 +13,7 @@ extern "C" { #include "./vpx_config.h" #include "./vp8_rtcd.h" } +#include "test/clear_system_state.h" #include "test/register_state_check.h" #include "third_party/googletest/src/include/gtest/gtest.h" @@ -32,6 +33,10 @@ class IDCTTest : public ::testing::TestWithParam<idct_fn_t> { output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1; } + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } + idct_fn_t UUT; short input[16]; unsigned char output[256]; diff --git a/test/intrapred_test.cc b/test/intrapred_test.cc index 149399024..39ec89679 100644 --- a/test/intrapred_test.cc +++ b/test/intrapred_test.cc @@ -11,6 +11,7 @@ #include <string.h> #include "test/acm_random.h" +#include "test/clear_system_state.h" #include "test/register_state_check.h" #include "third_party/googletest/src/include/gtest/gtest.h" extern "C" { @@ -25,6 +26,11 @@ namespace { using libvpx_test::ACMRandom; class IntraPredBase { + public: + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } + protected: void SetupMacroblock(uint8_t *data, int block_size, int stride, int num_planes) { diff --git a/test/pp_filter_test.cc b/test/pp_filter_test.cc index 412a57442..79896fe61 100644 --- a/test/pp_filter_test.cc +++ b/test/pp_filter_test.cc @@ -7,6 +7,7 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ +#include "test/clear_system_state.h" #include "test/register_state_check.h" #include "third_party/googletest/src/include/gtest/gtest.h" extern "C" { @@ -27,7 +28,12 @@ typedef void (*post_proc_func_t)(unsigned char *src_ptr, namespace { class Vp8PostProcessingFilterTest - : public ::testing::TestWithParam<post_proc_func_t> {}; + : public ::testing::TestWithParam<post_proc_func_t> { + public: + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } +}; // Test routine for the VP8 post-processing function // vp8_post_proc_down_and_across_mb_row_c. diff --git a/test/sad_test.cc b/test/sad_test.cc index 15667be2b..1f5435f2a 100644 --- a/test/sad_test.cc +++ b/test/sad_test.cc @@ -26,6 +26,7 @@ extern "C" { } #include "test/acm_random.h" +#include "test/clear_system_state.h" #include "test/register_state_check.h" #include "test/util.h" #include "third_party/googletest/src/include/gtest/gtest.h" @@ -67,6 +68,10 @@ class SADTestBase : public ::testing::Test { reference_data_ = NULL; } + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } + protected: // Handle blocks up to 4 blocks 64x64 with stride up to 128 static const int kDataAlignment = 16; @@ -308,6 +313,8 @@ const sad_m_by_n_fn_t sad_16x16_c_vp9 = vp9_sad16x16_c; const sad_m_by_n_fn_t sad_8x16_c_vp9 = vp9_sad8x16_c; const sad_m_by_n_fn_t sad_16x8_c_vp9 = vp9_sad16x8_c; const sad_m_by_n_fn_t sad_8x8_c_vp9 = vp9_sad8x8_c; +const sad_m_by_n_fn_t sad_8x4_c_vp9 = vp9_sad8x4_c; +const sad_m_by_n_fn_t sad_4x8_c_vp9 = vp9_sad4x8_c; const sad_m_by_n_fn_t sad_4x4_c_vp9 = vp9_sad4x4_c; #endif const sad_m_by_n_test_param_t c_tests[] = { @@ -325,6 +332,8 @@ const sad_m_by_n_test_param_t c_tests[] = { make_tuple(8, 16, sad_8x16_c_vp9), make_tuple(16, 8, sad_16x8_c_vp9), make_tuple(8, 8, sad_8x8_c_vp9), + make_tuple(8, 4, sad_8x4_c_vp9), + make_tuple(4, 8, sad_4x8_c_vp9), make_tuple(4, 4, sad_4x4_c_vp9), #endif }; @@ -420,8 +429,10 @@ INSTANTIATE_TEST_CASE_P(MMX, SADTest, ::testing::ValuesIn(mmx_tests)); #if HAVE_SSE #if CONFIG_VP9_ENCODER const sad_m_by_n_fn_t sad_4x4_sse_vp9 = vp9_sad4x4_sse; +const sad_m_by_n_fn_t sad_4x8_sse_vp9 = vp9_sad4x8_sse; INSTANTIATE_TEST_CASE_P(SSE, SADTest, ::testing::Values( - make_tuple(4, 4, sad_4x4_sse_vp9))); + make_tuple(4, 4, sad_4x4_sse_vp9), + make_tuple(4, 8, sad_4x8_sse_vp9))); const sad_n_by_n_by_4_fn_t sad_4x8x4d_sse = vp9_sad4x8x4d_sse; const sad_n_by_n_by_4_fn_t sad_4x4x4d_sse = vp9_sad4x4x4d_sse; @@ -446,6 +457,7 @@ const sad_m_by_n_fn_t sad_16x16_sse2_vp9 = vp9_sad16x16_sse2; const sad_m_by_n_fn_t sad_8x16_sse2_vp9 = vp9_sad8x16_sse2; const sad_m_by_n_fn_t sad_16x8_sse2_vp9 = vp9_sad16x8_sse2; const sad_m_by_n_fn_t sad_8x8_sse2_vp9 = vp9_sad8x8_sse2; +const sad_m_by_n_fn_t sad_8x4_sse2_vp9 = vp9_sad8x4_sse2; #endif const sad_m_by_n_test_param_t sse2_tests[] = { #if CONFIG_VP8_ENCODER @@ -462,6 +474,7 @@ const sad_m_by_n_test_param_t sse2_tests[] = { make_tuple(8, 16, sad_8x16_sse2_vp9), make_tuple(16, 8, sad_16x8_sse2_vp9), make_tuple(8, 8, sad_8x8_sse2_vp9), + make_tuple(8, 4, sad_8x4_sse2_vp9), #endif }; INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests)); diff --git a/test/sixtap_predict_test.cc b/test/sixtap_predict_test.cc index 9ab7a7347..ee4faac37 100644 --- a/test/sixtap_predict_test.cc +++ b/test/sixtap_predict_test.cc @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> #include "test/acm_random.h" +#include "test/clear_system_state.h" #include "test/register_state_check.h" #include "test/util.h" #include "third_party/googletest/src/include/gtest/gtest.h" @@ -48,6 +49,10 @@ class SixtapPredictTest : public PARAMS(int, int, sixtap_predict_fn_t) { dst_c_ = NULL; } + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } + protected: // Make test arrays big enough for 16x16 functions. Six-tap filters // need 5 extra pixels outside of the macroblock. diff --git a/test/subtract_test.cc b/test/subtract_test.cc index e7d107392..81bfb662c 100644 --- a/test/subtract_test.cc +++ b/test/subtract_test.cc @@ -10,6 +10,7 @@ #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/acm_random.h" +#include "test/clear_system_state.h" #include "test/register_state_check.h" extern "C" { #include "vpx_config.h" @@ -23,7 +24,12 @@ typedef void (*subtract_b_fn_t)(BLOCK *be, BLOCKD *bd, int pitch); namespace { -class SubtractBlockTest : public ::testing::TestWithParam<subtract_b_fn_t> {}; +class SubtractBlockTest : public ::testing::TestWithParam<subtract_b_fn_t> { + public: + virtual void TearDown() { + libvpx_test::ClearSystemState(); + } +}; using libvpx_test::ACMRandom; diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 98cdda0a2..1036d7c54 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -122,3 +122,223 @@ f95eb6214571434f1f73ab7833b9ccdf47588020 vp80-03-segmentation-1437.ivf.md5 086c56378df81b6cee264d7540a7b8f2b405c7a4 vp80-05-sharpness-1439.ivf.md5 d32dc2c4165eb266ea4c23c14a45459b363def32 vp80-05-sharpness-1440.ivf.md5 8c69dc3d8e563f56ffab5ad1e400d9e689dd23df vp80-05-sharpness-1443.ivf.md5 +c5b6fc822d7b4ed97b5a0d69e3a71d9de6cab815 vp90-00-akiyo-100.webm +1cd8ee73b53f4ecc2511effd233f9af6ecdfac7e vp90-00-akiyo-100.webm.md5 +a854b0f2313efde7767a4465afbcbe35005ffb07 vp90-00-akiyo-200.webm +b0f53ad309611246821174b642f6808cc1e670de vp90-00-akiyo-200.webm.md5 +38a5c0e5465f884474b1a5a9184685f17f961ba1 vp90-00-akiyo-300.webm +756a34417fc10dc2a49464eccaa6b7f987227b57 vp90-00-akiyo-300.webm.md5 +1047e6f19dd137ae7bbd5b93d407fc7186f8a98e vp90-00-akiyo-50.webm +0fa08a76901a6a5b2d4b58a6b20bfa5239409b9d vp90-00-akiyo-50.webm.md5 +767511b25dde2c5926f5284782a9f1e04fe7afda vp90-00-bowing-150.webm +b259c3c6afb30fd1ae7d3a563c1fe9fe6a4644cd vp90-00-bowing-150.webm.md5 +2ef831c75c021a03176536fb652196e9afc37888 vp90-00-bowing-25.webm +37d3522cd76b7bab3b5e973e2b2c51edea49ef3f vp90-00-bowing-25.webm.md5 +c1e4639f14914516ca704f38c875d01f4c06be14 vp90-00-bowing-400.webm +ca35c574512185d5f20f3b81517d6ac3333a1377 vp90-00-bowing-400.webm.md5 +e20fc293db095e52f29b891bc09458e7568e8603 vp90-00-bus-100.webm +a754ea588cc409546936c09fb1ad06b3014b94f9 vp90-00-bus-100.webm.md5 +da5eb45fa42f55ff70ec7b71999e6fd8489d12f9 vp90-00-bus-2000.webm +2a7356328eb991175cbddebd51a30018e48632f2 vp90-00-bus-2000.webm.md5 +607169c774664176aca7c7d46dabf04b9c3634e4 vp90-00-bus-300.webm +c84daa3a0290d73226b243dd630820ac97bf4fbd vp90-00-bus-300.webm.md5 +655902b54b9a8a882c11bc8bce1447f3b2085035 vp90-00-bus-4400.webm +f719ecd7b53c8e35fae735396629d1915ffc1ff9 vp90-00-bus-4400.webm.md5 +afcdca9763d233dd63fd67165a7b92ea679822af vp90-00-bus-800.webm +66e2a55560e570cae09520060f1ae315c7ea0a07 vp90-00-bus-800.webm.md5 +390b91c8566d94c3a869af77531585c38f9f78da vp90-00-cheer-1600.webm +3d47da26375a75afef0cf2123f5c808d0862e25d vp90-00-cheer-1600.webm.md5 +23419784db17a50e129e3bd030c20256cf0d6eb0 vp90-00-cheer-2800.webm +0df4676171f19e7807d719a9b8a6fadcefc8f1fc vp90-00-cheer-2800.webm.md5 +45ed3c42874d5ec88852798691cf54bfb0cf652a vp90-00-cheer-400.webm +374fd67ac9ae0e8146051b77963459c54b9eaaa2 vp90-00-cheer-400.webm.md5 +1c9459d824116a297ff0e90bed9be783005f9ac1 vp90-00-cheer-600.webm +9dc0d43f72c8eb49d51a9748fb9948495529a6b5 vp90-00-cheer-600.webm.md5 +a86c5af1929d2f929a5caf6ef847d0066086223b vp90-00-city-1200.webm +231c7f0f406e3a8d2328daee4c4466e1b4d47354 vp90-00-city-1200.webm.md5 +be9cf927e6ab517d7876925d21b3193b1373d03d vp90-00-city-2000.webm +487d60226a3a3039528a049e9c6e8243b07404e6 vp90-00-city-2000.webm.md5 +1f3cd649d5829d52c08da3323baa86b1dcf2d2de vp90-00-city-300.webm +8e3b38cfa2be757e46ea12cff11762cb50134615 vp90-00-city-300.webm.md5 +286f6ea64c33ce735b5b7806aac4ca5ee331af66 vp90-00-city-600.webm +7c51ead147ef4029094a2b455239090c1999d8fe vp90-00-city-600.webm.md5 +f7ecbd63bed06ed15afe0ba2a192f2cf7943714c vp90-00-coastguard-1200.webm +8c8fed2c64cc8fb330e9200e1e0f58a79b953b79 vp90-00-coastguard-1200.webm.md5 +2e63178e5b2c2cc84226df2b514c4dde46c32d70 vp90-00-coastguard-200.webm +128f2b22fdcfd02bc50e63b1cd6d40c0cc4998d6 vp90-00-coastguard-200.webm.md5 +97b779617d3c1ca8f50beda7126be5df913d071d vp90-00-coastguard-3600.webm +0da0ab4794439e6b8ab9ced41239e1307686be69 vp90-00-coastguard-3600.webm.md5 +5e060d66573a40f7f0a46ae9b6acb51b0afb2e3c vp90-00-coastguard-5200.webm +4ba526d4bb895c4794dc20edeb38b102a9b1bd92 vp90-00-coastguard-5200.webm.md5 +17810fa737f29d5b032836e38243bbb666f06636 vp90-00-container-1000.webm +7e0fd7e93c5a16394818f844aa5f2d5fa7a73ee2 vp90-00-container-1000.webm.md5 +38deb4f59cec9e62715dec2f3670ffe7b1cf493e vp90-00-container-200.webm +aa3229017f920750bd5d919e19ea6127ea05adc0 vp90-00-container-200.webm.md5 +8b1a67ef35d3f00981d23c41b56a0a2e09976312 vp90-00-container-50.webm +0a6f1a793b936ff1287326882f1165065a2dcea0 vp90-00-container-50.webm.md5 +4c724db691b7202b60b56107ec7b0abc6cc52bdc vp90-00-deadline-1000.webm +5903bd89be457be681a6c6c8fd8c19f4570173db vp90-00-deadline-1000.webm.md5 +ee5e19a8fe14d3e72b1314a012b49a3bc0586375 vp90-00-deadline-200.webm +77095f98406fa27a2da8661f21664c00292dcefc vp90-00-deadline-200.webm.md5 +8230b07aa0ee7adf3caabae4e3bef997929001eb vp90-00-deadline-50.webm +fc47a159b2d2b0bed93d4e2c35408243e70b6d24 vp90-00-deadline-50.webm.md5 +244d12cda51235dcc421fedbe12422b326f539e7 vp90-00-flower-100.webm +dfeca236450b5ff19c1558ad33fba7ab7ff75f27 vp90-00-flower-100.webm.md5 +d5b7057564f670f7bf82017e2abc3aed5656b810 vp90-00-flower-2000.webm +65118811f4d46ef1e911d520296731536d3a507e vp90-00-flower-2000.webm.md5 +a9c226643365f0c8ae03e780d55aa6c6fa9cc0e7 vp90-00-flower-300.webm +fa5193d1a6e6b9e8bb91f75e91a3a377f00fa42e vp90-00-flower-300.webm.md5 +b206284b51dec6219c46e9b03def38a94d91bf89 vp90-00-flower-4400.webm +c8a73acd8234b287e86465d03fbf4f886d1fefb2 vp90-00-flower-4400.webm.md5 +faff83d7b6aa89f5d9518ffc5d4b145eb02b6800 vp90-00-flower-800.webm +328dd1969804afc094d010f54f350bd05390d6a9 vp90-00-flower-800.webm.md5 +42caa40d3b76b8ae5e7573b95e09bc4e57bea835 vp90-00-football-1600.webm +167b8f58a85d83050d4c56391d6b2d9a9a205b9a vp90-00-football-1600.webm.md5 +4c4f93f594a8ef89a9ba903bbcff914022a5ad9d vp90-00-football-2800.webm +7995f7f91b13d4ab5badcd3f9282bd1fceba38f3 vp90-00-football-2800.webm.md5 +c3ff724e79b4ae0202929f3ed1a1a5b67d10901f vp90-00-football-400.webm +19164a0e58ca5d407282a867866e8ec4a0a08fea vp90-00-football-400.webm.md5 +95de1c4abceab3706f0225e3b9c5dc719901a6cf vp90-00-football-600.webm +4a4454ae4d65748a45eaa3decb783bbe0ba190dc vp90-00-football-600.webm.md5 +80eebcdae76459c00d14b6c50f7529377e53a1c2 vp90-00-foreman-1200.webm +8228cc5a7cc83970b3a65f9b49bc74733255b09c vp90-00-foreman-1200.webm.md5 +601d0ff4f058a3da3af4409e4117795f7c231fda vp90-00-foreman-2000.webm +e0c0b0aa6f9597984a2d78e799a00e0052710b2c vp90-00-foreman-2000.webm.md5 +30ebc327645d68bcc83eab72610bba22f877fb4c vp90-00-foreman-300.webm +080fc2adf29a84f02a3e4b5508fc2f8dc32f1440 vp90-00-foreman-300.webm.md5 +6b1a6be0f7bd7605b565750b3080be397d4c48a0 vp90-00-foreman-600.webm +f7713d3eba8d34d511ba1c9585a5a3f34e133ba5 vp90-00-foreman-600.webm.md5 +b080d9786abc89b4be59bffc5baba7b42fbc286a vp90-00-hallmonitor-1200.webm +77be47800b58001eb7a854d4d4a9b9823bbbe158 vp90-00-hallmonitor-1200.webm.md5 +05cd8e8d58ab8311ad528c27b4c89cdf268e749b vp90-00-hallmonitor-2000.webm +de1aa35c7172e78e07d6b197280214bbd362cc4e vp90-00-hallmonitor-2000.webm.md5 +908676b32b190e956518bb742d1415efceeb8c75 vp90-00-hallmonitor-300.webm +f9d39866db341d18256339e9fd2c0ec296f47702 vp90-00-hallmonitor-300.webm.md5 +1307c7f7558de34a6230912e684ff9571a05db5f vp90-00-hallmonitor-600.webm +954b292dd56be5c1bf153df440b132e1b1fbcb68 vp90-00-hallmonitor-600.webm.md5 +05f556288c5c4211420f7c332daded816f9b31b7 vp90-00-harbour-1200.webm +399481f93cc252f20ad5141dd402cf5363673578 vp90-00-harbour-1200.webm.md5 +fa62e449485c544c281030c5ccff32c60d4dd169 vp90-00-harbour-200.webm +3d0e1885befb2493c477384917797164d4fe58e4 vp90-00-harbour-200.webm.md5 +fa3a5e563c3d2215703c1a68f71fbe2168a42468 vp90-00-harbour-3600.webm +9af392f6b2cb5ec5c9446b7262206773df535319 vp90-00-harbour-3600.webm.md5 +476db4b15989a5a078f1d2fc5f9734d1d24f1da1 vp90-00-harbour-5200.webm +352a05b179dc1f86cf6ce27494a4a8fb42379d72 vp90-00-harbour-5200.webm.md5 +0ea17a4892383a2fd0be9f88f213f5f48f2a61f4 vp90-00-highway-100.webm +a2fe942955bafa83295d1381c9a25264764924c5 vp90-00-highway-100.webm.md5 +7ab80485670a5343a74c4a2454761ed3bed7ceef vp90-00-highway-1600.webm +fda9c82cb5d28a5ff5f7dae7c537e9187dfbd4cc vp90-00-highway-1600.webm.md5 +162d42e033dad04fd7ae3bf9d39e9e204c022edc vp90-00-highway-2800.webm +b882c93a2dc89feb6090b0f72e67ac8a59fc0986 vp90-00-highway-2800.webm.md5 +79b9a0e6fa6cdd2367228e9ac8d6a369a8d647e6 vp90-00-highway-50.webm +80ecf926372dbe8c1b4bcd68ea2101f78a93b02e vp90-00-highway-50.webm.md5 +a67fd02cbb75c1a757b5ea56b9eee46069bfadbf vp90-00-husky-100.webm +12cd583e791c8e5b40b5dffe4a9dbcc1929dc645 vp90-00-husky-100.webm.md5 +1a8b4302eb6f88b14a9acd4a6cbe62d0b380f2e4 vp90-00-husky-2000.webm +a9c2532e5d867d7627bb6767008b43b653cce904 vp90-00-husky-2000.webm.md5 +f56f66afd4d4512a49904275a1c942ba7379fec4 vp90-00-husky-300.webm +196dc386f104b7b9ed2ec6c6a1f104ce0319c2eb vp90-00-husky-300.webm.md5 +6ba3c16fd98d37a8de7023419682a3595778b9bc vp90-00-husky-4400.webm +2f4815ba97e352fcd0089d1a5883a0aff1e5394a vp90-00-husky-4400.webm.md5 +db04a296c377693dd6e974bea36256f4b14cddef vp90-00-husky-800.webm +7658473ad17ee689a37fda558c5a23816131cfc3 vp90-00-husky-800.webm.md5 +50cf9e34b61e1cf32c9dde2ebcc5f5703c379a41 vp90-00-ice-150.webm +806ceba91dc40c45eafc4d7ee61df9346c6fe5f9 vp90-00-ice-150.webm.md5 +4cfca1bea7aae6e4405abfca603cfbded13ded1a vp90-00-ice-400.webm +e4298abf05419973da89c0bfcdf0006b1606ebcd vp90-00-ice-400.webm.md5 +12e3ccfdf96c3f4eebeed8106c5daef6c2b28d83 vp90-00-ice-800.webm +6fb2aacb4d8131dcabaa61a9cd2497cd09854377 vp90-00-ice-800.webm.md5 +124977938c47ba739e918533bc5d6d73e41ce2ec vp90-00-mobile-1600.webm +603b2b523c8ed5922121d285567a845bb6693d35 vp90-00-mobile-1600.webm.md5 +93f204b90250791b884479be5da534a5bc6304ff vp90-00-mobile-2800.webm +21ec8735b774c66e192f7270c12075f598f700d5 vp90-00-mobile-2800.webm.md5 +fe9cdbfdeee2b7554efb532f646703cff55c2d2c vp90-00-mobile-400.webm +4def63c78ee09e90e6385d3122ada95343246102 vp90-00-mobile-400.webm.md5 +2a042aa8a06c45770dcb52c56a7f5cea6d51b8dd vp90-00-mobile-600.webm +03169f031dece0db3d89ce16cc3e0ee3eca21065 vp90-00-mobile-600.webm.md5 +7fc5b0b0c684d63e161c9c5932e1374327e15dd4 vp90-00-motherdaughter-100.webm +290ac7722caf4b15136b307a239c9b903113b9c4 vp90-00-motherdaughter-100.webm.md5 +67ddfce82bff083a1ceb108a7dcfb801791102f1 vp90-00-motherdaughter-300.webm +7696698d38e32f0afeb3a3e9a45b7fe3f237aaba vp90-00-motherdaughter-300.webm.md5 +ff65a1bee2fe384728017c5148df61379043d5b6 vp90-00-motherdaughter-600.webm +f0b167000bf40877d1ba7ba52a08b4310011c032 vp90-00-motherdaughter-600.webm.md5 +d73c54e676bd63424fc9ad8d0cef64e929081cf4 vp90-00-news-100.webm +71821b71a97823e9ba58563efc841dc6beefe9df vp90-00-news-100.webm.md5 +2937238d094863951eb8f218438b966d2b7b5430 vp90-00-news-300.webm +2587d0859a330cf6d8e0a135d1f586bb2a5033fc vp90-00-news-300.webm.md5 +65afdd4fc411951115b48435b8b65155594b5c99 vp90-00-news-600.webm +5815bb341db976f44dab97bb9cfba8ea0ca55502 vp90-00-news-600.webm.md5 +de5dd99ac04d3a937fc0951d06fb8f533fdc393a vp90-00-pamphlet-150.webm +0381d705fa490f35c772e3048b423b382088d546 vp90-00-pamphlet-150.webm.md5 +46f283284cb64b79243b2ea6aad709a526c26393 vp90-00-pamphlet-25.webm +f100fbebcad96f27ed8f340414b939bc738d49d0 vp90-00-pamphlet-25.webm.md5 +8df04ece12455c5c40f14cb089348260798c5f2b vp90-00-pamphlet-400.webm +66a2c87cd4194368d3477e9a334880b76c87e991 vp90-00-pamphlet-400.webm.md5 +a00e97e4a71f5e24f194c59cde7d41bc2c3af325 vp90-00-paris-1000.webm +53ef896e16d1b83aa5166945d149c7133401b3f0 vp90-00-paris-1000.webm.md5 +6b03388e0236f6171e20c73834858e3c87b441b2 vp90-00-paris-200.webm +55a324b0153c5d54cd0c0492fed8755c441fa18c vp90-00-paris-200.webm.md5 +429ec362a9600c8822652cf7e122e22bca033d69 vp90-00-paris-50.webm +4406226b7bddb11ede8ee0c442d52e5d3bbbde78 vp90-00-paris-50.webm.md5 +a7996d4e757ea484aa72e14f623d6c9e72537888 vp90-00-signirene-1000.webm +f65a1ac6e1ce77102e63fb363dbca361b8108c02 vp90-00-signirene-1000.webm.md5 +8c2f686179bc3e87a18b48bcb5058f3cd61e1b4c vp90-00-signirene-200.webm +b8ab16cba9392e49169c374eb1e0c1b763ccaefb vp90-00-signirene-200.webm.md5 +5f8f99c386dce64931bbd4fc42a59a78dc6fdba1 vp90-00-signirene-50.webm +fdb8c4bc302884d413a256634d3e2fbd92867c90 vp90-00-signirene-50.webm.md5 +d5074f0a5bcefe9fd651afbbebf0e0f3fedb965b vp90-00-silent-1000.webm +9c075894fbfb84791fcc7dbd3fcab15b0a9bd64e vp90-00-silent-1000.webm.md5 +32101f334f675715a8f411638dfda80afacc37a6 vp90-00-silent-200.webm +fb0dac37f31ca711443832046a6aaf868e69b357 vp90-00-silent-200.webm.md5 +0aaef50d7f94873e99ec7e39f59a6b74e92ad946 vp90-00-silent-50.webm +be9fc41965b5b63f7c7bbd6c91191e940903e012 vp90-00-silent-50.webm.md5 +5e22ad14c562733d4d4a3ce163b580ed4a64e6fe vp90-00-soccer-100.webm +1ca9a0016910cfca26def9944568749a168131d8 vp90-00-soccer-100.webm.md5 +2d9b2a0fa5ac210f8d7c646578698e045733ad4a vp90-00-soccer-2000.webm +f979078650057606ca770b3f03be4c509efb40a9 vp90-00-soccer-2000.webm.md5 +7b789360ffc1eb5a3735f8a1f8d248a24ca4267c vp90-00-soccer-300.webm +195d33b23ca8304519bd6e38e9657e53a04779d8 vp90-00-soccer-300.webm.md5 +3907318ef35573e4efc5c150d3aff271c7157501 vp90-00-soccer-4400.webm +4b43ceecae9a9a7d39a47347f9e20af3613827d1 vp90-00-soccer-4400.webm.md5 +c89920aa89194cb6a36f77dff8722573f0df7241 vp90-00-soccer-800.webm +1da71751009afa483a03e274a538df24c9f5e513 vp90-00-soccer-800.webm.md5 +efca14e8e0515a8f8ed3ded11fdbff24b09a7f9d vp90-00-stefan-1600.webm +6f103270ce03cc85b28dd1c86d0447922d810671 vp90-00-stefan-1600.webm.md5 +b99ab6a983d48c15aa3a9160d06286fca0074193 vp90-00-stefan-2800.webm +986a72dd9988c6bf4246cd5bd966ce991ba55319 vp90-00-stefan-2800.webm.md5 +eb962244ca51a101ad8f585df6be8f5f96691f18 vp90-00-stefan-400.webm +2747cfd8f74aedc370767f08129b35ace70e1fe7 vp90-00-stefan-400.webm.md5 +b507b8cedd0147c5316db8f84f35ace768c25069 vp90-00-stefan-600.webm +daeb369046c2dc27ecfde978b87fd8b49d83789f vp90-00-stefan-600.webm.md5 +c5c2dd891c2b5fe4a70845858ccb859df3455ee7 vp90-00-students-100.webm +d1be06dc636ece0c34ab8c17399888aaf19e0c19 vp90-00-students-100.webm.md5 +c9e4da3a8b455aa690d89338f32f9d76773cdd18 vp90-00-students-300.webm +a9aa72e1ee27063f8e9f13b4647cec01c8efb2d6 vp90-00-students-300.webm.md5 +e9e5072cd944a8994e50fce367975e3ce526bd67 vp90-00-students-600.webm +86525ce188a98a51f86fad27341729bb61d1ca8b vp90-00-students-600.webm.md5 +58deb053aeafefdfdf13741accf9fcbe4584ea94 vp90-00-tempete-1200.webm +ec395a2ec76b4c1e64e243366a8840da22ee3a65 vp90-00-tempete-1200.webm.md5 +5d35232eaa8ee149a917ff94536968fb37dad50e vp90-00-tempete-200.webm +7f8c7529f40d6b6d6de8e89dbf9697623d27c234 vp90-00-tempete-200.webm.md5 +c44eb147bc3f8682b96096fccef8beb4380c40db vp90-00-tempete-3600.webm +01fd23e412530fa2d5319a22886161957a747ee0 vp90-00-tempete-3600.webm.md5 +56ab322b34a750e16dcc8ccfb735a5b9270cedc4 vp90-00-tempete-5200.webm +1cf803409ae53b991bff10079af4ab07aaa2853d vp90-00-tempete-5200.webm.md5 +ffe48d52019c228e919f4b123028664b8d0c2f4b vp90-00-tennis-100.webm +406fda3367899995d4e37170063495832e2be372 vp90-00-tennis-100.webm.md5 +6c030f8142b1932fbe8eb5c2b39b3452a5eea3aa vp90-00-tennis-2000.webm +dcf20921e2a8ab0dcd09f7f6bdcdd35f979205ae vp90-00-tennis-2000.webm.md5 +3fe0df7b74f301b39e1b21e6926c69a8418b9b70 vp90-00-tennis-300.webm +80c8301d3a37b33ca50318ba000066a6ae9929dc vp90-00-tennis-300.webm.md5 +82a2497083b8dce6b1c73bcdf16323ea69d1cca9 vp90-00-tennis-4400.webm +83ce97bc09a7e1b2f2c3437195a8931d7608a62b vp90-00-tennis-4400.webm.md5 +2c8bd3a29bbd1085169bfcba9fdf65a37f4a16bb vp90-00-tennis-800.webm +9920a65e06d2e7025f13f3d8bf35670503875aed vp90-00-tennis-800.webm.md5 +26469062c5724c2cc4914436ef032bb55373f843 vp90-00-waterfall-150.webm +9b86373ce15302a9b22cef8f808ce0e37e6d2b65 vp90-00-waterfall-150.webm.md5 +410ba6af2ddca5110fa7a4c383dc8b28f38cf565 vp90-00-waterfall-200.webm +251892d3fdcbc9d7a20c22ba202ed4935222e5b8 vp90-00-waterfall-200.webm.md5 +40b643aff88aed3764c5b58c446a8fbbc5fb36d7 vp90-00-waterfall-400.webm +51f31a6b6408f8af4d107e0f2a3c1a274d4da6bb vp90-00-waterfall-400.webm.md5 +bd421141e01f53dc15ced790f9a96ab70a613260 vp90-00-waterfall-800.webm +1366efe772fccaa2b8a6ac3ce45255b312a2ef6c vp90-00-waterfall-800.webm.md5 diff --git a/test/test.mk b/test/test.mk index 1e0b2172e..806901d27 100644 --- a/test/test.mk +++ b/test/test.mk @@ -1,3 +1,4 @@ +LIBVPX_TEST_SRCS-yes += clear_system_state.h LIBVPX_TEST_SRCS-yes += register_state_check.h LIBVPX_TEST_SRCS-yes += test.mk LIBVPX_TEST_SRCS-yes += acm_random.h @@ -30,8 +31,17 @@ LIBVPX_TEST_SRCS-yes += decode_test_driver.cc LIBVPX_TEST_SRCS-yes += decode_test_driver.h LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h +## WebM Parsing +NESTEGG_SRCS += ../nestegg/halloc/halloc.h +NESTEGG_SRCS += ../nestegg/halloc/src/align.h +NESTEGG_SRCS += ../nestegg/halloc/src/halloc.c +NESTEGG_SRCS += ../nestegg/halloc/src/hlist.h +NESTEGG_SRCS += ../nestegg/include/nestegg/nestegg.h +NESTEGG_SRCS += ../nestegg/src/nestegg.c +LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(NESTEGG_SRCS) +LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h -LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += test_vector_test.cc +LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += test_vector_test.cc ## ## WHITE BOX TESTS @@ -217,3 +227,223 @@ LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1438.ivf.md5 LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1439.ivf.md5 LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1440.ivf.md5 LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1443.ivf.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-akiyo-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-150.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-150.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-25.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-25.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bowing-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-4400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-4400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-bus-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-1600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-1600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-2800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-2800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-cheer-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-city-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-3600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-3600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-5200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-coastguard-5200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-1000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-1000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-container-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-1000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-1000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-deadline-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-4400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-4400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-flower-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-1600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-1600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-2800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-2800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-football-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-foreman-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-hallmonitor-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-3600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-3600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-5200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-harbour-5200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-1600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-1600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-2800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-2800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-highway-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-4400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-4400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-husky-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-150.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-150.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-ice-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-1600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-1600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-2800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-2800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-mobile-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-motherdaughter-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-news-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-150.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-150.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-25.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-25.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-pamphlet-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-1000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-1000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-paris-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-1000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-1000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-signirene-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-1000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-1000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-50.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-silent-50.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-4400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-4400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-soccer-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-1600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-1600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-2800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-2800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-stefan-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-students-600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-1200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-1200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-3600.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-3600.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-5200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tempete-5200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-100.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-100.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-2000.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-2000.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-300.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-300.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-4400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-4400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-tennis-800.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-150.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-150.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-200.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-200.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-400.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-400.webm.md5 +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-800.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-00-waterfall-800.webm.md5 diff --git a/test/test_vector_test.cc b/test/test_vector_test.cc index e0d99b5dd..d7bd1845a 100644 --- a/test/test_vector_test.cc +++ b/test/test_vector_test.cc @@ -15,6 +15,7 @@ #include "test/codec_factory.h" #include "test/decode_test_driver.h" #include "test/ivf_video_source.h" +#include "test/webm_video_source.h" #include "test/util.h" #include "test/md5_helper.h" extern "C" { @@ -22,8 +23,8 @@ extern "C" { } namespace { -// There are 61 test vectors in total. -const char *kTestVectors[] = { +#if CONFIG_VP8_DECODER +const char *kVP8TestVectors[] = { "vp80-00-comprehensive-001.ivf", "vp80-00-comprehensive-002.ivf", "vp80-00-comprehensive-003.ivf", "vp80-00-comprehensive-004.ivf", "vp80-00-comprehensive-005.ivf", @@ -56,6 +57,66 @@ const char *kTestVectors[] = { "vp80-05-sharpness-1438.ivf", "vp80-05-sharpness-1439.ivf", "vp80-05-sharpness-1440.ivf", "vp80-05-sharpness-1443.ivf" }; +#endif +#if CONFIG_VP9_DECODER +const char *kVP9TestVectors[] = { + "vp90-00-akiyo-200.webm", "vp90-00-akiyo-300.webm", + "vp90-00-akiyo-50.webm", "vp90-00-bowing-150.webm", + "vp90-00-bowing-25.webm", "vp90-00-bowing-400.webm", + "vp90-00-bus-100.webm", "vp90-00-bus-2000.webm", + "vp90-00-bus-300.webm", "vp90-00-bus-4400.webm", + "vp90-00-bus-800.webm", "vp90-00-cheer-1600.webm", + "vp90-00-cheer-2800.webm", "vp90-00-cheer-400.webm", + "vp90-00-cheer-600.webm", "vp90-00-city-1200.webm", + "vp90-00-city-2000.webm", "vp90-00-city-300.webm", + "vp90-00-city-600.webm", "vp90-00-coastguard-1200.webm", + "vp90-00-coastguard-200.webm", "vp90-00-coastguard-3600.webm", + "vp90-00-coastguard-5200.webm", "vp90-00-container-1000.webm", + "vp90-00-container-200.webm", "vp90-00-container-50.webm", + "vp90-00-deadline-1000.webm", "vp90-00-deadline-200.webm", + "vp90-00-deadline-50.webm", "vp90-00-flower-100.webm", + "vp90-00-flower-2000.webm", "vp90-00-flower-300.webm", + "vp90-00-flower-4400.webm", "vp90-00-flower-800.webm", + "vp90-00-football-1600.webm", "vp90-00-football-2800.webm", + "vp90-00-football-400.webm", "vp90-00-football-600.webm", + "vp90-00-foreman-1200.webm", "vp90-00-foreman-2000.webm", + "vp90-00-foreman-300.webm", "vp90-00-foreman-600.webm", + "vp90-00-hallmonitor-1200.webm", "vp90-00-hallmonitor-2000.webm", + "vp90-00-hallmonitor-300.webm", "vp90-00-hallmonitor-600.webm", + "vp90-00-harbour-1200.webm", "vp90-00-harbour-200.webm", + "vp90-00-harbour-3600.webm", "vp90-00-harbour-5200.webm", + "vp90-00-highway-100.webm", "vp90-00-highway-1600.webm", + "vp90-00-highway-2800.webm", "vp90-00-highway-50.webm", + "vp90-00-husky-100.webm", "vp90-00-husky-2000.webm", + "vp90-00-husky-300.webm", "vp90-00-husky-4400.webm", + "vp90-00-husky-800.webm", "vp90-00-ice-150.webm", + "vp90-00-ice-400.webm", "vp90-00-ice-800.webm", + "vp90-00-mobile-1600.webm", "vp90-00-mobile-2800.webm", + "vp90-00-mobile-400.webm", "vp90-00-mobile-600.webm", + "vp90-00-motherdaughter-100.webm", "vp90-00-motherdaughter-300.webm", + "vp90-00-motherdaughter-600.webm", "vp90-00-news-100.webm", + "vp90-00-news-300.webm", "vp90-00-news-600.webm", + "vp90-00-pamphlet-150.webm", "vp90-00-pamphlet-25.webm", + "vp90-00-pamphlet-400.webm", "vp90-00-paris-1000.webm", + "vp90-00-paris-200.webm", "vp90-00-paris-50.webm", + "vp90-00-signirene-1000.webm", "vp90-00-signirene-200.webm", + "vp90-00-signirene-50.webm", "vp90-00-silent-1000.webm", + "vp90-00-silent-200.webm", "vp90-00-silent-50.webm", + "vp90-00-soccer-100.webm", "vp90-00-soccer-2000.webm", + "vp90-00-soccer-300.webm", "vp90-00-soccer-4400.webm", + "vp90-00-soccer-800.webm", "vp90-00-stefan-1600.webm", + "vp90-00-stefan-2800.webm", "vp90-00-stefan-400.webm", + "vp90-00-stefan-600.webm", "vp90-00-students-100.webm", + "vp90-00-students-300.webm", "vp90-00-students-600.webm", + "vp90-00-tempete-1200.webm", "vp90-00-tempete-200.webm", + "vp90-00-tempete-3600.webm", "vp90-00-tempete-5200.webm", + "vp90-00-tennis-100.webm", "vp90-00-tennis-2000.webm", + "vp90-00-tennis-300.webm", "vp90-00-tennis-4400.webm", + "vp90-00-tennis-800.webm", "vp90-00-waterfall-150.webm", + "vp90-00-waterfall-200.webm", "vp90-00-waterfall-400.webm", + "vp90-00-waterfall-800.webm", +}; +#endif class TestVectorTest : public ::libvpx_test::DecoderTest, public ::libvpx_test::CodecTestWithParam<const char*> { @@ -102,20 +163,28 @@ class TestVectorTest : public ::libvpx_test::DecoderTest, // the test failed. TEST_P(TestVectorTest, MD5Match) { const std::string filename = GET_PARAM(1); - // Open compressed video file. - libvpx_test::IVFVideoSource video(filename); + libvpx_test::CompressedVideoSource *video = NULL; - video.Init(); + // Open compressed video file. + if (filename.substr(filename.length() - 3, 3) == "ivf") { + video = new libvpx_test::IVFVideoSource(filename); + } else if (filename.substr(filename.length() - 4, 4) == "webm") { + video = new libvpx_test::WebMVideoSource(filename); + } + video->Init(); // Construct md5 file name. const std::string md5_filename = filename + ".md5"; OpenMD5File(md5_filename); // Decode frame, and check the md5 matching. - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_NO_FATAL_FAILURE(RunLoop(video)); + delete video; } VP8_INSTANTIATE_TEST_CASE(TestVectorTest, - ::testing::ValuesIn(kTestVectors)); + ::testing::ValuesIn(kVP8TestVectors)); +VP9_INSTANTIATE_TEST_CASE(TestVectorTest, + ::testing::ValuesIn(kVP9TestVectors)); } // namespace diff --git a/test/variance_test.cc b/test/variance_test.cc index 337980cd7..dfa1a07c7 100644 --- a/test/variance_test.cc +++ b/test/variance_test.cc @@ -12,6 +12,8 @@ #include "third_party/googletest/src/include/gtest/gtest.h" +#include "test/clear_system_state.h" + #include "vpx/vpx_integer.h" #include "vpx_config.h" extern "C" { @@ -51,6 +53,7 @@ class VarianceTest : virtual void TearDown() { delete[] src_; delete[] ref_; + libvpx_test::ClearSystemState(); } protected: diff --git a/test/vp8_boolcoder_test.cc b/test/vp8_boolcoder_test.cc index ab19c3412..c3a8d12e1 100644 --- a/test/vp8_boolcoder_test.cc +++ b/test/vp8_boolcoder_test.cc @@ -27,18 +27,28 @@ extern "C" { namespace { const int num_tests = 10; -void encrypt_buffer(uint8_t *buffer, int size, const uint8_t *key) { +// In a real use the 'decrypt_state' parameter will be a pointer to a struct +// with whatever internal state the decryptor uses. For testing we'll just +// xor with a constant key, and decrypt_state will point to the start of +// the original buffer. +const uint8_t secret_key[16] = { + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0 +}; + +void encrypt_buffer(uint8_t *buffer, int size) { for (int i = 0; i < size; ++i) { - buffer[i] ^= key[i % 32]; + buffer[i] ^= secret_key[i & 15]; } } -const uint8_t secret_key[32] = { - 234, 32, 2, 3, 4, 230, 6, 11, - 0, 132, 22, 23, 45, 21, 124, 255, - 0, 43, 52, 3, 23, 63, 99, 7, - 120, 8, 252, 84, 4, 83, 6, 13 -}; +void test_decrypt_cb(void *decrypt_state, const uint8_t *input, + uint8_t *output, int count) { + int offset = input - (uint8_t *)decrypt_state; + for (int i = 0; i < count; i++) { + output[i] = input[i] ^ secret_key[(offset + i) & 15]; + } +} } // namespace @@ -85,12 +95,13 @@ TEST(VP8, TestBitIO) { vp8_stop_encode(&bw); BOOL_DECODER br; - #if CONFIG_DECRYPT - encrypt_buffer(bw_buffer, buffer_size, secret_key); + encrypt_buffer(bw_buffer, buffer_size); + vp8dx_start_decode(&br, bw_buffer, buffer_size, + test_decrypt_cb, (void *)bw_buffer); +#else + vp8dx_start_decode(&br, bw_buffer, buffer_size, NULL, NULL); #endif - - vp8dx_start_decode(&br, bw_buffer, buffer_size, bw_buffer, secret_key); bit_rnd.Reset(random_seed); for (int i = 0; i < bits_to_test; ++i) { if (bit_method == 2) { diff --git a/test/vp8_decrypt_test.cc b/test/vp8_decrypt_test.cc index ea7b92049..d850f006c 100644 --- a/test/vp8_decrypt_test.cc +++ b/test/vp8_decrypt_test.cc @@ -11,55 +11,61 @@ #include <cstdio> #include <cstdlib> #include <string> +#include <vector> #include "third_party/googletest/src/include/gtest/gtest.h" -#include "test/decode_test_driver.h" +#include "test/codec_factory.h" #include "test/ivf_video_source.h" -#if CONFIG_DECRYPT - namespace { - -const uint8_t decrypt_key[32] = { - 255, 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, 0, 0, 0, +// In a real use the 'decrypt_state' parameter will be a pointer to a struct +// with whatever internal state the decryptor uses. For testing we'll just +// xor with a constant key, and decrypt_state will point to the start of +// the original buffer. +const uint8_t test_key[16] = { + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0 }; -} // namespace +void encrypt_buffer(const uint8_t *src, uint8_t *dst, int size, int offset = 0) { + for (int i = 0; i < size; ++i) { + dst[i] = src[i] ^ test_key[(offset + i) & 15]; + } +} -namespace libvpx_test { +void test_decrypt_cb(void *decrypt_state, const uint8_t *input, + uint8_t *output, int count) { + encrypt_buffer(input, output, count, input - (uint8_t *)decrypt_state); +} -TEST(TestDecrypt, NullKey) { - vpx_codec_dec_cfg_t cfg = {0}; - vpx_codec_ctx_t decoder = {0}; - vpx_codec_err_t res = vpx_codec_dec_init(&decoder, &vpx_codec_vp8_dx_algo, - &cfg, 0); - ASSERT_EQ(VPX_CODEC_OK, res); +} // namespace - res = vpx_codec_control(&decoder, VP8_SET_DECRYPT_KEY, NULL); - ASSERT_EQ(VPX_CODEC_INVALID_PARAM, res); -} +namespace libvpx_test { TEST(TestDecrypt, DecryptWorks) { libvpx_test::IVFVideoSource video("vp80-00-comprehensive-001.ivf"); video.Init(); vpx_codec_dec_cfg_t dec_cfg = {0}; - Decoder decoder(dec_cfg, 0); + VP8Decoder decoder(dec_cfg, 0); - // Zero decrypt key (by default) video.Begin(); + + // no decryption vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size()); ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); - // Non-zero decrypt key + // decrypt frame video.Next(); - decoder.Control(VP8_SET_DECRYPT_KEY, decrypt_key); + +#if CONFIG_DECRYPT + std::vector<uint8_t> encrypted(video.frame_size()); + encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size()); + vp8_decrypt_init di = { test_decrypt_cb, &encrypted[0] }; + decoder.Control(VP8D_SET_DECRYPTOR, &di); +#endif // CONFIG_DECRYPT + res = decoder.DecodeFrame(video.cxdata(), video.frame_size()); - ASSERT_NE(VPX_CODEC_OK, res) << decoder.DecodeError(); + ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); } } // namespace libvpx_test - -#endif // CONFIG_DECRYPT diff --git a/test/webm_video_source.h b/test/webm_video_source.h new file mode 100644 index 000000000..c7919a979 --- /dev/null +++ b/test/webm_video_source.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef TEST_WEBM_VIDEO_SOURCE_H_ +#define TEST_WEBM_VIDEO_SOURCE_H_ +#include <cstdarg> +#include <cstdio> +#include <cstdlib> +#include <new> +#include <string> +#include "nestegg/include/nestegg/nestegg.h" +#include "test/video_source.h" + +namespace libvpx_test { + +static int +nestegg_read_cb(void *buffer, size_t length, void *userdata) { + FILE *f = reinterpret_cast<FILE *>(userdata); + + if (fread(buffer, 1, length, f) < length) { + if (ferror(f)) + return -1; + if (feof(f)) + return 0; + } + return 1; +} + + +static int +nestegg_seek_cb(int64_t offset, int whence, void *userdata) { + FILE *f = reinterpret_cast<FILE *>(userdata); + switch (whence) { + case NESTEGG_SEEK_SET: + whence = SEEK_SET; + break; + case NESTEGG_SEEK_CUR: + whence = SEEK_CUR; + break; + case NESTEGG_SEEK_END: + whence = SEEK_END; + break; + }; + return fseek(f, (long)offset, whence) ? -1 : 0; +} + + +static int64_t +nestegg_tell_cb(void *userdata) { + FILE *f = reinterpret_cast<FILE *>(userdata); + return ftell(f); +} + + +static void +nestegg_log_cb(nestegg *context, unsigned int severity, char const *format, + ...) { + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +// This class extends VideoSource to allow parsing of WebM files, +// so that we can do actual file decodes. +class WebMVideoSource : public CompressedVideoSource { + public: + explicit WebMVideoSource(const std::string &file_name) + : file_name_(file_name), + input_file_(NULL), + nestegg_ctx_(NULL), + pkt_(NULL), + video_track_(0), + chunk_(0), + chunks_(0), + buf_(NULL), + buf_sz_(0), + frame_(0), + end_of_file_(false) { + } + + virtual ~WebMVideoSource() { + if (input_file_) + fclose(input_file_); + if (nestegg_ctx_) + nestegg_destroy(nestegg_ctx_); + } + + virtual void Init() { + } + + virtual void Begin() { + input_file_ = OpenTestDataFile(file_name_); + ASSERT_TRUE(input_file_) << "Input file open failed. Filename: " + << file_name_; + + nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, + input_file_}; + ASSERT_FALSE(nestegg_init(&nestegg_ctx_, io, NULL)) + << "nestegg_init failed"; + + unsigned int n; + ASSERT_FALSE(nestegg_track_count(nestegg_ctx_, &n)) + << "failed to get track count"; + + for (unsigned int i = 0; i < n; i++) { + int track_type = nestegg_track_type(nestegg_ctx_, i); + ASSERT_GE(track_type, 0) << "failed to get track type"; + + if (track_type == NESTEGG_TRACK_VIDEO) { + video_track_ = i; + break; + } + } + + FillFrame(); + } + + virtual void Next() { + ++frame_; + FillFrame(); + } + + void FillFrame() { + if (chunk_ >= chunks_) { + unsigned int track; + + do { + /* End of this packet, get another. */ + if (pkt_) + nestegg_free_packet(pkt_); + + int again = nestegg_read_packet(nestegg_ctx_, &pkt_); + ASSERT_GE(again, 0) << "nestegg_read_packet failed"; + if (!again) { + end_of_file_ = true; + return; + } + + ASSERT_FALSE(nestegg_packet_track(pkt_, &track)) + << "nestegg_packet_track failed"; + } while (track != video_track_); + + ASSERT_FALSE(nestegg_packet_count(pkt_, &chunks_)) + << "nestegg_packet_count failed"; + chunk_ = 0; + } + + ASSERT_FALSE(nestegg_packet_data(pkt_, chunk_, &buf_, &buf_sz_)) + << "nestegg_packet_data failed"; + chunk_++; + } + + virtual const uint8_t *cxdata() const { + return end_of_file_ ? NULL : buf_; + } + virtual const unsigned int frame_size() const { return buf_sz_; } + virtual const unsigned int frame_number() const { return frame_; } + + protected: + std::string file_name_; + FILE *input_file_; + nestegg *nestegg_ctx_; + nestegg_packet *pkt_; + unsigned int video_track_; + unsigned int chunk_; + unsigned int chunks_; + uint8_t *buf_; + size_t buf_sz_; + unsigned int frame_; + bool end_of_file_; +}; + +} // namespace libvpx_test + +#endif // TEST_WEBM_VIDEO_SOURCE_H_ diff --git a/vp8/decoder/dboolhuff.c b/vp8/decoder/dboolhuff.c index aa7a56a02..546fb2d21 100644 --- a/vp8/decoder/dboolhuff.c +++ b/vp8/decoder/dboolhuff.c @@ -14,16 +14,16 @@ int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source, unsigned int source_sz, - const unsigned char *origin, - const unsigned char *key) + vp8_decrypt_cb *decrypt_cb, + void *decrypt_state) { br->user_buffer_end = source+source_sz; br->user_buffer = source; br->value = 0; br->count = -8; br->range = 255; - br->origin = origin; - br->key = key; + br->decrypt_cb = decrypt_cb; + br->decrypt_state = decrypt_state; if (source_sz && !source) return 1; @@ -37,13 +37,20 @@ int vp8dx_start_decode(BOOL_DECODER *br, void vp8dx_bool_decoder_fill(BOOL_DECODER *br) { const unsigned char *bufptr = br->user_buffer; - const unsigned char *bufend = br->user_buffer_end; VP8_BD_VALUE value = br->value; int count = br->count; int shift = VP8_BD_VALUE_SIZE - 8 - (count + 8); - size_t bits_left = (bufend - bufptr)*CHAR_BIT; + size_t bytes_left = br->user_buffer_end - bufptr; + size_t bits_left = bytes_left * CHAR_BIT; int x = (int)(shift + CHAR_BIT - bits_left); int loop_end = 0; + unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1]; + + if (br->decrypt_cb) { + int n = bytes_left > sizeof(decrypted) ? sizeof(decrypted) : bytes_left; + br->decrypt_cb(br->decrypt_state, bufptr, decrypted, n); + bufptr = decrypted; + } if(x >= 0) { @@ -56,14 +63,13 @@ void vp8dx_bool_decoder_fill(BOOL_DECODER *br) while(shift >= loop_end) { count += CHAR_BIT; - value |= ((VP8_BD_VALUE)decrypt_byte(bufptr, br->origin, - br->key)) << shift; + value |= (VP8_BD_VALUE)*bufptr << shift; ++bufptr; + ++br->user_buffer; shift -= CHAR_BIT; } } - br->user_buffer = bufptr; br->value = value; br->count = count; } diff --git a/vp8/decoder/dboolhuff.h b/vp8/decoder/dboolhuff.h index 46a4dd60e..4c0ca1ce7 100644 --- a/vp8/decoder/dboolhuff.h +++ b/vp8/decoder/dboolhuff.h @@ -28,17 +28,11 @@ typedef size_t VP8_BD_VALUE; Even relatively modest values like 100 would work fine.*/ #define VP8_LOTS_OF_BITS (0x40000000) -static unsigned char decrypt_byte(const unsigned char *ch, - const unsigned char *origin, - const unsigned char *key) -{ -#if CONFIG_DECRYPT - const int offset = (int)(ch - origin); - return *ch ^ key[offset % 32]; // VP8_DECRYPT_KEY_SIZE -#else - return *ch; -#endif -} +/*Decrypt n bytes of data from input -> output, using the decrypt_state + passed in VP8D_SET_DECRYPTOR. +*/ +typedef void (vp8_decrypt_cb)(void *decrypt_state, const unsigned char *input, + unsigned char *output, int count); typedef struct { @@ -47,8 +41,8 @@ typedef struct VP8_BD_VALUE value; int count; unsigned int range; - const unsigned char *origin; - const unsigned char *key; + vp8_decrypt_cb *decrypt_cb; + void *decrypt_state; } BOOL_DECODER; DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); @@ -56,8 +50,8 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source, unsigned int source_sz, - const unsigned char *origin, - const unsigned char *key); + vp8_decrypt_cb *decrypt_cb, + void *decrypt_state); void vp8dx_bool_decoder_fill(BOOL_DECODER *br); diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index bb727db90..44c35effe 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -759,11 +759,16 @@ static void decode_mb_rows(VP8D_COMP *pbi) } -static unsigned int read_partition_size(const unsigned char *cx_size) +static unsigned int read_partition_size(VP8D_COMP *pbi, + const unsigned char *cx_size) { - const unsigned int size = - cx_size[0] + (cx_size[1] << 8) + (cx_size[2] << 16); - return size; + unsigned char temp[3]; + if (pbi->decrypt_cb) + { + pbi->decrypt_cb(pbi->decrypt_state, cx_size, temp, 3); + cx_size = temp; + } + return cx_size[0] + (cx_size[1] << 8) + (cx_size[2] << 16); } static int read_is_valid(const unsigned char *start, @@ -794,7 +799,7 @@ static unsigned int read_available_partition_size( if (i < num_part - 1) { if (read_is_valid(partition_size_ptr, 3, first_fragment_end)) - partition_size = read_partition_size(partition_size_ptr); + partition_size = read_partition_size(pbi, partition_size_ptr); else if (pbi->ec_active) partition_size = (unsigned int)bytes_left; else @@ -894,8 +899,7 @@ static void setup_token_decoder(VP8D_COMP *pbi, if (vp8dx_start_decode(bool_decoder, pbi->fragments.ptrs[partition_idx], pbi->fragments.sizes[partition_idx], - pbi->fragments.ptrs[0], - pbi->decrypt_key)) + pbi->decrypt_cb, pbi->decrypt_state)) vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder %d", partition_idx); @@ -986,7 +990,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) VP8_COMMON *const pc = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; const unsigned char *data = pbi->fragments.ptrs[0]; - const unsigned char *const origin = data; const unsigned char *data_end = data + pbi->fragments.sizes[0]; ptrdiff_t first_partition_length_in_bytes; @@ -1019,18 +1022,21 @@ int vp8_decode_frame(VP8D_COMP *pbi) } else { - const unsigned char data0 = decrypt_byte(data + 0, origin, - pbi->decrypt_key); - const unsigned char data1 = decrypt_byte(data + 1, origin, - pbi->decrypt_key); - const unsigned char data2 = decrypt_byte(data + 2, origin, - pbi->decrypt_key); - - pc->frame_type = (FRAME_TYPE)(data0 & 1); - pc->version = (data0 >> 1) & 7; - pc->show_frame = (data0 >> 4) & 1; + unsigned char clear_buffer[10]; + const unsigned char *clear = data; + if (pbi->decrypt_cb) + { + int n = data_end - data; + if (n > 10) n = 10; + pbi->decrypt_cb(pbi->decrypt_state, data, clear_buffer, n); + clear = clear_buffer; + } + + pc->frame_type = (FRAME_TYPE)(clear[0] & 1); + pc->version = (clear[0] >> 1) & 7; + pc->show_frame = (clear[0] >> 4) & 1; first_partition_length_in_bytes = - (data0 | (data1 << 8) | (data2 << 16)) >> 5; + (clear[0] | (clear[1] << 8) | (clear[2] << 16)) >> 5; if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end @@ -1039,6 +1045,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) "Truncated packet or corrupt partition 0 length"); data += 3; + clear += 3; vp8_setup_version(pc); @@ -1051,13 +1058,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) */ if (!pbi->ec_active || data + 3 < data_end) { - const unsigned char data0 = decrypt_byte(data + 0, origin, - pbi->decrypt_key); - const unsigned char data1 = decrypt_byte(data + 1, origin, - pbi->decrypt_key); - const unsigned char data2 = decrypt_byte(data + 2, origin, - pbi->decrypt_key); - if (data0 != 0x9d || data1 != 0x01 || data2 != 0x2a) + if (clear[0] != 0x9d || clear[1] != 0x01 || clear[2] != 0x2a) vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM, "Invalid frame sync code"); } @@ -1068,22 +1069,13 @@ int vp8_decode_frame(VP8D_COMP *pbi) */ if (!pbi->ec_active || data + 6 < data_end) { - const unsigned char data3 = decrypt_byte(data + 3, origin, - pbi->decrypt_key); - const unsigned char data4 = decrypt_byte(data + 4, origin, - pbi->decrypt_key); - const unsigned char data5 = decrypt_byte(data + 5, origin, - pbi->decrypt_key); - const unsigned char data6 = decrypt_byte(data + 6, origin, - pbi->decrypt_key); - - pc->Width = (data3 | (data4 << 8)) & 0x3fff; - pc->horiz_scale = data4 >> 6; - pc->Height = (data5 | (data6 << 8)) & 0x3fff; - pc->vert_scale = data6 >> 6; + pc->Width = (clear[3] | (clear[4] << 8)) & 0x3fff; + pc->horiz_scale = clear[4] >> 6; + pc->Height = (clear[5] | (clear[6] << 8)) & 0x3fff; + pc->vert_scale = clear[6] >> 6; } data += 7; - + clear += 7; } else { @@ -1098,11 +1090,8 @@ int vp8_decode_frame(VP8D_COMP *pbi) init_frame(pbi); - if (vp8dx_start_decode(bc, - data, - (unsigned int)(data_end - data), - pbi->fragments.ptrs[0], - pbi->decrypt_key)) + if (vp8dx_start_decode(bc, data, (unsigned int)(data_end - data), + pbi->decrypt_cb, pbi->decrypt_state)) vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0"); if (pc->frame_type == KEY_FRAME) { diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index c2325ebef..54a98f7cc 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -122,7 +122,8 @@ typedef struct VP8D_COMP int independent_partitions; int frame_corrupt_residual; - const unsigned char *decrypt_key; + vp8_decrypt_cb *decrypt_cb; + void *decrypt_state; } VP8D_COMP; int vp8_decode_frame(VP8D_COMP *cpi); diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 45cf3859e..c826f696d 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -29,8 +29,6 @@ #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \ VPX_CODEC_CAP_ERROR_CONCEALMENT : 0) -#define VP8_DECRYPT_KEY_SIZE 32 - typedef vpx_codec_stream_info_t vp8_stream_info_t; /* Structures for handling memory allocations */ @@ -75,7 +73,8 @@ struct vpx_codec_alg_priv int dbg_color_b_modes_flag; int dbg_display_mv_flag; #endif - unsigned char decrypt_key[VP8_DECRYPT_KEY_SIZE]; + vp8_decrypt_cb *decrypt_cb; + void *decrypt_state; vpx_image_t img; int img_setup; struct frame_buffers yv12_frame_buffers; @@ -153,8 +152,6 @@ static vpx_codec_err_t vp8_validate_mmaps(const vp8_stream_info_t *si, return res; } -static const unsigned char fake_decrypt_key[VP8_DECRYPT_KEY_SIZE] = { 0 }; - static void vp8_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) { int i; @@ -169,8 +166,8 @@ static void vp8_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) ctx->priv->alg_priv->mmaps[0] = *mmap; ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); - memcpy(ctx->priv->alg_priv->decrypt_key, fake_decrypt_key, - VP8_DECRYPT_KEY_SIZE); + ctx->priv->alg_priv->decrypt_cb = NULL; + ctx->priv->alg_priv->decrypt_state = NULL; ctx->priv->init_flags = ctx->init_flags; if (ctx->config.dec) @@ -269,10 +266,11 @@ static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx) return VPX_CODEC_OK; } -static vpx_codec_err_t vp8_peek_si_external(const uint8_t *data, - unsigned int data_sz, +static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data, + unsigned int data_sz, vpx_codec_stream_info_t *si, - const unsigned char *decrypt_key) + vp8_decrypt_cb *decrypt_cb, + void *decrypt_state) { vpx_codec_err_t res = VPX_CODEC_OK; @@ -288,27 +286,26 @@ static vpx_codec_err_t vp8_peek_si_external(const uint8_t *data, * 4 bytes:- including image width and height in the lowest 14 bits * of each 2-byte value. */ - - const uint8_t data0 = decrypt_byte(data, data, decrypt_key); - si->is_kf = 0; - if (data_sz >= 10 && !(data0 & 0x01)) /* I-Frame */ + uint8_t clear_buffer[10]; + const uint8_t *clear = data; + if (decrypt_cb) { - const uint8_t data3 = decrypt_byte(data + 3, data, decrypt_key); - const uint8_t data4 = decrypt_byte(data + 4, data, decrypt_key); - const uint8_t data5 = decrypt_byte(data + 5, data, decrypt_key); - const uint8_t data6 = decrypt_byte(data + 6, data, decrypt_key); - const uint8_t data7 = decrypt_byte(data + 7, data, decrypt_key); - const uint8_t data8 = decrypt_byte(data + 8, data, decrypt_key); - const uint8_t data9 = decrypt_byte(data + 9, data, decrypt_key); + int n = data_sz > 10 ? 10 : data_sz; + decrypt_cb(decrypt_state, data, clear_buffer, n); + clear = clear_buffer; + } + si->is_kf = 0; + if (data_sz >= 10 && !(clear[0] & 0x01)) /* I-Frame */ + { si->is_kf = 1; /* vet via sync code */ - if (data3 != 0x9d || data4 != 0x01 || data5 != 0x2a) + if (clear[3] != 0x9d || clear[4] != 0x01 || clear[5] != 0x2a) res = VPX_CODEC_UNSUP_BITSTREAM; - si->w = (data6 | (data7 << 8)) & 0x3fff; - si->h = (data8 | (data9 << 8)) & 0x3fff; + si->w = (clear[6] | (clear[7] << 8)) & 0x3fff; + si->h = (clear[8] | (clear[9] << 8)) & 0x3fff; /*printf("w=%d, h=%d\n", si->w, si->h);*/ if (!(si->h | si->w)) @@ -326,7 +323,7 @@ static vpx_codec_err_t vp8_peek_si_external(const uint8_t *data, static vpx_codec_err_t vp8_peek_si(const uint8_t *data, unsigned int data_sz, vpx_codec_stream_info_t *si) { - return vp8_peek_si_external(data, data_sz, si, fake_decrypt_key); + return vp8_peek_si_internal(data, data_sz, si, NULL, NULL); } static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx, @@ -455,10 +452,8 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, w = ctx->si.w; h = ctx->si.h; - res = vp8_peek_si_external(ctx->fragments.ptrs[0], - ctx->fragments.sizes[0], - &ctx->si, - ctx->decrypt_key); + res = vp8_peek_si_internal(ctx->fragments.ptrs[0], ctx->fragments.sizes[0], + &ctx->si, ctx->decrypt_cb, ctx->decrypt_state); if((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) { @@ -532,7 +527,8 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, } res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf); - ctx->yv12_frame_buffers.pbi[0]->decrypt_key = ctx->decrypt_key; + ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb; + ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state; } ctx->decoder_init = 1; @@ -956,17 +952,22 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, } - -static vpx_codec_err_t vp8_set_decrypt_key(vpx_codec_alg_priv_t *ctx, - int ctr_id, - va_list args) +static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx, + int ctrl_id, + va_list args) { - const unsigned char *data = va_arg(args, const unsigned char *); - if (data == NULL) { - return VPX_CODEC_INVALID_PARAM; - } + vp8_decrypt_init *init = va_arg(args, vp8_decrypt_init *); - memcpy(ctx->decrypt_key, data, VP8_DECRYPT_KEY_SIZE); + if (init) + { + ctx->decrypt_cb = init->decrypt_cb; + ctx->decrypt_state = init->decrypt_state; + } + else + { + ctx->decrypt_cb = NULL; + ctx->decrypt_state = NULL; + } return VPX_CODEC_OK; } @@ -982,7 +983,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, {VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted}, {VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame}, - {VP8_SET_DECRYPT_KEY, vp8_set_decrypt_key}, + {VP8D_SET_DECRYPTOR, vp8_set_decryptor}, { -1, NULL}, }; diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 98b19e8ae..37d29af17 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -217,8 +217,6 @@ typedef struct { int mb_mode_context[MAX_REF_FRAMES]; unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ - unsigned char need_to_clamp_mvs; - unsigned char need_to_clamp_secondmv; unsigned char segment_id; // Segment id for current frame // Flags used for prediction status of various bistream signals diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c index d7817114e..a6922715e 100644 --- a/vp9/common/vp9_findnearmv.c +++ b/vp9/common/vp9_findnearmv.c @@ -13,7 +13,6 @@ #include "vp9/common/vp9_findnearmv.h" #include "vp9/common/vp9_mvref_common.h" #include "vp9/common/vp9_sadmxn.h" -#include "vp9/common/vp9_subpelvar.h" static void lower_mv_precision(int_mv *mv, int usehp) { if (!usehp || !vp9_use_nmv_hp(&mv->as_mv)) { @@ -24,12 +23,6 @@ static void lower_mv_precision(int_mv *mv, int usehp) { } } -vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, vp9_prob *p, int context) { - p[0] = pc->fc.inter_mode_probs[context][0]; - p[1] = pc->fc.inter_mode_probs[context][1]; - p[2] = pc->fc.inter_mode_probs[context][2]; - return p; -} void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int_mv *mvlist, diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h index 17fef125c..d4ae2102d 100644 --- a/vp9/common/vp9_findnearmv.h +++ b/vp9/common/vp9_findnearmv.h @@ -70,10 +70,6 @@ static int check_mv_bounds(int_mv *mv, mv->as_mv.row > mb_to_bottom_edge; } -vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, - vp9_prob p[VP9_INTER_MODES - 1], - int context); - void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *pc, MACROBLOCKD *xd, int_mv *dst_nearest, diff --git a/vp9/common/vp9_idct.h b/vp9/common/vp9_idct.h index af35432c4..64f14c993 100644 --- a/vp9/common/vp9_idct.h +++ b/vp9/common/vp9_idct.h @@ -71,12 +71,6 @@ static INLINE int dct_const_round_shift(int input) { return rv; } -static INLINE int dct_32_round(int input) { - int rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS); - assert(-131072 <= rv && rv <= 131071); - return rv; -} - typedef void (*transform_1d)(int16_t*, int16_t*); typedef struct { diff --git a/vp9/common/vp9_invtrans.c b/vp9/common/vp9_invtrans.c deleted file mode 100644 index d47fca190..000000000 --- a/vp9/common/vp9_invtrans.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_invtrans.h" -#include "./vp9_rtcd.h" - -void vp9_inverse_transform_b_4x4_add(MACROBLOCKD *xd, int eob, int16_t *dqcoeff, - uint8_t *dest, int stride) { - if (eob <= 1) - xd->inv_txm4x4_1_add(dqcoeff, dest, stride); - else - xd->inv_txm4x4_add(dqcoeff, dest, stride); -} diff --git a/vp9/common/vp9_invtrans.h b/vp9/common/vp9_invtrans.h deleted file mode 100644 index dbdc50a2a..000000000 --- a/vp9/common/vp9_invtrans.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VP9_COMMON_VP9_INVTRANS_H_ -#define VP9_COMMON_VP9_INVTRANS_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_blockd.h" - -void vp9_inverse_transform_b_4x4_add(MACROBLOCKD *xd, int eob, int16_t *dqcoeff, - uint8_t *dest, int stride); -#endif // VP9_COMMON_VP9_INVTRANS_H_ diff --git a/vp9/common/vp9_modecont.c b/vp9/common/vp9_modecont.c index bdb0049b4..5d92cfa00 100644 --- a/vp9/common/vp9_modecont.c +++ b/vp9/common/vp9_modecont.c @@ -9,7 +9,7 @@ */ -#include "vp9/common/vp9_entropy.h" +#include "vp9/common/vp9_modecont.h" const vp9_prob vp9_default_inter_mode_probs[INTER_MODE_CONTEXTS] [VP9_INTER_MODES - 1] = { diff --git a/vp9/common/vp9_modecont.h b/vp9/common/vp9_modecont.h index 1a3e993a5..3ec607947 100644 --- a/vp9/common/vp9_modecont.h +++ b/vp9/common/vp9_modecont.h @@ -13,7 +13,7 @@ #include "vp9/common/vp9_entropy.h" -extern const int vp9_default_inter_mode_probs[INTER_MODE_CONTEXTS] - [VP9_INTER_MODES - 1]; +extern const vp9_prob vp9_default_inter_mode_probs[INTER_MODE_CONTEXTS] + [VP9_INTER_MODES - 1]; #endif // VP9_COMMON_VP9_MODECONT_H_ diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh index 85fbd79bb..a405aab8d 100644 --- a/vp9/common/vp9_rtcd_defs.sh +++ b/vp9/common/vp9_rtcd_defs.sh @@ -381,10 +381,10 @@ specialize vp9_sad8x8 mmx sse2 # TODO(jingning): need to covert these functions into mmx/sse2 form prototype unsigned int vp9_sad8x4 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int max_sad" -specialize vp9_sad8x4 +specialize vp9_sad8x4 sse2 prototype unsigned int vp9_sad4x8 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int max_sad" -specialize vp9_sad4x8 +specialize vp9_sad4x8 sse prototype unsigned int vp9_sad4x4 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int max_sad" specialize vp9_sad4x4 mmx sse @@ -572,6 +572,9 @@ specialize vp9_short_fdct8x4 sse2 prototype void vp9_short_fdct32x32 "int16_t *InputData, int16_t *OutputData, int pitch" specialize vp9_short_fdct32x32 +prototype void vp9_short_fdct32x32_rd "int16_t *InputData, int16_t *OutputData, int pitch" +specialize vp9_short_fdct32x32_rd + prototype void vp9_short_fdct16x16 "int16_t *InputData, int16_t *OutputData, int pitch" specialize vp9_short_fdct16x16 sse2 diff --git a/vp9/common/x86/vp9_subpixel_variance_sse2.c b/vp9/common/x86/vp9_subpixel_variance_sse2.c deleted file mode 100644 index c20b9fbe9..000000000 --- a/vp9/common/x86/vp9_subpixel_variance_sse2.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#define HALFNDX 8 - -void vp9_half_horiz_variance16x_h_sse2(const unsigned char *ref_ptr, - int ref_pixels_per_line, - const unsigned char *src_ptr, - int src_pixels_per_line, - unsigned int Height, - int *sum, - unsigned int *sumsquared); - -void vp9_half_vert_variance16x_h_sse2(const unsigned char *ref_ptr, - int ref_pixels_per_line, - const unsigned char *src_ptr, - int src_pixels_per_line, - unsigned int Height, - int *sum, - unsigned int *sumsquared); - -void vp9_half_horiz_vert_variance16x_h_sse2(const unsigned char *ref_ptr, - int ref_pixels_per_line, - const unsigned char *src_ptr, - int src_pixels_per_line, - unsigned int Height, - int *sum, - unsigned int *sumsquared); - -void vp9_filter_block2d_bil_var_sse2(const unsigned char *ref_ptr, - int ref_pixels_per_line, - const unsigned char *src_ptr, - int src_pixels_per_line, - unsigned int Height, - int xoffset, - int yoffset, - int *sum, - unsigned int *sumsquared); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 7a8fb0e58..b3d41bed7 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -501,8 +501,6 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, int mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, mb_to_bottom_edge; int j, idx, idy; - mbmi->need_to_clamp_mvs = 0; - mbmi->need_to_clamp_secondmv = 0; mbmi->ref_frame[1] = NONE; // Make sure the MACROBLOCKD mode info pointer is pointed at the @@ -562,7 +560,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, if (mbmi->ref_frame[0] != INTRA_FRAME) { int_mv nearest, nearby, best_mv; int_mv nearest_second, nearby_second, best_mv_second; - vp9_prob mv_ref_p[VP9_INTER_MODES - 1]; + vp9_prob *mv_ref_p; read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame); @@ -576,7 +574,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mbmi->ref_frame[0], mbmi->ref_mvs[mbmi->ref_frame[0]], cm->ref_frame_sign_bias); - vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[mbmi->ref_frame[0]]); + mv_ref_p = cm->fc.inter_mode_probs[ + mbmi->mb_mode_context[mbmi->ref_frame[0]]]; // If the segment level skip mode enabled if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) { @@ -624,7 +623,6 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mbmi->uv_mode = DC_PRED; if (mbmi->sb_type < BLOCK_SIZE_SB8X8) { - mbmi->need_to_clamp_mvs = 0; for (idy = 0; idy < 2; idy += bh) { for (idx = 0; idx < 2; idx += bw) { int_mv blockmv, secondmv; @@ -735,21 +733,9 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, case NEWMV: decode_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount, xd->allow_high_precision_mv); - mbmi->need_to_clamp_mvs = check_mv_bounds(mv0, - mb_to_left_edge, - mb_to_right_edge, - mb_to_top_edge, - mb_to_bottom_edge); - - if (mbmi->ref_frame[1] > 0) { + if (mbmi->ref_frame[1] > 0) decode_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc, &cm->fc.NMVcount, xd->allow_high_precision_mv); - mbmi->need_to_clamp_secondmv = check_mv_bounds(mv1, - mb_to_left_edge, - mb_to_right_edge, - mb_to_top_edge, - mb_to_bottom_edge); - } break; default: #if CONFIG_DEBUG diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 5fda068ac..193353272 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -20,7 +20,6 @@ #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_reconinter.h" #include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_invtrans.h" #include "vp9/common/vp9_alloccommon.h" #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_quant_common.h" @@ -199,14 +198,14 @@ static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) { static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, int ss_txfrm_size, void *arg) { MACROBLOCKD* const xd = arg; - int16_t* const qcoeff = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16); - const int stride = xd->plane[plane].dst.stride; + struct macroblockd_plane *pd = &xd->plane[plane]; + int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block, 16); + const int stride = pd->dst.stride; const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane, block, ss_txfrm_size); uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane, raster_block, - xd->plane[plane].dst.buf, - stride); + pd->dst.buf, stride); TX_TYPE tx_type; @@ -214,23 +213,20 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, case TX_4X4: tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT; if (tx_type == DCT_DCT) - xd->itxm_add(qcoeff, dst, stride, xd->plane[plane].eobs[block]); + xd->itxm_add(qcoeff, dst, stride, pd->eobs[block]); else - vp9_iht_add_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); + vp9_iht_add_c(tx_type, qcoeff, dst, stride, pd->eobs[block]); break; case TX_8X8: tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT; - vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); + vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride, pd->eobs[block]); break; case TX_16X16: tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT; - vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); + vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride, pd->eobs[block]); break; case TX_32X32: - vp9_idct_add_32x32(qcoeff, dst, stride, xd->plane[plane].eobs[block]); + vp9_idct_add_32x32(qcoeff, dst, stride, pd->eobs[block]); break; } } @@ -238,61 +234,40 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, int ss_txfrm_size, void *arg) { MACROBLOCKD* const xd = arg; - int16_t* const qcoeff = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16); - const int stride = xd->plane[plane].dst.stride; + struct macroblockd_plane *pd = &xd->plane[plane]; + const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane, block, ss_txfrm_size); uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane, raster_block, - xd->plane[plane].dst.buf, - stride); + pd->dst.buf, pd->dst.stride); const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2); - TX_TYPE tx_type; - int mode, b_mode; + int b_mode; int plane_b_size; - int tx_ib = raster_block >> tx_size; - mode = plane == 0? xd->mode_info_context->mbmi.mode: - xd->mode_info_context->mbmi.uv_mode; + const int tx_ib = raster_block >> tx_size; + const int mode = plane == 0 ? xd->mode_info_context->mbmi.mode + : xd->mode_info_context->mbmi.uv_mode; - if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8 && plane == 0) { + if (plane == 0 && xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) { assert(bsize == BLOCK_SIZE_SB8X8); b_mode = xd->mode_info_context->bmi[raster_block].as_mode.first; } else { b_mode = mode; } - if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { + if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) extend_for_intra(xd, plane, block, bsize, ss_txfrm_size); - } - plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x; - vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, - b_mode, dst, xd->plane[plane].dst.stride); + plane_b_size = b_width_log2(bsize) - pd->subsampling_x; + vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, b_mode, + dst, pd->dst.stride); - switch (ss_txfrm_size / 2) { - case TX_4X4: - tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT; - if (tx_type == DCT_DCT) - xd->itxm_add(qcoeff, dst, stride, xd->plane[plane].eobs[block]); - else - vp9_iht_add_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); - break; - case TX_8X8: - tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT; - vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); - break; - case TX_16X16: - tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT; - vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride, - xd->plane[plane].eobs[block]); - break; - case TX_32X32: - vp9_idct_add_32x32(qcoeff, dst, stride, xd->plane[plane].eobs[block]); - break; - } + // Early exit if there are no coefficients + if (xd->mode_info_context->mbmi.mb_skip_coeff) + return; + + decode_block(plane, block, bsize, ss_txfrm_size, arg); } static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd, @@ -301,9 +276,7 @@ static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd, MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; assert(mbmi->ref_frame[0] != INTRA_FRAME); - - if ((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) - vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common); + vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common); // prediction vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); @@ -311,15 +284,14 @@ static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd, if (mbmi->mb_skip_coeff) { vp9_reset_sb_tokens_context(xd, bsize); } else { - // re-initialize macroblock dequantizer before detokenization if (xd->segmentation_enabled) mb_init_dequantizer(&pbi->common, xd); - if (!vp9_reader_has_error(r)) { - vp9_decode_tokens(pbi, xd, r, bsize); - } + if (!vp9_reader_has_error(r)) + vp9_decode_tokens(pbi, r, bsize); + + foreach_transformed_block(xd, bsize, decode_block, xd); } - foreach_transformed_block(xd, bsize, decode_block, xd); } static void decode_sb_intra(VP9D_COMP *pbi, MACROBLOCKD *xd, @@ -329,13 +301,11 @@ static void decode_sb_intra(VP9D_COMP *pbi, MACROBLOCKD *xd, if (mbmi->mb_skip_coeff) { vp9_reset_sb_tokens_context(xd, bsize); } else { - // re-initialize macroblock dequantizer before detokenization if (xd->segmentation_enabled) mb_init_dequantizer(&pbi->common, xd); - if (!vp9_reader_has_error(r)) { - vp9_decode_tokens(pbi, xd, r, bsize); - } + if (!vp9_reader_has_error(r)) + vp9_decode_tokens(pbi, r, bsize); } foreach_transformed_block(xd, bsize, decode_block_intra, xd); @@ -355,8 +325,7 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, assert(mbmi->sb_type == bsize); assert(mbmi->ref_frame[0] != INTRA_FRAME); - if (pbi->common.frame_type != KEY_FRAME) - vp9_setup_interp_filters(xd, mbmi->interp_filter, pc); + vp9_setup_interp_filters(xd, mbmi->interp_filter, pc); // generate prediction vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); @@ -369,7 +338,7 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, mb_init_dequantizer(pc, xd); // dequantization and idct - eobtotal = vp9_decode_tokens(pbi, xd, r, bsize); + eobtotal = vp9_decode_tokens(pbi, r, bsize); if (eobtotal == 0) { // skip loopfilter for (n = 0; n < bw * bh; n++) { const int x_idx = n & (bw - 1), y_idx = n >> bwl; @@ -385,10 +354,10 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, int mi_row, int mi_col) { - const int bh = 1 << mi_height_log2(bsize); - const int bw = 1 << mi_width_log2(bsize); VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; + const int bh = 1 << mi_height_log2(bsize); + const int bw = 1 << mi_width_log2(bsize); const int mi_idx = mi_row * cm->mode_info_stride + mi_col; int i; @@ -396,14 +365,14 @@ static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, xd->mode_info_context->mbmi.sb_type = bsize; // Special case: if prev_mi is NULL, the previous mode info context // cannot be used. - xd->prev_mode_info_context = cm->prev_mi ? - cm->prev_mi + mi_idx : NULL; + xd->prev_mode_info_context = cm->prev_mi ? cm->prev_mi + mi_idx : NULL; for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].above_context = cm->above_context[i] + - (mi_col * 2 >> xd->plane[i].subsampling_x); - xd->plane[i].left_context = cm->left_context[i] + - (((mi_row * 2) & 15) >> xd->plane[i].subsampling_y); + struct macroblockd_plane *pd = &xd->plane[i]; + pd->above_context = cm->above_context[i] + + (mi_col * 2 >> pd->subsampling_x); + pd->left_context = cm->left_context[i] + + (((mi_row * 2) & 15) >> pd->subsampling_y); } xd->above_seg_context = cm->above_seg_context + mi_col; xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK); @@ -420,26 +389,24 @@ static void set_refs(VP9D_COMP *pbi, int mi_row, int mi_col) { MACROBLOCKD *const xd = &pbi->mb; MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; - if (mbmi->ref_frame[0] > INTRA_FRAME) { + // Select the appropriate reference frame for this MB + const int fb_idx = cm->active_ref_idx[mbmi->ref_frame[0] - 1]; + const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx]; + xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; + xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; + setup_pre_planes(xd, cfg, NULL, mi_row, mi_col, xd->scale_factor, + xd->scale_factor_uv); + xd->corrupted |= cfg->corrupted; + + if (mbmi->ref_frame[1] > INTRA_FRAME) { // Select the appropriate reference frame for this MB - const int fb_idx = cm->active_ref_idx[mbmi->ref_frame[0] - 1]; - const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx]; - xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; - xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; - setup_pre_planes(xd, cfg, NULL, mi_row, mi_col, - xd->scale_factor, xd->scale_factor_uv); - xd->corrupted |= cfg->corrupted; - - if (mbmi->ref_frame[1] > INTRA_FRAME) { - // Select the appropriate reference frame for this MB - const int second_fb_idx = cm->active_ref_idx[mbmi->ref_frame[1] - 1]; - const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx]; - xd->scale_factor[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; - xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; - setup_pre_planes(xd, NULL, second_cfg, mi_row, mi_col, - xd->scale_factor, xd->scale_factor_uv); - xd->corrupted |= second_cfg->corrupted; - } + const int second_fb_idx = cm->active_ref_idx[mbmi->ref_frame[1] - 1]; + const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx]; + xd->scale_factor[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; + xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; + setup_pre_planes(xd, NULL, second_cfg, mi_row, mi_col, xd->scale_factor, + xd->scale_factor_uv); + xd->corrupted |= second_cfg->corrupted; } } @@ -452,16 +419,17 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, return; set_offsets(pbi, bsize, mi_row, mi_col); vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r); - set_refs(pbi, mi_row, mi_col); - if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) + if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) { decode_sb_intra(pbi, xd, mi_row, mi_col, r, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); - else if (bsize < BLOCK_SIZE_SB8X8) - decode_atom(pbi, xd, mi_row, mi_col, r, BLOCK_SIZE_SB8X8); - else - decode_sb(pbi, xd, mi_row, mi_col, r, bsize); - + } else { + set_refs(pbi, mi_row, mi_col); + if (bsize < BLOCK_SIZE_SB8X8) + decode_atom(pbi, xd, mi_row, mi_col, r, BLOCK_SIZE_SB8X8); + else + decode_sb(pbi, xd, mi_row, mi_col, r, bsize); + } xd->corrupted |= vp9_reader_has_error(r); } @@ -469,8 +437,7 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col, vp9_reader* r, BLOCK_SIZE_TYPE bsize) { VP9_COMMON *const pc = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; - int bsl = mi_width_log2(bsize), bs = (1 << bsl) / 2; - int n; + int bs = (1 << mi_width_log2(bsize)) / 2, n; PARTITION_TYPE partition = PARTITION_NONE; BLOCK_SIZE_TYPE subsize; @@ -558,26 +525,22 @@ static void setup_token_decoder(VP9D_COMP *pbi, static void read_coef_probs_common(FRAME_CONTEXT *fc, TX_SIZE tx_size, vp9_reader *r) { - const int entropy_nodes_update = UNCONSTRAINED_NODES; vp9_coeff_probs_model *coef_probs = fc->coef_probs[tx_size]; - int i, j, k, l, m; - if (vp9_read_bit(r)) { + int i, j, k, l, m; for (i = 0; i < BLOCK_TYPES; i++) { for (j = 0; j < REF_TYPES; j++) { for (k = 0; k < COEF_BANDS; k++) { for (l = 0; l < PREV_COEF_CONTEXTS; l++) { - const int mstart = 0; if (l >= 3 && k == 0) continue; - for (m = mstart; m < entropy_nodes_update; m++) { + for (m = 0; m < UNCONSTRAINED_NODES; m++) { vp9_prob *const p = coef_probs[i][j][k][l] + m; - if (vp9_read(r, VP9_COEF_UPDATE_PROB)) { + if (vp9_read(r, VP9_COEF_UPDATE_PROB)) *p = vp9_read_prob_diff_update(r, *p); - } } } } @@ -1113,8 +1076,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi, cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2); - if ((cm->frame_type == KEY_FRAME) || - cm->error_resilient_mode || cm->intra_only) + if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode || cm->intra_only) vp9_setup_past_independence(cm, xd); setup_loopfilter(pbi, rb); diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index d06c9b000..3bbb212a3 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c @@ -8,15 +8,16 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include "vpx_mem/vpx_mem.h" +#include "vpx_ports/mem.h" #include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_common.h" -#include "vp9/decoder/vp9_onyxd_int.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vp9/decoder/vp9_detokenize.h" #include "vp9/common/vp9_seg_common.h" +#include "vp9/decoder/vp9_detokenize.h" +#include "vp9/decoder/vp9_onyxd_int.h" + #if CONFIG_BALANCED_COEFTREE #define ZERO_CONTEXT_NODE 0 #define EOB_CONTEXT_NODE 1 @@ -24,6 +25,7 @@ #define EOB_CONTEXT_NODE 0 #define ZERO_CONTEXT_NODE 1 #endif + #define ONE_CONTEXT_NODE 2 #define LOW_VAL_CONTEXT_NODE 3 #define TWO_CONTEXT_NODE 4 @@ -89,13 +91,12 @@ DECLARE_ALIGNED(16, extern const uint8_t, val += 1 << bits_count; \ } while (0); -static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd, +static int decode_coefs(FRAME_CONTEXT *fc, const MACROBLOCKD *xd, vp9_reader *r, int block_idx, PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr, TX_SIZE txfm_size, const int16_t *dq, ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) { ENTROPY_CONTEXT above_ec, left_ec; - FRAME_CONTEXT *const fc = &dx->common.fc; int pt, c = 0, pad, default_eob; int band; vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES]; @@ -298,10 +299,10 @@ static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) { struct decode_block_args { VP9D_COMP *pbi; - MACROBLOCKD *xd; vp9_reader *r; int *eobtotal; }; + static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, int ss_txfrm_size, @@ -310,42 +311,37 @@ static void decode_block(int plane, int block, const int bw = b_width_log2(bsize); // find the maximum eob for this transform size, adjusted by segment - MACROBLOCKD *xd = arg->xd; - const int segment_id = arg->xd->mode_info_context->mbmi.segment_id; + MACROBLOCKD *xd = &arg->pbi->mb; + struct macroblockd_plane* pd = &xd->plane[plane]; + const int segment_id = xd->mode_info_context->mbmi.segment_id; const TX_SIZE ss_tx_size = ss_txfrm_size / 2; - const int seg_eob = get_eob(arg->xd, segment_id, 16 << ss_txfrm_size); - int16_t* const qcoeff_base = arg->xd->plane[plane].qcoeff; + const int seg_eob = get_eob(xd, segment_id, 16 << ss_txfrm_size); const int off = block >> ss_txfrm_size; - const int mod = bw - ss_tx_size - arg->xd->plane[plane].subsampling_x; + const int mod = bw - ss_tx_size - pd->subsampling_x; const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size; const int loff = (off >> mod) << ss_tx_size; - int pt; - ENTROPY_CONTEXT *A = arg->xd->plane[plane].above_context + aoff; - ENTROPY_CONTEXT *L = arg->xd->plane[plane].left_context + loff; - const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, block, - arg->xd->plane[plane].plane_type, seg_eob, - BLOCK_OFFSET(qcoeff_base, block, 16), - ss_tx_size, arg->xd->plane[plane].dequant, - A, - L); + + ENTROPY_CONTEXT *A = pd->above_context + aoff; + ENTROPY_CONTEXT *L = pd->left_context + loff; + const int eob = decode_coefs(&arg->pbi->common.fc, xd, arg->r, block, + pd->plane_type, seg_eob, + BLOCK_OFFSET(pd->qcoeff, block, 16), + ss_tx_size, pd->dequant, A, L); if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { set_contexts_on_border(xd, bsize, plane, ss_tx_size, eob, aoff, loff, A, L); } else { - for (pt = 0; pt < (1 << ss_tx_size); pt++) { + int pt; + for (pt = 0; pt < (1 << ss_tx_size); pt++) A[pt] = L[pt] = eob > 0; - } } - arg->xd->plane[plane].eobs[block] = eob; - arg->eobtotal[0] += eob; + pd->eobs[block] = eob; + *arg->eobtotal += eob; } -int vp9_decode_tokens(VP9D_COMP* const pbi, - MACROBLOCKD* const xd, - vp9_reader *r, - BLOCK_SIZE_TYPE bsize) { +int vp9_decode_tokens(VP9D_COMP *pbi, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { int eobtotal = 0; - struct decode_block_args args = {pbi, xd, r, &eobtotal}; - foreach_transformed_block(xd, bsize, decode_block, &args); + struct decode_block_args args = {pbi, r, &eobtotal}; + foreach_transformed_block(&pbi->mb, bsize, decode_block, &args); return eobtotal; } diff --git a/vp9/decoder/vp9_detokenize.h b/vp9/decoder/vp9_detokenize.h index 13235bda1..d46b59635 100644 --- a/vp9/decoder/vp9_detokenize.h +++ b/vp9/decoder/vp9_detokenize.h @@ -14,9 +14,6 @@ #include "vp9/decoder/vp9_onyxd_int.h" -int vp9_decode_tokens(VP9D_COMP* const pbi, - MACROBLOCKD* const xd, - vp9_reader *r, - BLOCK_SIZE_TYPE bsize); +int vp9_decode_tokens(VP9D_COMP* pbi, vp9_reader *r, BLOCK_SIZE_TYPE bsize); #endif // VP9_DECODER_VP9_DETOKENIZE_H_ diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index e18394b1e..09ab2db67 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -708,11 +708,11 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, write_intra_mode(bc, mi->uv_mode, pc->fc.uv_mode_prob[mode]); } else { - vp9_prob mv_ref_p[VP9_INTER_MODES - 1]; + vp9_prob *mv_ref_p; encode_ref_frame(cpi, bc); - vp9_mv_ref_probs(&cpi->common, mv_ref_p, mi->mb_mode_context[rf]); + mv_ref_p = cpi->common.fc.inter_mode_probs[mi->mb_mode_context[rf]]; #ifdef ENTROPY_STATS active_section = 3; diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index e78f54eb4..59cc3d95c 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -139,6 +139,9 @@ struct macroblock { int optimize; + // indicate if it is in the rd search loop or encoding process + int rd_search; + // TODO(jingning): Need to refactor the structure arrays that buffers the // coding mode decisions of each partition type. PICK_MODE_CONTEXT ab4x4_context[4][4][4]; diff --git a/vp9/encoder/vp9_dct.c b/vp9/encoder/vp9_dct.c index 8d4eec139..a90bcf5df 100644 --- a/vp9/encoder/vp9_dct.c +++ b/vp9/encoder/vp9_dct.c @@ -991,8 +991,18 @@ void vp9_short_fht16x16_c(int16_t *input, int16_t *output, } } +static INLINE int dct_32_round(int input) { + int rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS); + assert(-131072 <= rv && rv <= 131071); + return rv; +} + +static INLINE int half_round_shift(int input) { + int rv = (input + 1 + (input < 0)) >> 2; + return rv; +} -static void dct32_1d(int *input, int *output) { +static void dct32_1d(int *input, int *output, int round) { int step[32]; // Stage 1 step[0] = input[0] + input[(32 - 1)]; @@ -1101,6 +1111,44 @@ static void dct32_1d(int *input, int *output) { step[30] = output[30] + output[25]; step[31] = output[31] + output[24]; + // dump the magnitude by half, hence the intermediate values are within 1108 + // the range of 16 bits. + if (round) { + step[0] = half_round_shift(step[0]); + step[1] = half_round_shift(step[1]); + step[2] = half_round_shift(step[2]); + step[3] = half_round_shift(step[3]); + step[4] = half_round_shift(step[4]); + step[5] = half_round_shift(step[5]); + step[6] = half_round_shift(step[6]); + step[7] = half_round_shift(step[7]); + step[8] = half_round_shift(step[8]); + step[9] = half_round_shift(step[9]); + step[10] = half_round_shift(step[10]); + step[11] = half_round_shift(step[11]); + step[12] = half_round_shift(step[12]); + step[13] = half_round_shift(step[13]); + step[14] = half_round_shift(step[14]); + step[15] = half_round_shift(step[15]); + + step[16] = half_round_shift(step[16]); + step[17] = half_round_shift(step[17]); + step[18] = half_round_shift(step[18]); + step[19] = half_round_shift(step[19]); + step[20] = half_round_shift(step[20]); + step[21] = half_round_shift(step[21]); + step[22] = half_round_shift(step[22]); + step[23] = half_round_shift(step[23]); + step[24] = half_round_shift(step[24]); + step[25] = half_round_shift(step[25]); + step[26] = half_round_shift(step[26]); + step[27] = half_round_shift(step[27]); + step[28] = half_round_shift(step[28]); + step[29] = half_round_shift(step[29]); + step[30] = half_round_shift(step[30]); + step[31] = half_round_shift(step[31]); + } + // Stage 4 output[0] = step[0] + step[3]; output[1] = step[1] + step[2]; @@ -1283,12 +1331,12 @@ void vp9_short_fdct32x32_c(int16_t *input, int16_t *out, int pitch) { int output[32 * 32]; // Columns - for (i = 0; i < 32; i++) { + for (i = 0; i < 32; ++i) { int temp_in[32], temp_out[32]; - for (j = 0; j < 32; j++) + for (j = 0; j < 32; ++j) temp_in[j] = input[j * shortpitch + i] << 2; - dct32_1d(temp_in, temp_out); - for (j = 0; j < 32; j++) + dct32_1d(temp_in, temp_out, 0); + for (j = 0; j < 32; ++j) output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; } @@ -1297,8 +1345,37 @@ void vp9_short_fdct32x32_c(int16_t *input, int16_t *out, int pitch) { int temp_in[32], temp_out[32]; for (j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32]; - dct32_1d(temp_in, temp_out); + dct32_1d(temp_in, temp_out, 0); for (j = 0; j < 32; ++j) out[j + i * 32] = (temp_out[j] + 1 + (temp_out[j] < 0)) >> 2; } } + +// Note that although we use dct_32_round in dct32_1d computation flow, +// this 2d fdct32x32 for rate-distortion optimization loop is operating +// within 16 bits precision. +void vp9_short_fdct32x32_rd_c(int16_t *input, int16_t *out, int pitch) { + int shortpitch = pitch >> 1; + int i, j; + int output[32 * 32]; + + // Columns + for (i = 0; i < 32; ++i) { + int temp_in[32], temp_out[32]; + for (j = 0; j < 32; ++j) + temp_in[j] = input[j * shortpitch + i] << 2; + dct32_1d(temp_in, temp_out, 0); + for (j = 0; j < 32; ++j) + output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; + } + + // Rows + for (i = 0; i < 32; ++i) { + int temp_in[32], temp_out[32]; + for (j = 0; j < 32; ++j) + temp_in[j] = output[j + i * 32]; + dct32_1d(temp_in, temp_out, 1); + for (j = 0; j < 32; ++j) + out[j + i * 32] = temp_out[j]; + } +} diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index e9749af81..2084a6401 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -23,7 +23,6 @@ #include "vp9/encoder/vp9_segmentation.h" #include "vp9/encoder/vp9_encodeintra.h" #include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_invtrans.h" #include "vp9/encoder/vp9_rdopt.h" #include "vp9/common/vp9_findnearmv.h" #include "vp9/common/vp9_reconintra.h" @@ -603,6 +602,8 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; + x->rd_search = 1; + if (bsize < BLOCK_SIZE_SB8X8) if (xd->ab_index != 0) return; @@ -1981,6 +1982,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, const int mis = cm->mode_info_stride; const int bwl = mi_width_log2(bsize); const int bw = 1 << bwl, bh = 1 << mi_height_log2(bsize); + x->rd_search = 0; if (cm->frame_type == KEY_FRAME) { if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c index fe4e9fd0f..f29dba0c1 100644 --- a/vp9/encoder/vp9_encodeintra.c +++ b/vp9/encoder/vp9_encodeintra.c @@ -13,7 +13,6 @@ #include "vp9/encoder/vp9_quantize.h" #include "vp9/common/vp9_reconintra.h" #include "vp9/encoder/vp9_encodemb.h" -#include "vp9/common/vp9_invtrans.h" #include "vp9/encoder/vp9_encodeintra.h" int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) { diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index 90f00d2be..4f45496df 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -13,7 +13,6 @@ #include "vp9/common/vp9_reconinter.h" #include "vp9/encoder/vp9_quantize.h" #include "vp9/encoder/vp9_tokenize.h" -#include "vp9/common/vp9_invtrans.h" #include "vp9/common/vp9_reconintra.h" #include "vpx_mem/vpx_mem.h" #include "vp9/encoder/vp9_rdopt.h" @@ -39,6 +38,15 @@ void vp9_subtract_block(int rows, int cols, } } +static void inverse_transform_b_4x4_add(MACROBLOCKD *xd, int eob, + int16_t *dqcoeff, uint8_t *dest, + int stride) { + if (eob <= 1) + xd->inv_txm4x4_1_add(dqcoeff, dest, stride); + else + xd->inv_txm4x4_add(dqcoeff, dest, stride); +} + static void subtract_plane(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize, int plane) { struct macroblock_plane *const p = &x->plane[plane]; @@ -454,7 +462,10 @@ static void xform_quant(int plane, int block, BLOCK_SIZE_TYPE bsize, switch (ss_txfrm_size / 2) { case TX_32X32: - vp9_short_fdct32x32(src_diff, coeff, bw * 2); + if (x->rd_search) + vp9_short_fdct32x32_rd(src_diff, coeff, bw * 2); + else + vp9_short_fdct32x32(src_diff, coeff, bw * 2); break; case TX_16X16: tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT; @@ -527,8 +538,8 @@ static void encode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, // this is like vp9_short_idct4x4 but has a special case around eob<=1 // which is significant (not just an optimization) for the lossless // case. - vp9_inverse_transform_b_4x4_add(xd, pd->eobs[block], dqcoeff, - dst, pd->dst.stride); + inverse_transform_b_4x4_add(xd, pd->eobs[block], dqcoeff, + dst, pd->dst.stride); else vp9_short_iht4x4_add(dqcoeff, dst, pd->dst.stride, tx_type); break; @@ -667,8 +678,8 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, // this is like vp9_short_idct4x4 but has a special case around eob<=1 // which is significant (not just an optimization) for the lossless // case. - vp9_inverse_transform_b_4x4_add(xd, pd->eobs[block], dqcoeff, - dst, pd->dst.stride); + inverse_transform_b_4x4_add(xd, pd->eobs[block], dqcoeff, + dst, pd->dst.stride); else vp9_short_iht4x4_add(dqcoeff, dst, pd->dst.stride, tx_type); break; diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c index 53d8be775..ccbb624b0 100644 --- a/vp9/encoder/vp9_quantize.c +++ b/vp9/encoder/vp9_quantize.c @@ -35,6 +35,153 @@ static void quantize(int16_t *zbin_boost_orig_ptr, uint16_t *eob_ptr, const int *scan, int mul) { int i, rc, eob; + int zbins[2], nzbins[2], zbin; + int x, y, z, sz; + int zero_run = 0; + int16_t *zbin_boost_ptr = zbin_boost_orig_ptr; + int zero_flag = n_coeffs; + + vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); + vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); + + eob = -1; + + // Base ZBIN + zbins[0] = zbin_ptr[0] + zbin_oq_value; + zbins[1] = zbin_ptr[1] + zbin_oq_value; + nzbins[0] = zbins[0] * -1; + nzbins[1] = zbins[1] * -1; + + if (!skip_block) { + // Pre-scan pass + for (i = n_coeffs - 1; i >= 0; i--) { + rc = scan[i]; + z = coeff_ptr[rc] * mul; + + if (z < zbins[rc != 0] && z > nzbins[rc != 0]) { + zero_flag--; + } else { + break; + } + } + + // Quantization pass: All coefficients with index >= zero_flag are + // skippable. Note: zero_flag can be zero. + for (i = 0; i < zero_flag; i++) { + rc = scan[i]; + z = coeff_ptr[rc] * mul; + + zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]); + zero_run += (zero_run < 15); + + sz = (z >> 31); // sign of z + x = (z ^ sz) - sz; + + if (x >= zbin) { + x += (round_ptr[rc != 0]); + y = ((int)(((int)(x * quant_ptr[rc != 0]) >> 16) + x)) + >> quant_shift_ptr[rc != 0]; // quantize (x) + x = (y ^ sz) - sz; // get the sign back + qcoeff_ptr[rc] = x; // write to destination + dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0] / mul; // dequantized value + + if (y) { + eob = i; // last nonzero coeffs + zero_run = 0; // set zero_run + } + } + } + } + *eob_ptr = eob + 1; +} + +// This function works well for large transform size. +static void quantize_sparse(int16_t *zbin_boost_orig_ptr, + int16_t *coeff_ptr, int n_coeffs, int skip_block, + int16_t *zbin_ptr, int16_t *round_ptr, + int16_t *quant_ptr, uint8_t *quant_shift_ptr, + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, + int16_t *dequant_ptr, int zbin_oq_value, + uint16_t *eob_ptr, const int *scan, int mul, + int *idx_arr) { + int i, rc, eob; + int zbins[2], pzbins[2], nzbins[2], zbin; + int x, y, z, sz; + int zero_run = 0; + int16_t *zbin_boost_ptr = zbin_boost_orig_ptr; + int idx = 0; + int pre_idx = 0; + + vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); + vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); + + eob = -1; + + // Base ZBIN + zbins[0] = zbin_ptr[0] + zbin_oq_value; + zbins[1] = zbin_ptr[1] + zbin_oq_value; + // Positive and negative ZBIN + pzbins[0] = zbins[0]/mul; + pzbins[1] = zbins[1]/mul; + nzbins[0] = pzbins[0] * -1; + nzbins[1] = pzbins[1] * -1; + + if (!skip_block) { + // Pre-scan pass + for (i = 0; i < n_coeffs; i++) { + rc = scan[i]; + z = coeff_ptr[rc]; + + // If the coefficient is out of the base ZBIN range, keep it for + // quantization. + if (z >= pzbins[rc != 0] || z <= nzbins[rc != 0]) + idx_arr[idx++] = i; + } + + // Quantization pass: only process the coefficients selected in + // pre-scan pass. Note: idx can be zero. + for (i = 0; i < idx; i++) { + rc = scan[idx_arr[i]]; + + // Calculate ZBIN + zero_run += idx_arr[i] - pre_idx; + if(zero_run > 15) zero_run = 15; + zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]); + + pre_idx = idx_arr[i]; + z = coeff_ptr[rc] * mul; + sz = (z >> 31); // sign of z + x = (z ^ sz) - sz; // x = abs(z) + + if (x >= zbin) { + x += (round_ptr[rc != 0]); + y = ((int)(((int)(x * quant_ptr[rc != 0]) >> 16) + x)) + >> quant_shift_ptr[rc != 0]; // quantize (x) + + x = (y ^ sz) - sz; // get the sign back + qcoeff_ptr[rc] = x; // write to destination + dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0] / mul; // dequantized value + + if (y) { + eob = idx_arr[i]; // last nonzero coeffs + zero_run = -1; // set zero_run + } + } + } + } + *eob_ptr = eob + 1; +} +#if 0 +// Original quantize function +static void quantize(int16_t *zbin_boost_orig_ptr, + int16_t *coeff_ptr, int n_coeffs, int skip_block, + int16_t *zbin_ptr, int16_t *round_ptr, int16_t *quant_ptr, + uint8_t *quant_shift_ptr, + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, + int16_t *dequant_ptr, int zbin_oq_value, + uint16_t *eob_ptr, + const int *scan, int mul) { + int i, rc, eob; int zbin; int x, y, z, sz; int zero_run = 0; @@ -74,6 +221,7 @@ static void quantize(int16_t *zbin_boost_orig_ptr, *eob_ptr = eob + 1; } +#endif void vp9_quantize(MACROBLOCK *mb, int plane, int block, int n_coeffs, TX_TYPE tx_type) { @@ -97,19 +245,40 @@ void vp9_quantize(MACROBLOCK *mb, int plane, int block, int n_coeffs, break; } - quantize(mb->plane[plane].zrun_zbin_boost, - BLOCK_OFFSET(mb->plane[plane].coeff, block, 16), - n_coeffs, mb->skip_block, - mb->plane[plane].zbin, - mb->plane[plane].round, - mb->plane[plane].quant, - mb->plane[plane].quant_shift, - BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16), - BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), - xd->plane[plane].dequant, - mb->plane[plane].zbin_extra, - &xd->plane[plane].eobs[block], - scan, mul); + // Call different quantization for different transform size. + if (n_coeffs >= 1024) { + // Save index of picked coefficient in pre-scan pass. + int idx_arr[1024]; + + quantize_sparse(mb->plane[plane].zrun_zbin_boost, + BLOCK_OFFSET(mb->plane[plane].coeff, block, 16), + n_coeffs, mb->skip_block, + mb->plane[plane].zbin, + mb->plane[plane].round, + mb->plane[plane].quant, + mb->plane[plane].quant_shift, + BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16), + BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), + xd->plane[plane].dequant, + mb->plane[plane].zbin_extra, + &xd->plane[plane].eobs[block], + scan, mul, idx_arr); + } + else { + quantize(mb->plane[plane].zrun_zbin_boost, + BLOCK_OFFSET(mb->plane[plane].coeff, block, 16), + n_coeffs, mb->skip_block, + mb->plane[plane].zbin, + mb->plane[plane].round, + mb->plane[plane].quant, + mb->plane[plane].quant_shift, + BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16), + BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), + xd->plane[plane].dequant, + mb->plane[plane].zbin_extra, + &xd->plane[plane].eobs[block], + scan, mul); + } } void vp9_regular_quantize_b_4x4(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type, diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 7eff2d04d..9cb7ab0e1 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -992,11 +992,9 @@ int vp9_cost_mv_ref(VP9_COMP *cpi, // Dont account for mode here if segment skip is enabled. if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) { VP9_COMMON *pc = &cpi->common; - - vp9_prob p[VP9_INTER_MODES - 1]; assert(NEARESTMV <= m && m <= NEWMV); - vp9_mv_ref_probs(pc, p, mode_context); - return cost_token(vp9_sb_mv_ref_tree, p, + return cost_token(vp9_sb_mv_ref_tree, + pc->fc.inter_mode_probs[mode_context], vp9_sb_mv_ref_encoding_array - NEARESTMV + m); } else return 0; @@ -1007,6 +1005,17 @@ void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) { x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int; } +static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize, + int_mv *frame_mv, + int mi_row, int mi_col, + int_mv single_newmv[MAX_REF_FRAMES], + int *rate_mv); +static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize, + int mi_row, int mi_col, + int_mv *tmp_mv, int *rate_mv); + static int labels2mode(MACROBLOCK *x, int i, MB_PREDICTION_MODE this_mode, int_mv *this_mv, int_mv *this_second_mv, @@ -1268,13 +1277,6 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, x->e_mbd.plane[0].pre[1] = orig_pre[1]; } -static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE_TYPE bsize, - int_mv *frame_mv, - YV12_BUFFER_CONFIG **scaled_ref_frame, - int mi_row, int mi_col, - int_mv single_newmv[MAX_REF_FRAMES]); - static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi, int_mv seg_mvs[4][MAX_REF_FRAMES], @@ -1295,7 +1297,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int bhl = b_height_log2(bsize), bh = 1 << bhl; int idx, idy; vp9_variance_fn_ptr_t *v_fn_ptr; - YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL}; ENTROPY_CONTEXT t_above[4], t_left[4]; ENTROPY_CONTEXT t_above_b[4], t_left_b[4]; @@ -1431,9 +1432,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, // adjust src pointers mi_buf_shift(x, i); if (cpi->sf.comp_inter_joint_search_thresh < bsize) { - iterative_motion_search(cpi, x, bsize, frame_mv[this_mode], - scaled_ref_frame, - mi_row, mi_col, seg_mvs[i]); + int rate_mv; + joint_motion_search(cpi, x, bsize, frame_mv[this_mode], + mi_row, mi_col, seg_mvs[i], + &rate_mv); seg_mvs[i][mbmi->ref_frame[0]].as_int = frame_mv[this_mode][mbmi->ref_frame[0]].as_int; seg_mvs[i][mbmi->ref_frame[1]].as_int = @@ -1790,6 +1792,14 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, frame_type, block_size); } +static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) { + YV12_BUFFER_CONFIG *scaled_ref_frame = NULL; + int fb = get_ref_frame_idx(cpi, ref_frame); + if (cpi->scaled_ref_idx[fb] != cpi->common.ref_frame_map[fb]) + scaled_ref_frame = &cpi->common.yv12_fb[cpi->scaled_ref_idx[fb]]; + return scaled_ref_frame; +} + static void model_rd_from_var_lapndz(int var, int n, int qstep, int *rate, int *dist) { // This function models the rate and distortion for a Laplacian @@ -1881,17 +1891,98 @@ static INLINE int get_switchable_rate(VP9_COMMON *cm, MACROBLOCK *x) { return SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[c][m]; } -static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE_TYPE bsize, - int_mv *frame_mv, - YV12_BUFFER_CONFIG **scaled_ref_frame, - int mi_row, int mi_col, - int_mv single_newmv[MAX_REF_FRAMES]) { +static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize, + int mi_row, int mi_col, + int_mv *tmp_mv, int *rate_mv) { + MACROBLOCKD *xd = &x->e_mbd; + MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; + struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; + int bestsme = INT_MAX; + int further_steps, step_param = cpi->sf.first_step; + int sadpb = x->sadperbit16; + int_mv mvp_full; + int ref = mbmi->ref_frame[0]; + int_mv ref_mv = mbmi->ref_mvs[ref][0]; + int sr = 0; + const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]); + + int tmp_col_min = x->mv_col_min; + int tmp_col_max = x->mv_col_max; + int tmp_row_min = x->mv_row_min; + int tmp_row_max = x->mv_row_max; + + YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref); + + if (scaled_ref_frame) { + int i; + // Swap out the reference frame for a version that's been scaled to + // match the resolution of the current frame, allowing the existing + // motion search code to be used without additional modifications. + for (i = 0; i < MAX_MB_PLANE; i++) + backup_yv12[i] = xd->plane[i].pre[0]; + + setup_pre_planes(xd, scaled_ref_frame, NULL, mi_row, mi_col, + NULL, NULL); + } + + vp9_clamp_mv_min_max(x, &ref_mv); + + sr = vp9_init_search_range(cpi->common.width, cpi->common.height); + + // mvp_full.as_int = ref_mv[0].as_int; + mvp_full.as_int = + mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int; + + mvp_full.as_mv.col >>= 3; + mvp_full.as_mv.row >>= 3; + + // adjust search range according to sr from mv prediction + step_param = MAX(step_param, sr); + + // Further step/diamond searches as necessary + further_steps = (cpi->sf.max_step_search_steps - 1) - step_param; + + bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, + sadpb, further_steps, 1, + &cpi->fn_ptr[block_size], + &ref_mv, tmp_mv); + + x->mv_col_min = tmp_col_min; + x->mv_col_max = tmp_col_max; + x->mv_row_min = tmp_row_min; + x->mv_row_max = tmp_row_max; + + if (bestsme < INT_MAX) { + int dis; /* TODO: use dis in distortion calculation later. */ + unsigned int sse; + cpi->find_fractional_mv_step(x, tmp_mv, &ref_mv, + x->errorperbit, + &cpi->fn_ptr[block_size], + x->nmvjointcost, x->mvcost, + &dis, &sse); + } + *rate_mv = vp9_mv_bit_cost(tmp_mv, &ref_mv, + x->nmvjointcost, x->mvcost, + 96, xd->allow_high_precision_mv); + if (scaled_ref_frame) { + int i; + for (i = 0; i < MAX_MB_PLANE; i++) + xd->plane[i].pre[0] = backup_yv12[i]; + } +} + +static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize, + int_mv *frame_mv, + int mi_row, int mi_col, + int_mv single_newmv[MAX_REF_FRAMES], + int *rate_mv) { int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize); MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; int refs[2] = { mbmi->ref_frame[0], - (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; + (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; int_mv ref_mv[2]; const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]); int ite; @@ -1903,6 +1994,9 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, struct buf_2d backup_second_yv12[MAX_MB_PLANE] = {{0}}; struct buf_2d scaled_first_yv12; int last_besterr[2] = {INT_MAX, INT_MAX}; + YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL}; + scaled_ref_frame[0] = get_scaled_ref_frame(cpi, mbmi->ref_frame[0]); + scaled_ref_frame[1] = get_scaled_ref_frame(cpi, mbmi->ref_frame[1]); ref_mv[0] = mbmi->ref_mvs[refs[0]][0]; ref_mv[1] = mbmi->ref_mvs[refs[1]][0]; @@ -1928,9 +2022,9 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, } xd->scale_factor[0].set_scaled_offsets(&xd->scale_factor[0], - mi_row, mi_col); + mi_row, mi_col); xd->scale_factor[1].set_scaled_offsets(&xd->scale_factor[1], - mi_row, mi_col); + mi_row, mi_col); scaled_first_yv12 = xd->plane[0].pre[0]; // Initialize mv using single prediction mode result. @@ -2025,6 +2119,14 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[1] = backup_second_yv12[i]; } + *rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]], + &mbmi->ref_mvs[refs[0]][0], + x->nmvjointcost, x->mvcost, 96, + x->e_mbd.allow_high_precision_mv); + *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]], + &mbmi->ref_mvs[refs[1]][0], + x->nmvjointcost, x->mvcost, 96, + x->e_mbd.allow_high_precision_mv); vpx_free(second_pred); } @@ -2038,7 +2140,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int *mode_excluded, int *disable_skip, INTERPOLATIONFILTERTYPE *best_filter, int_mv *frame_mv, - YV12_BUFFER_CONFIG **scaled_ref_frame, int mi_row, int mi_col, int_mv single_newmv[MAX_REF_FRAMES]) { const int bw = 1 << mi_width_log2(bsize), bh = 1 << mi_height_log2(bsize); @@ -2054,9 +2155,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, const int this_mode = mbmi->mode; int i; int refs[2] = { mbmi->ref_frame[0], - (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; + (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; int_mv cur_mv[2]; - int_mv ref_mv[2]; int64_t this_rd = 0; unsigned char tmp_buf[MAX_MB_PLANE][64 * 64]; int pred_exists = 0; @@ -2065,108 +2165,39 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int64_t rd, best_rd = INT64_MAX; switch (this_mode) { + int rate_mv; case NEWMV: - ref_mv[0] = mbmi->ref_mvs[refs[0]][0]; - ref_mv[1] = mbmi->ref_mvs[refs[1]][0]; - if (is_comp_pred) { // Initialize mv using single prediction mode result. frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int; frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int; - if (cpi->sf.comp_inter_joint_search_thresh < bsize) - iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame, - mi_row, mi_col, single_newmv); - + if (cpi->sf.comp_inter_joint_search_thresh < bsize) { + joint_motion_search(cpi, x, bsize, frame_mv, + mi_row, mi_col, single_newmv, &rate_mv); + } else { + rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]], + &mbmi->ref_mvs[refs[0]][0], + x->nmvjointcost, x->mvcost, 96, + x->e_mbd.allow_high_precision_mv); + rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]], + &mbmi->ref_mvs[refs[1]][0], + x->nmvjointcost, x->mvcost, 96, + x->e_mbd.allow_high_precision_mv); + } if (frame_mv[refs[0]].as_int == INVALID_MV || frame_mv[refs[1]].as_int == INVALID_MV) return INT64_MAX; - *rate2 += vp9_mv_bit_cost(&frame_mv[refs[0]], - &ref_mv[0], - x->nmvjointcost, x->mvcost, 96, - x->e_mbd.allow_high_precision_mv); - *rate2 += vp9_mv_bit_cost(&frame_mv[refs[1]], - &ref_mv[1], - x->nmvjointcost, x->mvcost, 96, - x->e_mbd.allow_high_precision_mv); - } else { - struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; - int bestsme = INT_MAX; - int further_steps, step_param = cpi->sf.first_step; - int sadpb = x->sadperbit16; - int_mv mvp_full, tmp_mv; - int sr = 0; - - int tmp_col_min = x->mv_col_min; - int tmp_col_max = x->mv_col_max; - int tmp_row_min = x->mv_row_min; - int tmp_row_max = x->mv_row_max; - - if (scaled_ref_frame[0]) { - int i; - - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) - backup_yv12[i] = xd->plane[i].pre[0]; - - setup_pre_planes(xd, scaled_ref_frame[0], NULL, mi_row, mi_col, - NULL, NULL); - } - - vp9_clamp_mv_min_max(x, &ref_mv[0]); - - sr = vp9_init_search_range(cpi->common.width, cpi->common.height); + *rate2 += rate_mv; - // mvp_full.as_int = ref_mv[0].as_int; - mvp_full.as_int = - mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int; - - mvp_full.as_mv.col >>= 3; - mvp_full.as_mv.row >>= 3; - - // adjust search range according to sr from mv prediction - step_param = MAX(step_param, sr); - - // Further step/diamond searches as necessary - further_steps = (cpi->sf.max_step_search_steps - 1) - step_param; - - bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, - sadpb, further_steps, 1, - &cpi->fn_ptr[block_size], - &ref_mv[0], &tmp_mv); - - x->mv_col_min = tmp_col_min; - x->mv_col_max = tmp_col_max; - x->mv_row_min = tmp_row_min; - x->mv_row_max = tmp_row_max; - - if (bestsme < INT_MAX) { - int dis; /* TODO: use dis in distortion calculation later. */ - unsigned int sse; - cpi->find_fractional_mv_step(x, &tmp_mv, - &ref_mv[0], - x->errorperbit, - &cpi->fn_ptr[block_size], - x->nmvjointcost, x->mvcost, - &dis, &sse); - } - frame_mv[refs[0]].as_int = tmp_mv.as_int; + } else { + int_mv tmp_mv; + single_motion_search(cpi, x, bsize, mi_row, mi_col, + &tmp_mv, &rate_mv); + *rate2 += rate_mv; + frame_mv[refs[0]].as_int = + xd->mode_info_context->bmi[0].as_mv[0].as_int = tmp_mv.as_int; single_newmv[refs[0]].as_int = tmp_mv.as_int; - - // Add the new motion vector cost to our rolling cost variable - *rate2 += vp9_mv_bit_cost(&tmp_mv, &ref_mv[0], - x->nmvjointcost, x->mvcost, - 96, xd->allow_high_precision_mv); - - // restore the predictor, if required - if (scaled_ref_frame[0]) { - int i; - - for (i = 0; i < MAX_MB_PLANE; i++) - xd->plane[i].pre[0] = backup_yv12[i]; - } } break; case NEARMV: @@ -2188,7 +2219,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, mbmi->mv[i].as_int = cur_mv[i].as_int; } - /* We don't include the cost of the second reference here, because there * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other * words if you present them in that order, the second one is always known @@ -2200,10 +2230,10 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, interpolating_intpel_seen = 0; // Are all MVs integer pel for Y and UV intpel_mv = (mbmi->mv[0].as_mv.row & 15) == 0 && - (mbmi->mv[0].as_mv.col & 15) == 0; + (mbmi->mv[0].as_mv.col & 15) == 0; if (is_comp_pred) intpel_mv &= (mbmi->mv[1].as_mv.row & 15) == 0 && - (mbmi->mv[1].as_mv.col & 15) == 0; + (mbmi->mv[1].as_mv.col & 15) == 0; // Search for best switchable filter by checking the variance of // pred error irrespective of whether the filter will be used if (cpi->speed > 4) { @@ -2215,7 +2245,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int rs = 0; const INTERPOLATIONFILTERTYPE filter = vp9_switchable_interp[i]; const int is_intpel_interp = intpel_mv && - vp9_is_interpolating_filter[filter]; + vp9_is_interpolating_filter[filter]; mbmi->interp_filter = filter; vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); @@ -2263,7 +2293,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, // Set the appripriate filter mbmi->interp_filter = cm->mcomp_filter_type != SWITCHABLE ? - cm->mcomp_filter_type : *best_filter; + cm->mcomp_filter_type : *best_filter; vp9_setup_interp_filters(xd, mbmi->interp_filter, cm); @@ -2876,17 +2906,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, compmode_cost = vp9_cost_bit(comp_mode_p, is_comp_pred); } else { - YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL}; - int fb = get_ref_frame_idx(cpi, mbmi->ref_frame[0]); - if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb]) - scaled_ref_frame[0] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]]; - - if (comp_pred) { - fb = get_ref_frame_idx(cpi, mbmi->ref_frame[1]); - if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb]) - scaled_ref_frame[1] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]]; - } - compmode_cost = vp9_cost_bit(comp_mode_p, mbmi->ref_frame[1] > INTRA_FRAME); this_rd = handle_inter_mode(cpi, x, bsize, @@ -2896,7 +2915,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, &rate_uv, &distortion_uv, &mode_excluded, &disable_skip, &tmp_best_filter, frame_mv[this_mode], - scaled_ref_frame, mi_row, mi_col, + mi_row, mi_col, single_newmv); if (this_rd == INT64_MAX) continue; diff --git a/vp9/encoder/vp9_variance.h b/vp9/encoder/vp9_variance.h index aaa43ef82..38808d7be 100644 --- a/vp9/encoder/vp9_variance.h +++ b/vp9/encoder/vp9_variance.h @@ -86,18 +86,18 @@ typedef struct vp9_variance_vtable { vp9_sad_multi_d_fn_t sdx4df; } vp9_variance_fn_ptr_t; -static void comp_avg_pred(uint8_t *comp_pred, const uint8_t *pred, int weight, +static void comp_avg_pred(uint8_t *comp_pred, const uint8_t *pred, int width, int height, uint8_t *ref, int ref_stride) { int i, j; for (i = 0; i < height; i++) { - for (j = 0; j < weight; j++) { + for (j = 0; j < width; j++) { int tmp; tmp = pred[j] + ref[j]; comp_pred[j] = (tmp + 1) >> 1; } - comp_pred += weight; - pred += weight; + comp_pred += width; + pred += width; ref += ref_stride; } } diff --git a/vp9/encoder/vp9_variance_c.c b/vp9/encoder/vp9_variance_c.c index 3b9d50f34..23e776791 100644 --- a/vp9/encoder/vp9_variance_c.c +++ b/vp9/encoder/vp9_variance_c.c @@ -14,6 +14,7 @@ #include "vp9/common/vp9_subpelvar.h" #include "vpx/vpx_integer.h" #include "vpx_ports/mem.h" +#include "./vp9_rtcd.h" unsigned int vp9_get_mb_ss_c(const int16_t *src_ptr) { unsigned int i, sum = 0; @@ -56,7 +57,7 @@ unsigned int vp9_sub_pixel_variance64x32_c(const uint8_t *src_ptr, 1, 33, 64, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 32, 64, vfilter); - return vp9_variance64x32_c(temp2, 64, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance64x32(temp2, 64, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance64x32_c(const uint8_t *src_ptr, @@ -79,7 +80,7 @@ unsigned int vp9_sub_pixel_avg_variance64x32_c(const uint8_t *src_ptr, 1, 33, 64, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 32, 64, vfilter); comp_avg_pred(temp3, second_pred, 64, 32, temp2, 64); - return vp9_variance64x32_c(temp3, 64, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance64x32(temp3, 64, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_variance32x64_c(const uint8_t *src_ptr, @@ -113,7 +114,7 @@ unsigned int vp9_sub_pixel_variance32x64_c(const uint8_t *src_ptr, 1, 65, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 64, 32, vfilter); - return vp9_variance32x64_c(temp2, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x64(temp2, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance32x64_c(const uint8_t *src_ptr, @@ -136,7 +137,7 @@ unsigned int vp9_sub_pixel_avg_variance32x64_c(const uint8_t *src_ptr, 1, 65, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 64, 32, vfilter); comp_avg_pred(temp3, second_pred, 32, 64, temp2, 32); - return vp9_variance32x64_c(temp3, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x64(temp3, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_variance32x16_c(const uint8_t *src_ptr, @@ -170,7 +171,7 @@ unsigned int vp9_sub_pixel_variance32x16_c(const uint8_t *src_ptr, 1, 17, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 16, 32, vfilter); - return vp9_variance32x16_c(temp2, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x16(temp2, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance32x16_c(const uint8_t *src_ptr, @@ -193,7 +194,7 @@ unsigned int vp9_sub_pixel_avg_variance32x16_c(const uint8_t *src_ptr, 1, 17, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 16, 32, vfilter); comp_avg_pred(temp3, second_pred, 32, 16, temp2, 32); - return vp9_variance32x16_c(temp3, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x16(temp3, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_variance16x32_c(const uint8_t *src_ptr, @@ -227,7 +228,7 @@ unsigned int vp9_sub_pixel_variance16x32_c(const uint8_t *src_ptr, 1, 33, 16, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 32, 16, vfilter); - return vp9_variance16x32_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x32(temp2, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance16x32_c(const uint8_t *src_ptr, @@ -250,7 +251,7 @@ unsigned int vp9_sub_pixel_avg_variance16x32_c(const uint8_t *src_ptr, 1, 33, 16, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 32, 16, vfilter); comp_avg_pred(temp3, second_pred, 16, 32, temp2, 16); - return vp9_variance16x32_c(temp3, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x32(temp3, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_variance64x64_c(const uint8_t *src_ptr, @@ -451,7 +452,7 @@ unsigned int vp9_sub_pixel_variance4x4_c(const uint8_t *src_ptr, // Now filter Verticaly var_filter_block2d_bil_second_pass(fdata3, temp2, 4, 4, 4, 4, vfilter); - return vp9_variance4x4_c(temp2, 4, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance4x4(temp2, 4, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance4x4_c(const uint8_t *src_ptr, @@ -477,7 +478,7 @@ unsigned int vp9_sub_pixel_avg_variance4x4_c(const uint8_t *src_ptr, // Now filter Verticaly var_filter_block2d_bil_second_pass(fdata3, temp2, 4, 4, 4, 4, vfilter); comp_avg_pred(temp3, second_pred, 4, 4, temp2, 4); - return vp9_variance4x4_c(temp3, 4, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance4x4(temp3, 4, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance8x8_c(const uint8_t *src_ptr, @@ -498,7 +499,7 @@ unsigned int vp9_sub_pixel_variance8x8_c(const uint8_t *src_ptr, 1, 9, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 8, 8, vfilter); - return vp9_variance8x8_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x8(temp2, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance8x8_c(const uint8_t *src_ptr, @@ -521,7 +522,7 @@ unsigned int vp9_sub_pixel_avg_variance8x8_c(const uint8_t *src_ptr, 1, 9, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 8, 8, vfilter); comp_avg_pred(temp3, second_pred, 8, 8, temp2, 8); - return vp9_variance8x8_c(temp3, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x8(temp3, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance16x16_c(const uint8_t *src_ptr, @@ -542,7 +543,7 @@ unsigned int vp9_sub_pixel_variance16x16_c(const uint8_t *src_ptr, 1, 17, 16, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 16, 16, vfilter); - return vp9_variance16x16_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x16(temp2, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance16x16_c(const uint8_t *src_ptr, @@ -566,7 +567,7 @@ unsigned int vp9_sub_pixel_avg_variance16x16_c(const uint8_t *src_ptr, var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 16, 16, vfilter); comp_avg_pred(temp3, second_pred, 16, 16, temp2, 16); - return vp9_variance16x16_c(temp3, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x16(temp3, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance64x64_c(const uint8_t *src_ptr, @@ -587,7 +588,7 @@ unsigned int vp9_sub_pixel_variance64x64_c(const uint8_t *src_ptr, 1, 65, 64, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 64, 64, vfilter); - return vp9_variance64x64_c(temp2, 64, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance64x64(temp2, 64, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance64x64_c(const uint8_t *src_ptr, @@ -610,7 +611,7 @@ unsigned int vp9_sub_pixel_avg_variance64x64_c(const uint8_t *src_ptr, 1, 65, 64, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 64, 64, vfilter); comp_avg_pred(temp3, second_pred, 64, 64, temp2, 64); - return vp9_variance64x64_c(temp3, 64, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance64x64(temp3, 64, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance32x32_c(const uint8_t *src_ptr, @@ -631,7 +632,7 @@ unsigned int vp9_sub_pixel_variance32x32_c(const uint8_t *src_ptr, 1, 33, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 32, 32, vfilter); - return vp9_variance32x32_c(temp2, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x32(temp2, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance32x32_c(const uint8_t *src_ptr, @@ -654,7 +655,7 @@ unsigned int vp9_sub_pixel_avg_variance32x32_c(const uint8_t *src_ptr, 1, 33, 32, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 32, 32, vfilter); comp_avg_pred(temp3, second_pred, 32, 32, temp2, 32); - return vp9_variance32x32_c(temp3, 32, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance32x32(temp3, 32, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_variance_halfpixvar16x16_h_c(const uint8_t *src_ptr, @@ -795,7 +796,7 @@ unsigned int vp9_sub_pixel_variance16x8_c(const uint8_t *src_ptr, 1, 9, 16, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 8, 16, vfilter); - return vp9_variance16x8_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x8(temp2, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance16x8_c(const uint8_t *src_ptr, @@ -818,7 +819,7 @@ unsigned int vp9_sub_pixel_avg_variance16x8_c(const uint8_t *src_ptr, 1, 9, 16, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 8, 16, vfilter); comp_avg_pred(temp3, second_pred, 16, 8, temp2, 16); - return vp9_variance16x8_c(temp3, 16, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance16x8(temp3, 16, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance8x16_c(const uint8_t *src_ptr, @@ -839,7 +840,7 @@ unsigned int vp9_sub_pixel_variance8x16_c(const uint8_t *src_ptr, 1, 17, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 16, 8, vfilter); - return vp9_variance8x16_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x16(temp2, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance8x16_c(const uint8_t *src_ptr, @@ -862,7 +863,7 @@ unsigned int vp9_sub_pixel_avg_variance8x16_c(const uint8_t *src_ptr, 1, 17, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 16, 8, vfilter); comp_avg_pred(temp3, second_pred, 8, 16, temp2, 8); - return vp9_variance8x16_c(temp3, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x16(temp3, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance8x4_c(const uint8_t *src_ptr, @@ -883,7 +884,7 @@ unsigned int vp9_sub_pixel_variance8x4_c(const uint8_t *src_ptr, 1, 5, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 4, 8, vfilter); - return vp9_variance8x4_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x4(temp2, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance8x4_c(const uint8_t *src_ptr, @@ -906,7 +907,7 @@ unsigned int vp9_sub_pixel_avg_variance8x4_c(const uint8_t *src_ptr, 1, 5, 8, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 4, 8, vfilter); comp_avg_pred(temp3, second_pred, 8, 4, temp2, 8); - return vp9_variance8x4_c(temp3, 8, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance8x4(temp3, 8, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_variance4x8_c(const uint8_t *src_ptr, @@ -929,7 +930,7 @@ unsigned int vp9_sub_pixel_variance4x8_c(const uint8_t *src_ptr, 1, 9, 4, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 4, 4, 8, 4, vfilter); - return vp9_variance4x8_c(temp2, 4, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance4x8(temp2, 4, dst_ptr, dst_pixels_per_line, sse); } unsigned int vp9_sub_pixel_avg_variance4x8_c(const uint8_t *src_ptr, @@ -952,5 +953,5 @@ unsigned int vp9_sub_pixel_avg_variance4x8_c(const uint8_t *src_ptr, 1, 9, 4, hfilter); var_filter_block2d_bil_second_pass(fdata3, temp2, 4, 4, 8, 4, vfilter); comp_avg_pred(temp3, second_pred, 4, 8, temp2, 4); - return vp9_variance4x8_c(temp3, 4, dst_ptr, dst_pixels_per_line, sse); + return vp9_variance4x8(temp3, 4, dst_ptr, dst_pixels_per_line, sse); } diff --git a/vp9/encoder/x86/vp9_sad_sse2.asm b/vp9/encoder/x86/vp9_sad_sse2.asm index ea92377ee..8fb7d4118 100644 --- a/vp9/encoder/x86/vp9_sad_sse2.asm +++ b/vp9/encoder/x86/vp9_sad_sse2.asm @@ -166,29 +166,46 @@ cglobal sad8x%1, 4, 7, 5, src, src_stride, ref, ref_stride, \ INIT_XMM sse2 SAD8XN 16 ; sad8x16_sse2 SAD8XN 8 ; sad8x8_sse2 +SAD8XN 4 ; sad8x4_sse2 -; unsigned int vp9_sad4x4_sse(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -INIT_MMX sse -cglobal sad4x4, 4, 4, 8, src, src_stride, ref, ref_stride +; unsigned int vp9_sad4x{4, 8}_sse(uint8_t *src, int src_stride, +; uint8_t *ref, int ref_stride); +%macro SAD4XN 1 +cglobal sad4x%1, 4, 7, 7, src, src_stride, ref, ref_stride, \ + src_stride3, ref_stride3, n_rows movsxdifnidn src_strideq, src_strided movsxdifnidn ref_strideq, ref_strided - movd m0, [refq] - movd m1, [refq+ref_strideq] + lea src_stride3q, [src_strideq*3] + lea ref_stride3q, [ref_strideq*3] + mov n_rowsd, %1/4 + pxor m0, m0 + +.loop: + movd m1, [refq] + movd m2, [refq+ref_strideq] + movd m3, [refq+ref_strideq*2] + movd m4, [refq+ref_stride3q] + punpckldq m1, m2 + punpckldq m3, m4 movd m2, [srcq] - movd m3, [srcq+src_strideq] - lea refq, [refq+ref_strideq*2] - lea srcq, [srcq+src_strideq*2] - movd m4, [refq] - movd m5, [refq+ref_strideq] - movd m6, [srcq] - movd m7, [srcq+src_strideq] - punpckldq m0, m1 - punpckldq m2, m3 - punpckldq m4, m5 - punpckldq m6, m7 - psadbw m0, m2 - psadbw m4, m6 - paddd m0, m4 + movd m5, [srcq+src_strideq] + movd m4, [srcq+src_strideq*2] + movd m6, [srcq+src_stride3q] + punpckldq m2, m5 + punpckldq m4, m6 + psadbw m1, m2 + psadbw m3, m4 + lea refq, [refq+ref_strideq*4] + paddd m0, m1 + lea srcq, [srcq+src_strideq*4] + paddd m0, m3 + dec n_rowsd + jg .loop + movd eax, m0 RET +%endmacro + +INIT_MMX sse +SAD4XN 8 ; sad4x8_sse +SAD4XN 4 ; sad4x4_sse diff --git a/vp9/common/x86/vp9_subpel_variance_impl_sse2.asm b/vp9/encoder/x86/vp9_subpel_variance_impl_sse2.asm index 8a2a471f5..8a2a471f5 100644 --- a/vp9/common/x86/vp9_subpel_variance_impl_sse2.asm +++ b/vp9/encoder/x86/vp9_subpel_variance_impl_sse2.asm diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk index b6d50f8ef..7a7483332 100644 --- a/vp9/vp9_common.mk +++ b/vp9/vp9_common.mk @@ -38,7 +38,6 @@ VP9_COMMON_SRCS-yes += common/vp9_enums.h VP9_COMMON_SRCS-yes += common/vp9_extend.h VP9_COMMON_SRCS-yes += common/vp9_findnearmv.h VP9_COMMON_SRCS-yes += common/vp9_idct.h -VP9_COMMON_SRCS-yes += common/vp9_invtrans.h VP9_COMMON_SRCS-yes += common/vp9_loopfilter.h VP9_COMMON_SRCS-yes += common/vp9_modecont.h VP9_COMMON_SRCS-yes += common/vp9_mv.h @@ -59,7 +58,6 @@ VP9_COMMON_SRCS-yes += common/vp9_textblit.h VP9_COMMON_SRCS-yes += common/vp9_tile_common.h VP9_COMMON_SRCS-yes += common/vp9_tile_common.c VP9_COMMON_SRCS-yes += common/vp9_treecoder.h -VP9_COMMON_SRCS-yes += common/vp9_invtrans.c VP9_COMMON_SRCS-yes += common/vp9_loopfilter.c VP9_COMMON_SRCS-yes += common/vp9_loopfilter_filters.c VP9_COMMON_SRCS-yes += common/vp9_mbpitch.c @@ -87,8 +85,6 @@ VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_iwalsh_sse2.asm VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_loopfilter_sse2.asm VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_recon_sse2.asm VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_recon_wrapper_sse2.c -VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_subpel_variance_impl_sse2.asm -VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_subpixel_variance_sse2.c VP9_COMMON_SRCS-$(HAVE_SSSE3) += common/x86/vp9_subpixel_8t_ssse3.asm ifeq ($(CONFIG_POSTPROC),yes) VP9_COMMON_SRCS-$(HAVE_MMX) += common/x86/vp9_postproc_mmx.asm diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk index 86fd08850..4bed6c0d7 100644 --- a/vp9/vp9cx.mk +++ b/vp9/vp9cx.mk @@ -86,6 +86,7 @@ VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_sad_sse2.asm VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_sad4d_sse2.asm VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_fwalsh_sse2.asm VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_subtract_sse2.asm +VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_subpel_variance_impl_sse2.asm VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_temporal_filter_apply_sse2.asm VP9_CX_SRCS-$(HAVE_SSE3) += encoder/x86/vp9_sad_sse3.asm VP9_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/vp9_sad_ssse3.asm diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h index 201df88fe..7d250ccae 100644 --- a/vpx/vp8dx.h +++ b/vpx/vp8dx.h @@ -63,11 +63,11 @@ enum vp8_dec_control_id { */ VP8D_GET_LAST_REF_USED, - /** decryption key to protect encoded data buffer before decoding, - * pointer to 32 byte array which is copied, so the array passed - * does not need to be preserved + /** decryption function to decrypt encoded buffer data immediately + * before decoding. Takes a vp8_decrypt_init, which contains + * a callback function and opaque context pointer. */ - VP8_SET_DECRYPT_KEY, + VP8D_SET_DECRYPTOR, /** For testing. */ VP9_INVERT_TILE_DECODE_ORDER, @@ -75,6 +75,14 @@ enum vp8_dec_control_id { VP8_DECODER_CTRL_ID_MAX }; +typedef struct vp8_decrypt_init { + /** Decrypt n bytes of data from input -> output, using the decrypt_state + * passed in VP8D_SET_DECRYPTOR. + */ + void (*decrypt_cb)(void *decrypt_state, const unsigned char *input, + unsigned char *output, int count); + void *decrypt_state; +} vp8_decrypt_init; /*!\brief VP8 decoder control function parameter type * @@ -87,7 +95,7 @@ enum vp8_dec_control_id { VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES, int *) VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED, int *) VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *) -VPX_CTRL_USE_TYPE(VP8_SET_DECRYPT_KEY, const unsigned char *) +VPX_CTRL_USE_TYPE(VP8D_SET_DECRYPTOR, vp8_decrypt_init *) VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int) /*! @} - end defgroup vp8_decoder */ diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h index a51cd2e01..b009c3560 100644 --- a/vpx_ports/x86.h +++ b/vpx_ports/x86.h @@ -186,36 +186,23 @@ x86_readtsc(void) { #if defined(__GNUC__) && __GNUC__ static void x87_set_control_word(unsigned short mode) { - __asm__ __volatile__("fldcw %0" : : "m"( *&mode)); + __asm__ __volatile__("fldcw %0" : : "m"(*&mode)); } static unsigned short x87_get_control_word(void) { unsigned short mode; - __asm__ __volatile__("fstcw %0\n\t":"=m"( *&mode):); + __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):); return mode; } #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) static void -x87_set_control_word(unsigned short mode) -{ - asm volatile("fldcw %0" : : "m"(*&mode)); -} -static unsigned short -x87_get_control_word(void) -{ - unsigned short mode; - asm volatile("fstcw %0\n\t":"=m"(*&mode):); - return mode; -} -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -static void x87_set_control_word(unsigned short mode) { - asm volatile("fldcw %0" : : "m"( *&mode)); + asm volatile("fldcw %0" : : "m"(*&mode)); } static unsigned short x87_get_control_word(void) { unsigned short mode; - asm volatile("fstcw %0\n\t":"=m"( *&mode):); + asm volatile("fstcw %0\n\t":"=m"(*&mode):); return mode; } #elif ARCH_X86_64 @@ -67,6 +67,8 @@ static const struct { }; #include "args.h" +static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1, + "Number of times to decode the file"); static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use"); static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, @@ -676,7 +678,7 @@ void generate_filename(const char *pattern, char *out, size_t q_len, } -int main(int argc, const char **argv_) { +int main_loop(int argc, const char **argv_) { vpx_codec_ctx_t decoder; char *fn = NULL; int i; @@ -737,6 +739,8 @@ int main(int argc, const char **argv_) { else die("Error: Unrecognized argument (%s) to --codec\n", arg.val); + } else if (arg_match(&arg, &looparg, argi)) { + // no-op } else if (arg_match(&arg, &outputfile, argi)) outfile_pattern = arg.val; else if (arg_match(&arg, &use_yv12, argi)) { @@ -1152,3 +1156,25 @@ fail: return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS; } + +int main(int argc, const char **argv_) { + unsigned int loops = 1, i; + char **argv, **argi, **argj; + struct arg arg; + int error = 0; + + argv = argv_dup(argc - 1, argv_ + 1); + for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { + memset(&arg, 0, sizeof(arg)); + arg.argv_step = 1; + + if (arg_match(&arg, &looparg, argi)) { + loops = arg_parse_uint(&arg); + break; + } + } + free(argv); + for (i = 0; !error && i < loops; i++) + error = main_loop(argc, argv_); + return error; +} |