diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/byte_alignment_test.cc | 189 | ||||
-rw-r--r-- | test/decode_test_driver.h | 8 | ||||
-rw-r--r-- | test/encode_test_driver.cc | 31 | ||||
-rw-r--r-- | test/encode_test_driver.h | 2 | ||||
-rw-r--r-- | test/fdct4x4_test.cc | 7 | ||||
-rw-r--r-- | test/fdct8x8_test.cc | 5 | ||||
-rw-r--r-- | test/lpf_8_test.cc | 2 | ||||
-rw-r--r-- | test/test.mk | 1 | ||||
-rw-r--r-- | test/vp9_end_to_end_test.cc | 51 |
9 files changed, 267 insertions, 29 deletions
diff --git a/test/byte_alignment_test.cc b/test/byte_alignment_test.cc new file mode 100644 index 000000000..aa4b78b9a --- /dev/null +++ b/test/byte_alignment_test.cc @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <string> + +#include "./vpx_config.h" +#include "test/codec_factory.h" +#include "test/decode_test_driver.h" +#include "test/md5_helper.h" +#include "test/util.h" +#if CONFIG_WEBM_IO +#include "test/webm_video_source.h" +#endif + +namespace { + +const int kLegacyByteAlignment = 0; +const int kLegacyYPlaneByteAlignment = 32; +const int kNumPlanesToCheck = 3; +const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm"; +const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5"; + +#if CONFIG_WEBM_IO + +struct ByteAlignmentTestParam { + int byte_alignment; + vpx_codec_err_t expected_value; + bool decode_remaining; +}; + +const ByteAlignmentTestParam kBaTestParams[] = { + {kLegacyByteAlignment, VPX_CODEC_OK, true}, + {32, VPX_CODEC_OK, true}, + {64, VPX_CODEC_OK, true}, + {128, VPX_CODEC_OK, true}, + {256, VPX_CODEC_OK, true}, + {512, VPX_CODEC_OK, true}, + {1024, VPX_CODEC_OK, true}, + {1, VPX_CODEC_INVALID_PARAM, false}, + {-2, VPX_CODEC_INVALID_PARAM, false}, + {4, VPX_CODEC_INVALID_PARAM, false}, + {16, VPX_CODEC_INVALID_PARAM, false}, + {255, VPX_CODEC_INVALID_PARAM, false}, + {2048, VPX_CODEC_INVALID_PARAM, false}, +}; + +// Class for testing byte alignment of reference buffers. +class ByteAlignmentTest + : public ::testing::TestWithParam<ByteAlignmentTestParam> { + protected: + ByteAlignmentTest() + : video_(NULL), + decoder_(NULL), + md5_file_(NULL) {} + + virtual void SetUp() { + video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); + ASSERT_TRUE(video_ != NULL); + video_->Init(); + video_->Begin(); + + const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); + decoder_ = new libvpx_test::VP9Decoder(cfg, 0); + ASSERT_TRUE(decoder_ != NULL); + + OpenMd5File(kVP9Md5File); + } + + virtual void TearDown() { + if (md5_file_ != NULL) + fclose(md5_file_); + + delete decoder_; + delete video_; + } + + void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) { + decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value); + } + + vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) { + const vpx_codec_err_t res = + decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); + CheckDecodedFrames(byte_alignment_to_check); + if (res == VPX_CODEC_OK) + video_->Next(); + return res; + } + + vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) { + for (; video_->cxdata() != NULL; video_->Next()) { + const vpx_codec_err_t res = + decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); + if (res != VPX_CODEC_OK) + return res; + CheckDecodedFrames(byte_alignment_to_check); + } + return VPX_CODEC_OK; + } + + private: + // Check if |data| is aligned to |byte_alignment_to_check|. + // |byte_alignment_to_check| must be a power of 2. + void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) { + ASSERT_EQ(0u, reinterpret_cast<size_t>(data) % byte_alignment_to_check); + } + + // Iterate through the planes of the decoded frames and check for + // alignment based off |byte_alignment_to_check|. + void CheckDecodedFrames(int byte_alignment_to_check) { + libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); + const vpx_image_t *img; + + // Get decompressed data + while ((img = dec_iter.Next()) != NULL) { + if (byte_alignment_to_check == kLegacyByteAlignment) { + CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment); + } else { + for (int i = 0; i < kNumPlanesToCheck; ++i) { + CheckByteAlignment(img->planes[i], byte_alignment_to_check); + } + } + CheckMd5(*img); + } + } + + // TODO(fgalligan): Move the MD5 testing code into another class. + void OpenMd5File(const std::string &md5_file_name_) { + md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); + ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: " + << md5_file_name_; + } + + void CheckMd5(const vpx_image_t &img) { + ASSERT_TRUE(md5_file_ != NULL); + char expected_md5[33]; + char junk[128]; + + // Read correct md5 checksums. + const int res = fscanf(md5_file_, "%s %s", expected_md5, junk); + ASSERT_NE(EOF, res) << "Read md5 data failed"; + expected_md5[32] = '\0'; + + ::libvpx_test::MD5 md5_res; + md5_res.Add(&img); + const char *const actual_md5 = md5_res.Get(); + + // Check md5 match. + ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match"; + } + + libvpx_test::WebMVideoSource *video_; + libvpx_test::VP9Decoder *decoder_; + FILE *md5_file_; +}; + +TEST_F(ByteAlignmentTest, SwitchByteAlignment) { + const int num_elements = 14; + const int byte_alignments[] = { 0, 32, 64, 128, 256, 512, 1024, + 0, 1024, 32, 512, 64, 256, 128 }; + + for (int i = 0; i < num_elements; ++i) { + SetByteAlignment(byte_alignments[i], VPX_CODEC_OK); + ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i])); + } + SetByteAlignment(byte_alignments[0], VPX_CODEC_OK); + ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0])); +} + +TEST_P(ByteAlignmentTest, TestAlignment) { + const ByteAlignmentTestParam t = GetParam(); + SetByteAlignment(t.byte_alignment, t.expected_value); + if (t.decode_remaining) + ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment)); +} + +INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest, + ::testing::ValuesIn(kBaTestParams)); + +#endif // CONFIG_WEBM_IO + +} // namespace diff --git a/test/decode_test_driver.h b/test/decode_test_driver.h index 232428eb0..f566c53c7 100644 --- a/test/decode_test_driver.h +++ b/test/decode_test_driver.h @@ -72,15 +72,19 @@ class Decoder { } void Control(int ctrl_id, int arg) { + Control(ctrl_id, arg, VPX_CODEC_OK); + } + + void Control(int ctrl_id, const void *arg) { InitOnce(); const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); } - void Control(int ctrl_id, const void *arg) { + void Control(int ctrl_id, int arg, vpx_codec_err_t expected_value) { InitOnce(); const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); + ASSERT_EQ(expected_value, res) << DecodeError(); } const char* DecodeError() { diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc index b49e8cba2..7a133643d 100644 --- a/test/encode_test_driver.cc +++ b/test/encode_test_driver.cc @@ -17,6 +17,21 @@ #include "third_party/googletest/src/include/gtest/gtest.h" namespace libvpx_test { +void Encoder::InitEncoder(VideoSource *video) { + vpx_codec_err_t res; + const vpx_image_t *img = video->img(); + + if (video->img() && !encoder_.priv) { + cfg_.g_w = img->d_w; + cfg_.g_h = img->d_h; + cfg_.g_timebase = video->timebase(); + cfg_.rc_twopass_stats_in = stats_->buf(); + res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, + init_flags_); + ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); + } +} + void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) { if (video->img()) EncodeFrameInternal(*video, frame_flags); @@ -39,17 +54,6 @@ void Encoder::EncodeFrameInternal(const VideoSource &video, vpx_codec_err_t res; const vpx_image_t *img = video.img(); - // Handle first frame initialization - if (!encoder_.priv) { - cfg_.g_w = img->d_w; - cfg_.g_h = img->d_h; - cfg_.g_timebase = video.timebase(); - cfg_.rc_twopass_stats_in = stats_->buf(); - res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, - init_flags_); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - // Handle frame resizing if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { cfg_.g_w = img->d_w; @@ -160,6 +164,9 @@ void EncoderTest::RunLoop(VideoSource *video) { &stats_); ASSERT_TRUE(encoder != NULL); + video->Begin(); + encoder->InitEncoder(video); + unsigned long dec_init_flags = 0; // NOLINT // Use fragment decoder if encoder outputs partitions. // NOTE: fragment decoder and partition encoder are only supported by VP8. @@ -167,7 +174,7 @@ void EncoderTest::RunLoop(VideoSource *video) { dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS; Decoder* const decoder = codec_->CreateDecoder(dec_cfg, dec_init_flags, 0); bool again; - for (again = true, video->Begin(); again; video->Next()) { + for (again = true; again; video->Next()) { again = (video->img() != NULL); PreEncodeFrameHook(video); diff --git a/test/encode_test_driver.h b/test/encode_test_driver.h index 770ac7e92..765c7d164 100644 --- a/test/encode_test_driver.h +++ b/test/encode_test_driver.h @@ -104,6 +104,8 @@ class Encoder { return CxDataIterator(&encoder_); } + void InitEncoder(VideoSource *video); + const vpx_image_t *GetPreviewFrame() { return vpx_codec_get_preview_frame(&encoder_); } diff --git a/test/fdct4x4_test.cc b/test/fdct4x4_test.cc index d6a3473ae..5357a8d2d 100644 --- a/test/fdct4x4_test.cc +++ b/test/fdct4x4_test.cc @@ -474,14 +474,17 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values( make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_neon, 0, VPX_BITS_8))); +#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE + +#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE INSTANTIATE_TEST_CASE_P( - DISABLED_NEON, Trans4x4HT, + NEON, Trans4x4HT, ::testing::Values( make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8))); -#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE +#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \ !CONFIG_EMULATE_HARDWARE diff --git a/test/fdct8x8_test.cc b/test/fdct8x8_test.cc index 01abca5fa..6f2c89bc1 100644 --- a/test/fdct8x8_test.cc +++ b/test/fdct8x8_test.cc @@ -699,6 +699,9 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values( make_tuple(&vp9_fdct8x8_neon, &vp9_idct8x8_64_add_neon, 0, VPX_BITS_8))); +#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE + +#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE INSTANTIATE_TEST_CASE_P( NEON, FwdTrans8x8HT, ::testing::Values( @@ -706,7 +709,7 @@ INSTANTIATE_TEST_CASE_P( make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8))); -#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE +#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE // TODO(jingning): re-enable after these handle the expanded range [0, 65535] diff --git a/test/lpf_8_test.cc b/test/lpf_8_test.cc index e1be80baa..cdc0a9895 100644 --- a/test/lpf_8_test.cc +++ b/test/lpf_8_test.cc @@ -613,10 +613,8 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( NEON, Loop8Test9Param, ::testing::Values( -#if HAVE_NEON_ASM make_tuple(&vp9_lpf_horizontal_4_dual_neon, &vp9_lpf_horizontal_4_dual_c, 8), -#endif // HAVE_NEON_ASM make_tuple(&vp9_lpf_horizontal_8_dual_neon, &vp9_lpf_horizontal_8_dual_c, 8), make_tuple(&vp9_lpf_vertical_4_dual_neon, diff --git a/test/test.mk b/test/test.mk index 6e935defd..bd65759c5 100644 --- a/test/test.mk +++ b/test/test.mk @@ -31,6 +31,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc +LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += invalid_file_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc diff --git a/test/vp9_end_to_end_test.cc b/test/vp9_end_to_end_test.cc index b98deceba..b7dd932e0 100644 --- a/test/vp9_end_to_end_test.cc +++ b/test/vp9_end_to_end_test.cc @@ -22,8 +22,17 @@ const unsigned int kHeight = 90; const unsigned int kFramerate = 50; const unsigned int kFrames = 10; const int kBitrate = 500; -const int kCpuUsed = 2; -const double psnr_threshold = 35.0; +// List of psnr thresholds for speed settings 0-7 and 5 encoding modes +const double kPsnrThreshold[][5] = { + { 36.0, 37.0, 37.0, 37.0, 37.0 }, + { 35.0, 36.0, 36.0, 36.0, 36.0 }, + { 34.0, 35.0, 35.0, 35.0, 35.0 }, + { 33.0, 34.0, 34.0, 34.0, 34.0 }, + { 32.0, 33.0, 33.0, 33.0, 33.0 }, + { 31.0, 32.0, 32.0, 32.0, 32.0 }, + { 30.0, 31.0, 31.0, 31.0, 31.0 }, + { 29.0, 30.0, 30.0, 30.0, 30.0 }, +}; typedef struct { const char *filename; @@ -33,7 +42,7 @@ typedef struct { unsigned int profile; } TestVideoParam; -const TestVideoParam TestVectors[] = { +const TestVideoParam kTestVectors[] = { {"park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420, VPX_BITS_8, 0}, {"park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1}, {"park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1}, @@ -50,6 +59,16 @@ const TestVideoParam TestVectors[] = { #endif // CONFIG_VP9_HIGHBITDEPTH }; +// Encoding modes tested +const libvpx_test::TestMode kEncodingModeVectors[] = { + ::libvpx_test::kTwoPassGood, + ::libvpx_test::kOnePassGood, + ::libvpx_test::kRealTime, +}; + +// Speed settings tested +const int kCpuUsedVectors[] = {1, 2, 3, 5, 6}; + int is_extension_y4m(const char *filename) { const char *dot = strrchr(filename, '.'); if (!dot || dot == filename) @@ -60,11 +79,13 @@ int is_extension_y4m(const char *filename) { class EndToEndTestLarge : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, \ - TestVideoParam> { + public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, \ + TestVideoParam, int> { protected: EndToEndTestLarge() : EncoderTest(GET_PARAM(0)), + test_video_param_(GET_PARAM(2)), + cpu_used_(GET_PARAM(3)), psnr_(0.0), nframes_(0), encoding_mode_(GET_PARAM(1)) { @@ -81,9 +102,11 @@ class EndToEndTestLarge } else { cfg_.g_lag_in_frames = 0; cfg_.rc_end_usage = VPX_CBR; + cfg_.rc_buf_sz = 1000; + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 600; } dec_cfg_.threads = 4; - test_video_param_ = GET_PARAM(2); } virtual void BeginPassHook(unsigned int) { @@ -101,7 +124,7 @@ class EndToEndTestLarge if (video->frame() == 1) { encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); encoder->Control(VP9E_SET_TILE_COLUMNS, 4); - encoder->Control(VP8E_SET_CPUUSED, kCpuUsed); + encoder->Control(VP8E_SET_CPUUSED, cpu_used_); if (encoding_mode_ != ::libvpx_test::kRealTime) { encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); @@ -117,7 +140,12 @@ class EndToEndTestLarge return 0.0; } + double GetPsnrThreshold() { + return kPsnrThreshold[cpu_used_][encoding_mode_]; + } + TestVideoParam test_video_param_; + int cpu_used_; private: double psnr_; @@ -132,6 +160,8 @@ TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) { cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; cfg_.g_bit_depth = test_video_param_.bit_depth; init_flags_ = VPX_CODEC_USE_PSNR; + if (cfg_.g_bit_depth > 8) + init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; libvpx_test::VideoSource *video; if (is_extension_y4m(test_video_param_.filename)) { @@ -146,13 +176,14 @@ TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) { ASSERT_NO_FATAL_FAILURE(RunLoop(video)); const double psnr = GetAveragePsnr(); - EXPECT_GT(psnr, psnr_threshold); + EXPECT_GT(psnr, GetPsnrThreshold()); delete(video); } VP9_INSTANTIATE_TEST_CASE( EndToEndTestLarge, - ::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood), - ::testing::ValuesIn(TestVectors)); + ::testing::ValuesIn(kEncodingModeVectors), + ::testing::ValuesIn(kTestVectors), + ::testing::ValuesIn(kCpuUsedVectors)); } // namespace |