John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | #include <climits> |
| 11 | #include <vector> |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 12 | #include "third_party/googletest/src/include/gtest/gtest.h" |
| 13 | #include "test/codec_factory.h" |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 14 | #include "test/encode_test_driver.h" |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 15 | #include "test/i420_video_source.h" |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 16 | #include "test/util.h" |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 17 | |
| 18 | namespace { |
| 19 | |
| 20 | class KeyframeTest : public ::libvpx_test::EncoderTest, |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 21 | public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 22 | protected: |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 23 | KeyframeTest() : EncoderTest(GET_PARAM(0)) {} |
Alex Converse | 6207a38 | 2014-03-12 14:51:42 -0700 | [diff] [blame] | 24 | virtual ~KeyframeTest() {} |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 25 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 26 | virtual void SetUp() { |
| 27 | InitializeConfig(); |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 28 | SetMode(GET_PARAM(1)); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 29 | kf_count_ = 0; |
| 30 | kf_count_max_ = INT_MAX; |
| 31 | kf_do_force_kf_ = false; |
John Koleszar | 606ac45 | 2012-07-10 15:43:44 -0700 | [diff] [blame] | 32 | set_cpu_used_ = 0; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 33 | } |
| 34 | |
John Koleszar | 606ac45 | 2012-07-10 15:43:44 -0700 | [diff] [blame] | 35 | virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, |
| 36 | ::libvpx_test::Encoder *encoder) { |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 37 | if (kf_do_force_kf_) |
Adrian Grange | 4206c6d | 2012-10-02 11:03:09 -0700 | [diff] [blame] | 38 | frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF; |
John Koleszar | 606ac45 | 2012-07-10 15:43:44 -0700 | [diff] [blame] | 39 | if (set_cpu_used_ && video->frame() == 1) |
| 40 | encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { |
| 44 | if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { |
| 45 | kf_pts_list_.push_back(pkt->data.frame.pts); |
| 46 | kf_count_++; |
| 47 | abort_ |= kf_count_ > kf_count_max_; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | bool kf_do_force_kf_; |
| 52 | int kf_count_; |
| 53 | int kf_count_max_; |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 54 | std::vector<vpx_codec_pts_t> kf_pts_list_; |
John Koleszar | 606ac45 | 2012-07-10 15:43:44 -0700 | [diff] [blame] | 55 | int set_cpu_used_; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 56 | }; |
| 57 | |
| 58 | TEST_P(KeyframeTest, TestRandomVideoSource) { |
| 59 | // Validate that encoding the RandomVideoSource produces multiple keyframes. |
| 60 | // This validates the results of the TestDisableKeyframes test. |
| 61 | kf_count_max_ = 2; // early exit successful tests. |
| 62 | |
| 63 | ::libvpx_test::RandomVideoSource video; |
| 64 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 65 | |
Jim Bankoski | 6f35b19 | 2012-10-01 14:17:43 -0700 | [diff] [blame] | 66 | // In realtime mode - auto placed keyframes are exceedingly rare, don't |
| 67 | // bother with this check if(GetParam() > 0) |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 68 | if (GET_PARAM(1) > 0) |
Jim Bankoski | 6f35b19 | 2012-10-01 14:17:43 -0700 | [diff] [blame] | 69 | EXPECT_GT(kf_count_, 1); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | TEST_P(KeyframeTest, TestDisableKeyframes) { |
| 73 | cfg_.kf_mode = VPX_KF_DISABLED; |
| 74 | kf_count_max_ = 1; // early exit failed tests. |
| 75 | |
| 76 | ::libvpx_test::RandomVideoSource video; |
| 77 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 78 | |
| 79 | EXPECT_EQ(1, kf_count_); |
| 80 | } |
| 81 | |
| 82 | TEST_P(KeyframeTest, TestForceKeyframe) { |
| 83 | cfg_.kf_mode = VPX_KF_DISABLED; |
| 84 | kf_do_force_kf_ = true; |
| 85 | |
| 86 | ::libvpx_test::DummyVideoSource video; |
| 87 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 88 | |
| 89 | // verify that every third frame is a keyframe. |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 90 | for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); |
| 91 | iter != kf_pts_list_.end(); ++iter) { |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 92 | ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter; |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | TEST_P(KeyframeTest, TestKeyframeMaxDistance) { |
| 97 | cfg_.kf_max_dist = 25; |
| 98 | |
| 99 | ::libvpx_test::DummyVideoSource video; |
| 100 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 101 | |
| 102 | // verify that keyframe interval matches kf_max_dist |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 103 | for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); |
| 104 | iter != kf_pts_list_.end(); ++iter) { |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 105 | ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter; |
| 106 | } |
| 107 | } |
| 108 | |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 109 | TEST_P(KeyframeTest, TestAutoKeyframe) { |
| 110 | cfg_.kf_mode = VPX_KF_AUTO; |
| 111 | kf_do_force_kf_ = false; |
| 112 | |
John Koleszar | 606ac45 | 2012-07-10 15:43:44 -0700 | [diff] [blame] | 113 | // Force a deterministic speed step in Real Time mode, as the faster modes |
| 114 | // may not produce a keyframe like we expect. This is necessary when running |
| 115 | // on very slow environments (like Valgrind). The step -11 was determined |
| 116 | // experimentally as the fastest mode that still throws the keyframe. |
| 117 | if (deadline_ == VPX_DL_REALTIME) |
| 118 | set_cpu_used_ = -11; |
| 119 | |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 120 | // This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120. |
| 121 | // I check only the first 40 frames to make sure there's a keyframe at frame |
| 122 | // 0 and 30. |
| 123 | ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, |
| 124 | 30, 1, 0, 40); |
| 125 | |
| 126 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
| 127 | |
Jim Bankoski | 6f35b19 | 2012-10-01 14:17:43 -0700 | [diff] [blame] | 128 | // In realtime mode - auto placed keyframes are exceedingly rare, don't |
| 129 | // bother with this check |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 130 | if (GET_PARAM(1) > 0) |
Jim Bankoski | 6f35b19 | 2012-10-01 14:17:43 -0700 | [diff] [blame] | 131 | EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes "; |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 132 | |
| 133 | // Verify that keyframes match the file keyframes in the file. |
| 134 | for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); |
| 135 | iter != kf_pts_list_.end(); ++iter) { |
Jim Bankoski | 96b6b6b | 2012-06-23 11:20:41 -0700 | [diff] [blame] | 136 | if (deadline_ == VPX_DL_REALTIME && *iter > 0) |
| 137 | EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame " |
| 138 | << *iter; |
| 139 | else |
| 140 | EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter; |
| 141 | } |
| 142 | } |
| 143 | |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 144 | VP8_INSTANTIATE_TEST_CASE(KeyframeTest, ALL_TEST_MODES); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 145 | } // namespace |