11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann#include <climits> 111b362b15af34006e6a11974088a46d42b903418eJohann#include <vector> 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "third_party/googletest/src/include/gtest/gtest.h" 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/codec_factory.h" 141b362b15af34006e6a11974088a46d42b903418eJohann#include "test/encode_test_driver.h" 151b362b15af34006e6a11974088a46d42b903418eJohann#include "test/i420_video_source.h" 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/util.h" 171b362b15af34006e6a11974088a46d42b903418eJohann 181b362b15af34006e6a11974088a46d42b903418eJohannnamespace { 191b362b15af34006e6a11974088a46d42b903418eJohann 201b362b15af34006e6a11974088a46d42b903418eJohannclass KeyframeTest : public ::libvpx_test::EncoderTest, 21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { 221b362b15af34006e6a11974088a46d42b903418eJohann protected: 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang KeyframeTest() : EncoderTest(GET_PARAM(0)) {} 24a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian virtual ~KeyframeTest() {} 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 261b362b15af34006e6a11974088a46d42b903418eJohann virtual void SetUp() { 271b362b15af34006e6a11974088a46d42b903418eJohann InitializeConfig(); 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang SetMode(GET_PARAM(1)); 291b362b15af34006e6a11974088a46d42b903418eJohann kf_count_ = 0; 301b362b15af34006e6a11974088a46d42b903418eJohann kf_count_max_ = INT_MAX; 311b362b15af34006e6a11974088a46d42b903418eJohann kf_do_force_kf_ = false; 321b362b15af34006e6a11974088a46d42b903418eJohann set_cpu_used_ = 0; 331b362b15af34006e6a11974088a46d42b903418eJohann } 341b362b15af34006e6a11974088a46d42b903418eJohann 351b362b15af34006e6a11974088a46d42b903418eJohann virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, 361b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::Encoder *encoder) { 371b362b15af34006e6a11974088a46d42b903418eJohann if (kf_do_force_kf_) 381b362b15af34006e6a11974088a46d42b903418eJohann frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF; 391b362b15af34006e6a11974088a46d42b903418eJohann if (set_cpu_used_ && video->frame() == 1) 401b362b15af34006e6a11974088a46d42b903418eJohann encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); 411b362b15af34006e6a11974088a46d42b903418eJohann } 421b362b15af34006e6a11974088a46d42b903418eJohann 431b362b15af34006e6a11974088a46d42b903418eJohann virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { 441b362b15af34006e6a11974088a46d42b903418eJohann if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { 451b362b15af34006e6a11974088a46d42b903418eJohann kf_pts_list_.push_back(pkt->data.frame.pts); 461b362b15af34006e6a11974088a46d42b903418eJohann kf_count_++; 471b362b15af34006e6a11974088a46d42b903418eJohann abort_ |= kf_count_ > kf_count_max_; 481b362b15af34006e6a11974088a46d42b903418eJohann } 491b362b15af34006e6a11974088a46d42b903418eJohann } 501b362b15af34006e6a11974088a46d42b903418eJohann 511b362b15af34006e6a11974088a46d42b903418eJohann bool kf_do_force_kf_; 521b362b15af34006e6a11974088a46d42b903418eJohann int kf_count_; 531b362b15af34006e6a11974088a46d42b903418eJohann int kf_count_max_; 541b362b15af34006e6a11974088a46d42b903418eJohann std::vector<vpx_codec_pts_t> kf_pts_list_; 551b362b15af34006e6a11974088a46d42b903418eJohann int set_cpu_used_; 561b362b15af34006e6a11974088a46d42b903418eJohann}; 571b362b15af34006e6a11974088a46d42b903418eJohann 581b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(KeyframeTest, TestRandomVideoSource) { 591b362b15af34006e6a11974088a46d42b903418eJohann // Validate that encoding the RandomVideoSource produces multiple keyframes. 601b362b15af34006e6a11974088a46d42b903418eJohann // This validates the results of the TestDisableKeyframes test. 611b362b15af34006e6a11974088a46d42b903418eJohann kf_count_max_ = 2; // early exit successful tests. 621b362b15af34006e6a11974088a46d42b903418eJohann 631b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::RandomVideoSource video; 641b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 651b362b15af34006e6a11974088a46d42b903418eJohann 661b362b15af34006e6a11974088a46d42b903418eJohann // In realtime mode - auto placed keyframes are exceedingly rare, don't 671b362b15af34006e6a11974088a46d42b903418eJohann // bother with this check if(GetParam() > 0) 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (GET_PARAM(1) > 0) 691b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_GT(kf_count_, 1); 701b362b15af34006e6a11974088a46d42b903418eJohann} 711b362b15af34006e6a11974088a46d42b903418eJohann 721b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(KeyframeTest, TestDisableKeyframes) { 731b362b15af34006e6a11974088a46d42b903418eJohann cfg_.kf_mode = VPX_KF_DISABLED; 741b362b15af34006e6a11974088a46d42b903418eJohann kf_count_max_ = 1; // early exit failed tests. 751b362b15af34006e6a11974088a46d42b903418eJohann 761b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::RandomVideoSource video; 771b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 781b362b15af34006e6a11974088a46d42b903418eJohann 791b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_EQ(1, kf_count_); 801b362b15af34006e6a11974088a46d42b903418eJohann} 811b362b15af34006e6a11974088a46d42b903418eJohann 821b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(KeyframeTest, TestForceKeyframe) { 831b362b15af34006e6a11974088a46d42b903418eJohann cfg_.kf_mode = VPX_KF_DISABLED; 841b362b15af34006e6a11974088a46d42b903418eJohann kf_do_force_kf_ = true; 851b362b15af34006e6a11974088a46d42b903418eJohann 861b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::DummyVideoSource video; 871b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 881b362b15af34006e6a11974088a46d42b903418eJohann 891b362b15af34006e6a11974088a46d42b903418eJohann // verify that every third frame is a keyframe. 901b362b15af34006e6a11974088a46d42b903418eJohann for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); 911b362b15af34006e6a11974088a46d42b903418eJohann iter != kf_pts_list_.end(); ++iter) { 921b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter; 931b362b15af34006e6a11974088a46d42b903418eJohann } 941b362b15af34006e6a11974088a46d42b903418eJohann} 951b362b15af34006e6a11974088a46d42b903418eJohann 961b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(KeyframeTest, TestKeyframeMaxDistance) { 971b362b15af34006e6a11974088a46d42b903418eJohann cfg_.kf_max_dist = 25; 981b362b15af34006e6a11974088a46d42b903418eJohann 991b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::DummyVideoSource video; 1001b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 1011b362b15af34006e6a11974088a46d42b903418eJohann 1021b362b15af34006e6a11974088a46d42b903418eJohann // verify that keyframe interval matches kf_max_dist 1031b362b15af34006e6a11974088a46d42b903418eJohann for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); 1041b362b15af34006e6a11974088a46d42b903418eJohann iter != kf_pts_list_.end(); ++iter) { 1051b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter; 1061b362b15af34006e6a11974088a46d42b903418eJohann } 1071b362b15af34006e6a11974088a46d42b903418eJohann} 1081b362b15af34006e6a11974088a46d42b903418eJohann 1091b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(KeyframeTest, TestAutoKeyframe) { 1101b362b15af34006e6a11974088a46d42b903418eJohann cfg_.kf_mode = VPX_KF_AUTO; 1111b362b15af34006e6a11974088a46d42b903418eJohann kf_do_force_kf_ = false; 1121b362b15af34006e6a11974088a46d42b903418eJohann 1131b362b15af34006e6a11974088a46d42b903418eJohann // Force a deterministic speed step in Real Time mode, as the faster modes 1141b362b15af34006e6a11974088a46d42b903418eJohann // may not produce a keyframe like we expect. This is necessary when running 1151b362b15af34006e6a11974088a46d42b903418eJohann // on very slow environments (like Valgrind). The step -11 was determined 1161b362b15af34006e6a11974088a46d42b903418eJohann // experimentally as the fastest mode that still throws the keyframe. 1171b362b15af34006e6a11974088a46d42b903418eJohann if (deadline_ == VPX_DL_REALTIME) 1181b362b15af34006e6a11974088a46d42b903418eJohann set_cpu_used_ = -11; 1191b362b15af34006e6a11974088a46d42b903418eJohann 1201b362b15af34006e6a11974088a46d42b903418eJohann // This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120. 1211b362b15af34006e6a11974088a46d42b903418eJohann // I check only the first 40 frames to make sure there's a keyframe at frame 1221b362b15af34006e6a11974088a46d42b903418eJohann // 0 and 30. 1231b362b15af34006e6a11974088a46d42b903418eJohann ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 1241b362b15af34006e6a11974088a46d42b903418eJohann 30, 1, 0, 40); 1251b362b15af34006e6a11974088a46d42b903418eJohann 1261b362b15af34006e6a11974088a46d42b903418eJohann ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 1271b362b15af34006e6a11974088a46d42b903418eJohann 1281b362b15af34006e6a11974088a46d42b903418eJohann // In realtime mode - auto placed keyframes are exceedingly rare, don't 1291b362b15af34006e6a11974088a46d42b903418eJohann // bother with this check 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (GET_PARAM(1) > 0) 1311b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes "; 1321b362b15af34006e6a11974088a46d42b903418eJohann 1331b362b15af34006e6a11974088a46d42b903418eJohann // Verify that keyframes match the file keyframes in the file. 1341b362b15af34006e6a11974088a46d42b903418eJohann for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin(); 1351b362b15af34006e6a11974088a46d42b903418eJohann iter != kf_pts_list_.end(); ++iter) { 1361b362b15af34006e6a11974088a46d42b903418eJohann if (deadline_ == VPX_DL_REALTIME && *iter > 0) 1371b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame " 1381b362b15af34006e6a11974088a46d42b903418eJohann << *iter; 1391b362b15af34006e6a11974088a46d42b903418eJohann else 1401b362b15af34006e6a11974088a46d42b903418eJohann EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter; 1411b362b15af34006e6a11974088a46d42b903418eJohann } 1421b362b15af34006e6a11974088a46d42b903418eJohann} 1431b362b15af34006e6a11974088a46d42b903418eJohann 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangVP8_INSTANTIATE_TEST_CASE(KeyframeTest, ALL_TEST_MODES); 1451b362b15af34006e6a11974088a46d42b903418eJohann} // namespace 146