Merge changes I94a061eb,If6910fe3

* changes:
  add auto keyframe unit test
  Add support for downloading test data
This commit is contained in:
John Koleszar 2012-06-25 12:52:02 -07:00 committed by Gerrit Code Review
commit d67acd870a
8 changed files with 188 additions and 15 deletions

12
README
View File

@ -1,5 +1,5 @@
vpx Multi-Format Codec SDK
README - 19 May 2010
README - 21 June 2012
Welcome to the WebM VP8 Codec SDK!
@ -15,11 +15,19 @@ COMPILING THE APPLICATIONS/LIBRARIES:
* Building the documentation requires PHP[3] and Doxygen[4]. If you do not
have these packages, you must pass --disable-install-docs to the
configure script.
* Downloading the data for the unit tests requires curl[5] and sha1sum.
sha1sum is provided via the GNU coreutils, installed by default on
many *nix platforms, as well as MinGW and Cygwin. If coreutils is not
available, a compatible version of sha1sum can be built from
source[6]. These requirements are optional if not running the unit
tests.
[1]: http://www.tortall.net/projects/yasm
[2]: http://www.cygwin.com
[3]: http://php.net
[4]: http://www.doxygen.org
[5]: http://curl.haxx.se
[6]: http://www.microbrew.org/tools/md5sha1sum/
2. Out-of-tree builds
Out of tree builds are a supported method of building the application. For
@ -94,5 +102,5 @@ COMPILING THE APPLICATIONS/LIBRARIES:
SUPPORT
This library is an open source project supported by its community. Please
please email webm-users@webmproject.org for help.
please email webm-discuss@webmproject.org for help.

View File

@ -21,6 +21,7 @@ all: .DEFAULT
clean:: .DEFAULT
install:: .DEFAULT
test:: .DEFAULT
testdata:: .DEFAULT
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
@ -99,6 +100,8 @@ dist:
install::
.PHONY: test
test::
.PHONY: testdata
testdata::
$(BUILD_PFX)%.c.d: %.c
$(if $(quiet),@echo " [DEP] $@")

22
libs.mk
View File

@ -352,10 +352,28 @@ CODEC_DOC_SRCS += vpx/vpx_codec.h \
## libvpx test directives
##
ifeq ($(CONFIG_UNIT_TESTS),yes)
LIBVPX_TEST_DATA_PATH ?= .
include $(SRC_PATH_BARE)/test/test.mk
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
LIBVPX_TEST_BINS=./test_libvpx
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
$(call enabled,LIBVPX_TEST_DATA))
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
$(LIBVPX_TEST_DATA):
@echo " [DOWNLOAD] $@"
$(qexec)trap 'rm -f $@' INT TERM &&\
curl -L -o $@ $(call libvpx_test_data_url,$(@F))
testdata:: $(LIBVPX_TEST_DATA)
$(qexec)if [ -x "$$(which sha1sum)" ]; then\
echo "Checking test data:";\
(cd $(LIBVPX_TEST_DATA_PATH); sha1sum -c)\
< $(SRC_PATH_BARE)/test/test-data.sha1; \
else\
echo "Skipping test data integrity check, sha1sum not found.";\
fi
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
ifeq ($(CONFIG_MSVS),yes)
@ -390,7 +408,7 @@ test_libvpx.vcproj: $(LIBVPX_TEST_SRCS)
PROJECTS-$(CONFIG_MSVS) += test_libvpx.vcproj
test::
test:: testdata
@set -e; for t in $(addprefix Win32/Release/,$(notdir $(LIBVPX_TEST_BINS:.cc=.exe))); do $$t; done
endif
else
@ -422,7 +440,7 @@ $(foreach bin,$(LIBVPX_TEST_BINS),\
)))\
$(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
test:: $(LIBVPX_TEST_BINS)
test:: $(LIBVPX_TEST_BINS) testdata
@set -e; for t in $(LIBVPX_TEST_BINS); do $$t; done
endif

View File

@ -105,8 +105,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
Encoder encoder(cfg_, deadline_, &stats_);
bool again;
for (video->Begin(), again = true; again; video->Next()) {
for (again = true, video->Begin(); again; video->Next()) {
again = video->img() != NULL;
PreEncodeFrameHook(video);

117
test/i420_video_source.h Normal file
View 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_

View File

@ -10,7 +10,7 @@
#include <climits>
#include <vector>
#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"
namespace {
@ -46,7 +46,7 @@ class KeyframeTest : public ::libvpx_test::EncoderTest,
bool kf_do_force_kf_;
int kf_count_;
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) {
@ -78,9 +78,8 @@ TEST_P(KeyframeTest, TestForceKeyframe) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// verify that every third frame is a keyframe.
for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
iter != kf_pts_list_.end();
++iter) {
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
iter != kf_pts_list_.end(); ++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));
// verify that keyframe interval matches kf_max_dist
for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
iter != kf_pts_list_.end();
iter++) {
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
iter != kf_pts_list_.end(); ++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);
} // namespace

1
test/test-data.sha1 Normal file
View File

@ -0,0 +1 @@
d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv

View File

@ -3,9 +3,12 @@ LIBVPX_TEST_SRCS-yes += boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += config_test.cc
LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
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 += keyframe_test.cc
LIBVPX_TEST_SRCS-yes += pp_filter_test.cc
LIBVPX_TEST_SRCS-yes += resize_test.cc
LIBVPX_TEST_SRCS-yes += test_libvpx.cc
LIBVPX_TEST_SRCS-yes += video_source.h
LIBVPX_TEST_DATA-yes += hantro_collage_w352h288.yuv