add auto keyframe unit test
To do so we add a framework for encoding a yv12 file.. Change-Id: I94a061eb916beaf6cde920cf1aaadb6eed10a717
This commit is contained in:
parent
007486329f
commit
96b6b6bbf0
@ -105,8 +105,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
Encoder encoder(cfg_, deadline_, &stats_);
|
Encoder encoder(cfg_, deadline_, &stats_);
|
||||||
|
|
||||||
bool again;
|
bool again;
|
||||||
|
for (again = true, video->Begin(); again; video->Next()) {
|
||||||
for (video->Begin(), again = true; again; video->Next()) {
|
|
||||||
again = video->img() != NULL;
|
again = video->img() != NULL;
|
||||||
|
|
||||||
PreEncodeFrameHook(video);
|
PreEncodeFrameHook(video);
|
||||||
|
117
test/i420_video_source.h
Normal file
117
test/i420_video_source.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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_I420_VIDEO_SOURCE_H_
|
||||||
|
#define TEST_I420_VIDEO_SOURCE_H_
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "test/video_source.h"
|
||||||
|
|
||||||
|
namespace libvpx_test {
|
||||||
|
|
||||||
|
// This class extends VideoSource to allow parsing of raw yv12
|
||||||
|
// so that we can do actual file encodes.
|
||||||
|
class I420VideoSource : public VideoSource {
|
||||||
|
public:
|
||||||
|
I420VideoSource(const std::string &file_name,
|
||||||
|
unsigned int width, unsigned int height,
|
||||||
|
int rate_numerator, int rate_denominator,
|
||||||
|
unsigned int start, int limit)
|
||||||
|
: file_name_(file_name),
|
||||||
|
img_(NULL),
|
||||||
|
start_(start),
|
||||||
|
limit_(limit),
|
||||||
|
framerate_numerator_(rate_numerator),
|
||||||
|
framerate_denominator_(rate_denominator) {
|
||||||
|
|
||||||
|
// This initializes raw_sz_, width_, height_ and allocates an img.
|
||||||
|
SetSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~I420VideoSource() {
|
||||||
|
vpx_img_free(img_);
|
||||||
|
if (input_file_)
|
||||||
|
fclose(input_file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Begin() {
|
||||||
|
std::string path_to_source = file_name_;
|
||||||
|
const char *kDataPath = getenv("LIBVPX_TEST_DATA_PATH");
|
||||||
|
if (kDataPath) {
|
||||||
|
path_to_source = kDataPath;
|
||||||
|
path_to_source += "/";
|
||||||
|
path_to_source += file_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_file_ = fopen(path_to_source.c_str(), "rb");
|
||||||
|
ASSERT_TRUE(input_file_) << "File open failed.";
|
||||||
|
|
||||||
|
if (start_) {
|
||||||
|
fseek(input_file_, raw_sz_ * start_, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_ = start_;
|
||||||
|
FillFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Next() {
|
||||||
|
++frame_;
|
||||||
|
FillFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual vpx_image_t *img() const { return (frame_ < limit_) ? img_ : NULL; }
|
||||||
|
|
||||||
|
// Models a stream where Timebase = 1/FPS, so pts == frame.
|
||||||
|
virtual vpx_codec_pts_t pts() const { return frame_; }
|
||||||
|
|
||||||
|
virtual unsigned long duration() const { return 1; }
|
||||||
|
|
||||||
|
virtual vpx_rational_t timebase() const {
|
||||||
|
const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ };
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual unsigned int frame() const { return frame_; }
|
||||||
|
|
||||||
|
void SetSize(unsigned int width, unsigned int height) {
|
||||||
|
if (width != width_ || height != height_) {
|
||||||
|
vpx_img_free(img_);
|
||||||
|
img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_VPXI420, width, height, 1);
|
||||||
|
ASSERT_TRUE(img_ != NULL);
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
raw_sz_ = width * height * 3 / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FillFrame() {
|
||||||
|
// Read a frame from input_file.
|
||||||
|
if (fread(img_->img_data, raw_sz_, 1, input_file_) == 0) {
|
||||||
|
limit_ = frame_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string file_name_;
|
||||||
|
FILE *input_file_;
|
||||||
|
vpx_image_t *img_;
|
||||||
|
size_t raw_sz_;
|
||||||
|
unsigned int start_;
|
||||||
|
unsigned int limit_;
|
||||||
|
unsigned int frame_;
|
||||||
|
unsigned int width_;
|
||||||
|
unsigned int height_;
|
||||||
|
unsigned int framerate_numerator_;
|
||||||
|
unsigned int framerate_denominator_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libvpx_test
|
||||||
|
|
||||||
|
#endif // TEST_I420_VIDEO_SOURCE_H_
|
@ -10,13 +10,13 @@
|
|||||||
#include <climits>
|
#include <climits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "test/encode_test_driver.h"
|
#include "test/encode_test_driver.h"
|
||||||
#include "test/video_source.h"
|
#include "test/i420_video_source.h"
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class KeyframeTest : public ::libvpx_test::EncoderTest,
|
class KeyframeTest : public ::libvpx_test::EncoderTest,
|
||||||
public ::testing::TestWithParam<enum libvpx_test::TestMode> {
|
public ::testing::TestWithParam<enum libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
@ -46,7 +46,7 @@ class KeyframeTest : public ::libvpx_test::EncoderTest,
|
|||||||
bool kf_do_force_kf_;
|
bool kf_do_force_kf_;
|
||||||
int kf_count_;
|
int kf_count_;
|
||||||
int kf_count_max_;
|
int kf_count_max_;
|
||||||
std::vector< vpx_codec_pts_t > kf_pts_list_;
|
std::vector<vpx_codec_pts_t> kf_pts_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(KeyframeTest, TestRandomVideoSource) {
|
TEST_P(KeyframeTest, TestRandomVideoSource) {
|
||||||
@ -78,9 +78,8 @@ TEST_P(KeyframeTest, TestForceKeyframe) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
// verify that every third frame is a keyframe.
|
// verify that every third frame is a keyframe.
|
||||||
for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
iter != kf_pts_list_.end();
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
++iter) {
|
|
||||||
ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter;
|
ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,12 +91,37 @@ TEST_P(KeyframeTest, TestKeyframeMaxDistance) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
// verify that keyframe interval matches kf_max_dist
|
// verify that keyframe interval matches kf_max_dist
|
||||||
for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
iter != kf_pts_list_.end();
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
iter++) {
|
|
||||||
ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter;
|
ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestAutoKeyframe) {
|
||||||
|
cfg_.kf_mode = VPX_KF_AUTO;
|
||||||
|
kf_do_force_kf_ = false;
|
||||||
|
|
||||||
|
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
|
||||||
|
// I check only the first 40 frames to make sure there's a keyframe at frame
|
||||||
|
// 0 and 30.
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 40);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes ";
|
||||||
|
|
||||||
|
// Verify that keyframes match the file keyframes in the file.
|
||||||
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
|
|
||||||
|
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||||
|
EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame "
|
||||||
|
<< *iter;
|
||||||
|
else
|
||||||
|
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(AllModes, KeyframeTest, ALL_TEST_MODES);
|
INSTANTIATE_TEST_CASE_P(AllModes, KeyframeTest, ALL_TEST_MODES);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
1
test/test-data.sha1
Normal file
1
test/test-data.sha1
Normal file
@ -0,0 +1 @@
|
|||||||
|
d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv
|
@ -3,8 +3,11 @@ LIBVPX_TEST_SRCS-yes += boolcoder_test.cc
|
|||||||
LIBVPX_TEST_SRCS-yes += config_test.cc
|
LIBVPX_TEST_SRCS-yes += config_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
|
LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
|
||||||
LIBVPX_TEST_SRCS-yes += encode_test_driver.h
|
LIBVPX_TEST_SRCS-yes += encode_test_driver.h
|
||||||
|
LIBVPX_TEST_SRCS-yes += i420_video_source.h
|
||||||
LIBVPX_TEST_SRCS-yes += idctllm_test.cc
|
LIBVPX_TEST_SRCS-yes += idctllm_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += keyframe_test.cc
|
LIBVPX_TEST_SRCS-yes += keyframe_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += resize_test.cc
|
LIBVPX_TEST_SRCS-yes += resize_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += test_libvpx.cc
|
LIBVPX_TEST_SRCS-yes += test_libvpx.cc
|
||||||
LIBVPX_TEST_SRCS-yes += video_source.h
|
LIBVPX_TEST_SRCS-yes += video_source.h
|
||||||
|
|
||||||
|
LIBVPX_TEST_DATA-yes += hantro_collage_w352h288.yuv
|
Loading…
x
Reference in New Issue
Block a user