shithub: libvpx

Download patch

ref: d67acd870a469857c38f89427c06f4f6bfa46e2b
parent: 4e06b0c602356635f2f0cb97c04a92bd478e63b7
parent: 96b6b6bbf046c944b44a2ca96d4c6adb851fecf7
author: John Koleszar <jkoleszar@google.com>
date: Mon Jun 25 08:52:02 EDT 2012

Merge changes I94a061eb,If6910fe3

* changes:
  add auto keyframe unit test
  Add support for downloading test data

--- a/README
+++ b/README
@@ -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 @@
     * 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 @@
 
 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.
 
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -21,6 +21,7 @@
 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 @@
 install::
 .PHONY: test
 test::
+.PHONY: testdata
+testdata::
 
 $(BUILD_PFX)%.c.d: %.c
 	$(if $(quiet),@echo "    [DEP] $@")
--- a/libs.mk
+++ b/libs.mk
@@ -352,11 +352,29 @@
 ## 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 @@
 
 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 @@
         )))\
     $(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
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -105,8 +105,7 @@
     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);
--- /dev/null
+++ b/test/i420_video_source.h
@@ -1,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_
--- a/test/keyframe_test.cc
+++ b/test/keyframe_test.cc
@@ -10,13 +10,13 @@
 #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 {
 
 class KeyframeTest : public ::libvpx_test::EncoderTest,
-  public ::testing::TestWithParam<enum libvpx_test::TestMode> {
+    public ::testing::TestWithParam<enum libvpx_test::TestMode> {
  protected:
   virtual void SetUp() {
     InitializeConfig();
@@ -46,7 +46,7 @@
   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 @@
   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,10 +91,35 @@
   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;
   }
 }
 
--- /dev/null
+++ b/test/test-data.sha1
@@ -1,0 +1,1 @@
+d5dfb0151c9051f8c85999255645d7a23916d3c0  hantro_collage_w352h288.yuv
--- a/test/test.mk
+++ b/test/test.mk
@@ -3,6 +3,7 @@
 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
@@ -9,3 +10,5 @@
 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
--