ref: caf0f14f84b7d66a614bc6f83ca7b311dcda437b
parent: d708e7fbbefb1db496a1073e1f8e3b113f073aab
parent: 2fb29ff7f9267b7bcb5cd29907d2b00f1c279ae3
author: John Koleszar <jkoleszar@google.com>
date: Thu May 24 08:22:34 EDT 2012
Merge changes I231c062e,Idadc42c7 * changes: Add external resize tests Prevent external frame size changes in two-pass
--- a/test/encode_test_driver.h
+++ b/test/encode_test_driver.h
@@ -32,6 +32,10 @@
::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 {
--- /dev/null
+++ b/test/resize_test.cc
@@ -1,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
--- a/test/test.mk
+++ b/test/test.mk
@@ -4,5 +4,6 @@
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
--- a/test/video_source.h
+++ b/test/video_source.h
@@ -44,8 +44,9 @@
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 @@
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 @@
size_t raw_sz_;
unsigned int limit_;
unsigned int frame_;
+ unsigned int width_;
+ unsigned int height_;
};
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -447,7 +447,7 @@
vpx_codec_err_t res;
if (((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
- && cfg->g_lag_in_frames > 1)
+ && (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS))
ERROR("Cannot change width or height after initialization");
/* Prevent increasing lag_in_frames. This check is stricter than it needs
--
⑨