Add external resize tests
authorJohn Koleszar <jkoleszar@google.com>
Wed, 23 May 2012 19:55:27 +0000 (12:55 -0700)
committerJohn Koleszar <jkoleszar@google.com>
Thu, 24 May 2012 16:38:39 +0000 (09:38 -0700)
Adds a test that ensures the application is able to trigger frame size
changes via vpx_codec_enc_config_set()

Change-Id: I231c062e533d75c8d63c5f8a5544650117429a63

test/encode_test_driver.h
test/resize_test.cc [new file with mode: 0644]
test/test.mk
test/video_source.h

index 43faaae..2fb627c 100644 (file)
@@ -32,6 +32,10 @@ enum TestMode {
                                          ::libvpx_test::kTwoPassGood, \
                                          ::libvpx_test::kTwoPassBest)
 
+#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
+                                              ::libvpx_test::kOnePassGood, \
+                                              ::libvpx_test::kOnePassBest)
+
 
 // Provides an object to handle the libvpx get_cx_data() iteration pattern
 class CxDataIterator {
diff --git a/test/resize_test.cc b/test/resize_test.cc
new file mode 100644 (file)
index 0000000..c846157
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  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.
+ */
+#include <climits>
+#include <vector>
+#include "test/encode_test_driver.h"
+#include "test/video_source.h"
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+namespace {
+
+const unsigned int kInitialWidth = 320;
+const unsigned int kInitialHeight = 240;
+
+unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
+  if (frame < 10)
+    return val;
+  if (frame < 20)
+    return val / 2;
+  if (frame < 30)
+    return val * 2 / 3;
+  if (frame < 40)
+    return val / 4;
+  if (frame < 50)
+    return val * 7 / 8;
+  return val;
+}
+
+class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
+ public:
+  ResizingVideoSource() {
+    SetSize(kInitialWidth, kInitialHeight);
+    limit_ = 60;
+  }
+
+ protected:
+  virtual void Next() {
+    ++frame_;
+    SetSize(ScaleForFrameNumber(frame_, kInitialWidth),
+            ScaleForFrameNumber(frame_, kInitialHeight));
+    FillFrame();
+  }
+};
+
+class ResizeTest : public ::libvpx_test::EncoderTest,
+  public ::testing::TestWithParam<enum libvpx_test::TestMode> {
+ protected:
+  struct FrameInfo {
+    FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
+        : pts(_pts), w(_w), h(_h) {}
+
+    vpx_codec_pts_t pts;
+    unsigned int    w;
+    unsigned int    h;
+  };
+
+  virtual void SetUp() {
+    InitializeConfig();
+    SetMode(GetParam());
+  }
+
+  virtual bool Continue() const {
+    return !HasFatalFailure() && !abort_;
+  }
+
+  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
+    if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
+      const unsigned char *buf =
+          reinterpret_cast<const unsigned char *>(pkt->data.frame.buf);
+      const unsigned int w = (buf[6] | (buf[7] << 8)) & 0x3fff;
+      const unsigned int h = (buf[8] | (buf[9] << 8)) & 0x3fff;
+
+      frame_info_list_.push_back(FrameInfo(pkt->data.frame.pts, w, h));
+    }
+  }
+
+  std::vector< FrameInfo > frame_info_list_;
+};
+
+TEST_P(ResizeTest, TestExternalResizeWorks) {
+  ResizingVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  for (std::vector<FrameInfo>::iterator info = frame_info_list_.begin();
+       info != frame_info_list_.end(); ++info) {
+    const vpx_codec_pts_t pts = info->pts;
+    const unsigned int expected_w = ScaleForFrameNumber(pts, kInitialWidth);
+    const unsigned int expected_h = ScaleForFrameNumber(pts, kInitialHeight);
+
+    EXPECT_EQ(expected_w, info->w)
+        << "Frame " << pts << "had unexpected width";
+    EXPECT_EQ(expected_h, info->h)
+        << "Frame " << pts << "had unexpected height";
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(OnePass, ResizeTest, ONE_PASS_TEST_MODES);
+}  // namespace
index d04ad17..ac500fe 100644 (file)
@@ -4,5 +4,6 @@ LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
 LIBVPX_TEST_SRCS-yes += encode_test_driver.h
 LIBVPX_TEST_SRCS-yes += idctllm_test.cc
 LIBVPX_TEST_SRCS-yes += keyframe_test.cc
+LIBVPX_TEST_SRCS-yes += resize_test.cc
 LIBVPX_TEST_SRCS-yes += test_libvpx.cc
 LIBVPX_TEST_SRCS-yes += video_source.h
index 86c6caa..3507ef0 100644 (file)
@@ -44,8 +44,9 @@ class VideoSource {
 
 class DummyVideoSource : public VideoSource {
  public:
-  DummyVideoSource()
-    : img_(NULL), limit_(100) { SetSize(80, 64); }
+  DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
+    SetSize(80, 64);
+  }
 
   virtual ~DummyVideoSource() { vpx_img_free(img_); }
 
@@ -76,9 +77,13 @@ class DummyVideoSource : public VideoSource {
   virtual unsigned int frame() const { return frame_; }
 
   void SetSize(unsigned int width, unsigned int height) {
-    vpx_img_free(img_);
-    raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
-    img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_VPXI420, width, height, 32);
+    if (width != width_ || height != height_) {
+      vpx_img_free(img_);
+      raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
+      img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_VPXI420, width, height, 32);
+      width_ = width;
+      height_ = height;
+    }
   }
 
  protected:
@@ -88,6 +93,8 @@ class DummyVideoSource : public VideoSource {
   size_t       raw_sz_;
   unsigned int limit_;
   unsigned int frame_;
+  unsigned int width_;
+  unsigned int height_;
 };