diff --git a/build/make/Makefile b/build/make/Makefile index b6cf3208a..26ca0be70 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -66,6 +66,7 @@ endif BUILD_ROOT?=. VPATH=$(SRC_PATH_BARE) CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH) +CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH) ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/ -I$(SRC_PATH)/ DIST_DIR?=dist HOSTCC?=gcc @@ -111,11 +112,11 @@ $(BUILD_PFX)%.c.o: %.c $(BUILD_PFX)%.cc.d: %.cc $(if $(quiet),@echo " [DEP] $@") $(qexec)mkdir -p $(dir $@) - $(qexec)g++ $(INTERNAL_CFLAGS) $(CFLAGS) -M $< | $(fmt_deps) > $@ + $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@ $(BUILD_PFX)%.cc.o: %.cc $(if $(quiet),@echo " [CXX] $@") - $(qexec)g++ $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $< + $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< $(BUILD_PFX)%.asm.d: %.asm $(if $(quiet),@echo " [DEP] $@") @@ -213,7 +214,7 @@ define linkerxx_template $(1): $(filter-out -%,$(2)) $(1): $(if $(quiet),@echo " [LD] $$@") - $(qexec)g++ $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs)) + $(qexec)$$(CXX) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs)) endef # make-3.80 has a bug with expanding large input strings to the eval function, # which was triggered in some cases by the following component of diff --git a/build/make/configure.sh b/build/make/configure.sh index 068ccdc2a..f8d69aed1 100755 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -166,6 +166,17 @@ is_in(){ add_cflags() { CFLAGS="${CFLAGS} $@" + CXXFLAGS="${CXXFLAGS} $@" +} + + +add_cflags_only() { + CFLAGS="${CFLAGS} $@" +} + + +add_cxxflags_only() { + CXXFLAGS="${CXXFLAGS} $@" } @@ -277,6 +288,13 @@ check_cc() { check_cmd ${CC} ${CFLAGS} "$@" -c -o ${TMP_O} ${TMP_C} } +check_cxx() { + log check_cxx "$@" + cat >${TMP_C} + log_file ${TMP_C} + check_cmd ${CXX} ${CXXFLAGS} "$@" -c -o ${TMP_O} ${TMP_C} +} + check_cpp() { log check_cpp "$@" cat > ${TMP_C} @@ -310,8 +328,25 @@ int x; EOF } +check_cxxflags() { + log check_cxxflags "$@" + + # Catch CFLAGS that trigger CXX warnings + case "$CXX" in + *g++*) check_cxx -Werror "$@" <> $1 << EOF @@ -379,6 +416,7 @@ TOOLCHAIN=${toolchain} ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl} CC=${CC} +CXX=${CXX} AR=${AR} LD=${LD} AS=${AS} @@ -386,6 +424,7 @@ STRIP=${STRIP} NM=${NM} CFLAGS = ${CFLAGS} +CXXFLAGS = ${CXXFLAGS} ARFLAGS = -rus\$(if \$(quiet),c,v) LDFLAGS = ${LDFLAGS} ASFLAGS = ${ASFLAGS} @@ -538,6 +577,7 @@ post_process_cmdline() { setup_gnu_toolchain() { CC=${CC:-${CROSS}gcc} + CXX=${CXX:-${CROSS}g++} AR=${AR:-${CROSS}ar} LD=${LD:-${CROSS}${link_with_cc:-ld}} AS=${AS:-${CROSS}as} @@ -792,6 +832,7 @@ process_common_toolchain() { -name "arm-linux-androideabi-gcc*" -print -quit` TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi- CC=${TOOLCHAIN_PATH}gcc + CXX=${TOOLCHAIN_PATH}g++ AR=${TOOLCHAIN_PATH}ar LD=${TOOLCHAIN_PATH}gcc AS=${TOOLCHAIN_PATH}as @@ -827,6 +868,7 @@ process_common_toolchain() { SDK_PATH=${sdk_path} fi TOOLCHAIN_PATH=${SDK_PATH}/usr/bin + CXX=${TOOLCHAIN_PATH}/g++ CC=${TOOLCHAIN_PATH}/gcc AR=${TOOLCHAIN_PATH}/ar LD=${TOOLCHAIN_PATH}/arm-apple-darwin10-llvm-gcc-4.2 @@ -938,6 +980,7 @@ process_common_toolchain() { ;; solaris*) CC=${CC:-${CROSS}gcc} + CXX=${CXX:-${CROSS}g++} LD=${LD:-${CROSS}gcc} CROSS=${CROSS:-g} ;; diff --git a/configure b/configure index 2b1328dbd..eed6f970b 100755 --- a/configure +++ b/configure @@ -586,6 +586,16 @@ process_toolchain() { if enabled postproc_visualizer; then enabled postproc || die "postproc_visualizer requires postproc to be enabled" fi + + # Enable unit tests if we have a working C++ compiler + case "$tgt_cc" in + vs*) + soft_enable unit_tests;; + *) + check_cxx "$@" <> $@ @echo "INCLUDE_PATH += ." >> $@; @echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@ + +## Generate vpx_rtcd.h for all objects +$(OBJS-yes:.o=.d): $(BUILD_PFX)vpx_rtcd.h diff --git a/vp8/encoder/boolcoder_test.cc b/test/boolcoder_test.cc similarity index 97% rename from vp8/encoder/boolcoder_test.cc rename to test/boolcoder_test.cc index 9d9462690..00c2b7593 100644 --- a/vp8/encoder/boolcoder_test.cc +++ b/test/boolcoder_test.cc @@ -121,9 +121,3 @@ TEST(VP8, TestBitIO) } } } - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc new file mode 100644 index 000000000..0a188facf --- /dev/null +++ b/test/encode_test_driver.cc @@ -0,0 +1,137 @@ +/* + * 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 "test/encode_test_driver.h" +#include "test/video_source.h" +#include "third_party/googletest/src/include/gtest/gtest.h" + +namespace libvpx_test { + +void Encoder::EncodeFrame(VideoSource *video, unsigned long flags) { + if (video->img()) + EncodeFrameInternal(*video, flags); + else + Flush(); + + // Handle twopass stats + CxDataIterator iter = GetCxData(); + + while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { + if (pkt->kind != VPX_CODEC_STATS_PKT) + continue; + + stats_->Append(*pkt); + } +} + +void Encoder::EncodeFrameInternal(const VideoSource &video, + unsigned long flags) { + vpx_codec_err_t res; + const vpx_image_t *img = video.img(); + + // Handle first frame initialization + if (!encoder_.priv) { + cfg_.g_w = img->d_w; + cfg_.g_h = img->d_h; + cfg_.g_timebase = video.timebase(); + cfg_.rc_twopass_stats_in = stats_->buf(); + res = vpx_codec_enc_init(&encoder_, &vpx_codec_vp8_cx_algo, &cfg_, 0); + ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); + } + + // Handle frame resizing + if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { + cfg_.g_w = img->d_w; + cfg_.g_h = img->d_h; + res = vpx_codec_enc_config_set(&encoder_, &cfg_); + ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); + } + + // Encode the frame + res = vpx_codec_encode(&encoder_, + video.img(), video.pts(), video.duration(), + flags, deadline_); + ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); +} + +void Encoder::Flush() { + const vpx_codec_err_t res = vpx_codec_encode(&encoder_, NULL, 0, 0, 0, + deadline_); + ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); +} + +void EncoderTest::SetMode(TestMode mode) { + switch (mode) { + case kRealTime: + deadline_ = VPX_DL_REALTIME; + break; + + case kOnePassGood: + case kTwoPassGood: + deadline_ = VPX_DL_GOOD_QUALITY; + break; + + case kOnePassBest: + case kTwoPassBest: + deadline_ = VPX_DL_BEST_QUALITY; + break; + + default: + ASSERT_TRUE(false) << "Unexpected mode " << mode; + } + + if (mode == kTwoPassGood || mode == kTwoPassBest) + passes_ = 2; + else + passes_ = 1; +} + +void EncoderTest::RunLoop(VideoSource *video) { + for (unsigned int pass = 0; pass < passes_; pass++) { + if (passes_ == 1) + cfg_.g_pass = VPX_RC_ONE_PASS; + else if (pass == 0) + cfg_.g_pass = VPX_RC_FIRST_PASS; + else + cfg_.g_pass = VPX_RC_LAST_PASS; + + BeginPassHook(pass); + Encoder encoder(cfg_, deadline_, &stats_); + + bool again; + + for (video->Begin(), again = true; again; video->Next()) { + again = video->img() != NULL; + + PreEncodeFrameHook(video); + encoder.EncodeFrame(video, flags_); + + CxDataIterator iter = encoder.GetCxData(); + + while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { + again = true; + + if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) + continue; + + FramePktHook(pkt); + } + + if (!Continue()) + break; + } + + EndPassHook(); + + if (!Continue()) + break; + } +} + +} // namespace libvpx_test diff --git a/test/encode_test_driver.h b/test/encode_test_driver.h new file mode 100644 index 000000000..43faaaed7 --- /dev/null +++ b/test/encode_test_driver.h @@ -0,0 +1,178 @@ +/* + * 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_ENCODE_TEST_DRIVER_H_ +#define TEST_ENCODE_TEST_DRIVER_H_ +#include +#include +#include "third_party/googletest/src/include/gtest/gtest.h" +#include "vpx/vpx_encoder.h" +#include "vpx/vp8cx.h" + +namespace libvpx_test { + +class VideoSource; + +enum TestMode { + kRealTime, + kOnePassGood, + kOnePassBest, + kTwoPassGood, + kTwoPassBest +}; +#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \ + ::libvpx_test::kOnePassGood, \ + ::libvpx_test::kOnePassBest, \ + ::libvpx_test::kTwoPassGood, \ + ::libvpx_test::kTwoPassBest) + + +// Provides an object to handle the libvpx get_cx_data() iteration pattern +class CxDataIterator { + public: + explicit CxDataIterator(vpx_codec_ctx_t *encoder) + : encoder_(encoder), iter_(NULL) {} + + const vpx_codec_cx_pkt_t *Next() { + return vpx_codec_get_cx_data(encoder_, &iter_); + } + + private: + vpx_codec_ctx_t *encoder_; + vpx_codec_iter_t iter_; +}; + + +// Implements an in-memory store for libvpx twopass statistics +class TwopassStatsStore { + public: + void Append(const vpx_codec_cx_pkt_t &pkt) { + buffer_.append(reinterpret_cast(pkt.data.twopass_stats.buf), + pkt.data.twopass_stats.sz); + } + + vpx_fixed_buf_t buf() { + const vpx_fixed_buf_t buf = { &buffer_[0], buffer_.size() }; + return buf; + } + + protected: + std::string buffer_; +}; + + +// Provides a simplified interface to manage one video encoding pass, given +// a configuration and video source. +// +// TODO(jkoleszar): The exact services it provides and the appropriate +// level of abstraction will be fleshed out as more tests are written. +class Encoder { + public: + Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline, + TwopassStatsStore *stats) + : cfg_(cfg), deadline_(deadline), stats_(stats) { + memset(&encoder_, 0, sizeof(encoder_)); + } + + ~Encoder() { + vpx_codec_destroy(&encoder_); + } + + CxDataIterator GetCxData() { + return CxDataIterator(&encoder_); + } + + // This is a thin wrapper around vpx_codec_encode(), so refer to + // vpx_encoder.h for its semantics. + void EncodeFrame(VideoSource *video, unsigned long flags); + + // Convenience wrapper for EncodeFrame() + void EncodeFrame(VideoSource *video) { + EncodeFrame(video, 0); + } + + void set_deadline(unsigned long deadline) { + deadline_ = deadline; + } + + protected: + const char *EncoderError() { + const char *detail = vpx_codec_error_detail(&encoder_); + return detail ? detail : vpx_codec_error(&encoder_); + } + + // Encode an image + void EncodeFrameInternal(const VideoSource &video, unsigned long flags); + + // Flush the encoder on EOS + void Flush(); + + vpx_codec_ctx_t encoder_; + vpx_codec_enc_cfg_t cfg_; + unsigned long deadline_; + TwopassStatsStore *stats_; +}; + + +// Common test functionality for all Encoder tests. +// +// This class is a mixin which provides the main loop common to all +// encoder tests. It provides hooks which can be overridden by subclasses +// to implement each test's specific behavior, while centralizing the bulk +// of the boilerplate. Note that it doesn't inherit the gtest testing +// classes directly, so that tests can be parameterized differently. +class EncoderTest { + protected: + EncoderTest() : abort_(false), flags_(0) {} + + virtual ~EncoderTest() {} + + // Initialize the cfg_ member with the default configuration. + void InitializeConfig() { + const vpx_codec_err_t res = vpx_codec_enc_config_default( + &vpx_codec_vp8_cx_algo, &cfg_, 0); + ASSERT_EQ(VPX_CODEC_OK, res); + } + + // Map the TestMode enum to the deadline_ and passes_ variables. + void SetMode(TestMode mode); + + // Main loop. + virtual void RunLoop(VideoSource *video); + + // Hook to be called at the beginning of a pass. + virtual void BeginPassHook(unsigned int pass) {} + + // Hook to be called at the end of a pass. + virtual void EndPassHook() {} + + // Hook to be called before encoding a frame. + virtual void PreEncodeFrameHook(VideoSource *video) {} + + // Hook to be called on every compressed data packet. + virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {} + + // Hook to determine whether the encode loop should continue. + virtual bool Continue() const { return !abort_; } + + bool abort_; + vpx_codec_enc_cfg_t cfg_; + unsigned int passes_; + unsigned long deadline_; + TwopassStatsStore stats_; + unsigned long flags_; +}; + +} // namespace libvpx_test + +// Macros to be used with ::testing::Combine +#define PARAMS(...) ::testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > > +#define GET_PARAM(k) std::tr1::get< k >(GetParam()) + +#endif // TEST_ENCODE_TEST_DRIVER_H_ diff --git a/vp8/common/idctllm_test.h b/test/idctllm_test.cc similarity index 84% rename from vp8/common/idctllm_test.h rename to test/idctllm_test.cc index a6a694b18..dd42e2299 100755 --- a/vp8/common/idctllm_test.h +++ b/test/idctllm_test.cc @@ -9,10 +9,15 @@ */ - #include "third_party/googletest/src/include/gtest/gtest.h" +extern "C" { +#include "vpx_config.h" +#include "vpx_rtcd.h" +} +#include "third_party/googletest/src/include/gtest/gtest.h" + typedef void (*idct_fn_t)(short *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride); + int pred_stride, unsigned char *dst_ptr, + int dst_stride); namespace { class IDCTTest : public ::testing::TestWithParam { @@ -110,4 +115,11 @@ TEST_P(IDCTTest, TestWithData) else EXPECT_EQ(0, output[i]) << "i==" << i; } + +INSTANTIATE_TEST_CASE_P(C, IDCTTest, + ::testing::Values(vp8_short_idct4x4llm_c)); +#if HAVE_MMX +INSTANTIATE_TEST_CASE_P(MMX, IDCTTest, + ::testing::Values(vp8_short_idct4x4llm_mmx)); +#endif } diff --git a/test/keyframe_test.cc b/test/keyframe_test.cc new file mode 100644 index 000000000..db18e5dab --- /dev/null +++ b/test/keyframe_test.cc @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include "test/encode_test_driver.h" +#include "test/video_source.h" +#include "third_party/googletest/src/include/gtest/gtest.h" + +namespace { + +class KeyframeTest : public ::libvpx_test::EncoderTest, + public ::testing::TestWithParam { + protected: + virtual void SetUp() { + InitializeConfig(); + SetMode(GetParam()); + kf_count_ = 0; + kf_count_max_ = INT_MAX; + kf_do_force_kf_ = false; + } + + virtual bool Continue() { + return !HasFatalFailure() && !abort_; + } + + virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video) { + if (kf_do_force_kf_) + flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF; + } + + virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { + if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { + kf_pts_list_.push_back(pkt->data.frame.pts); + kf_count_++; + abort_ |= kf_count_ > kf_count_max_; + } + } + + bool kf_do_force_kf_; + int kf_count_; + int kf_count_max_; + std::vector< vpx_codec_pts_t > kf_pts_list_; +}; + +TEST_P(KeyframeTest, TestRandomVideoSource) { + // Validate that encoding the RandomVideoSource produces multiple keyframes. + // This validates the results of the TestDisableKeyframes test. + kf_count_max_ = 2; // early exit successful tests. + + ::libvpx_test::RandomVideoSource video; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + EXPECT_GT(kf_count_, 1); +} + +TEST_P(KeyframeTest, TestDisableKeyframes) { + cfg_.kf_mode = VPX_KF_DISABLED; + kf_count_max_ = 1; // early exit failed tests. + + ::libvpx_test::RandomVideoSource video; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + EXPECT_EQ(1, kf_count_); +} + +TEST_P(KeyframeTest, TestForceKeyframe) { + cfg_.kf_mode = VPX_KF_DISABLED; + kf_do_force_kf_ = true; + + ::libvpx_test::DummyVideoSource video; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + // verify that every third frame is a keyframe. + for (std::vector::iterator iter = kf_pts_list_.begin(); + iter != kf_pts_list_.end(); + ++iter) { + ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter; + } +} + +TEST_P(KeyframeTest, TestKeyframeMaxDistance) { + cfg_.kf_max_dist = 25; + + ::libvpx_test::DummyVideoSource video; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + // verify that keyframe interval matches kf_max_dist + for (std::vector::iterator iter = kf_pts_list_.begin(); + iter != kf_pts_list_.end(); + iter++) { + ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter; + } +} + +INSTANTIATE_TEST_CASE_P(AllModes, KeyframeTest, ALL_TEST_MODES); +} // namespace diff --git a/test/test.mk b/test/test.mk new file mode 100644 index 000000000..d04ad170f --- /dev/null +++ b/test/test.mk @@ -0,0 +1,8 @@ +LIBVPX_TEST_SRCS-yes += test.mk +LIBVPX_TEST_SRCS-yes += boolcoder_test.cc +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 += test_libvpx.cc +LIBVPX_TEST_SRCS-yes += video_source.h diff --git a/vp8/common/x86/idctllm_mmx_test.cc b/test/test_libvpx.cc old mode 100755 new mode 100644 similarity index 50% rename from vp8/common/x86/idctllm_mmx_test.cc rename to test/test_libvpx.cc index 8c115335e..48bfc6c76 --- a/vp8/common/x86/idctllm_mmx_test.cc +++ b/test/test_libvpx.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. + * 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 @@ -7,24 +7,7 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ - - - extern "C" { - void vp8_short_idct4x4llm_mmx(short *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride); -} - -#include "vp8/common/idctllm_test.h" - -namespace -{ - -INSTANTIATE_TEST_CASE_P(MMX, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_mmx)); - -} // namespace - +#include "third_party/googletest/src/include/gtest/gtest.h" int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/video_source.h b/test/video_source.h new file mode 100644 index 000000000..86c6caa83 --- /dev/null +++ b/test/video_source.h @@ -0,0 +1,109 @@ +/* + * 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_VIDEO_SOURCE_H_ +#define TEST_VIDEO_SOURCE_H_ +#include "vpx/vpx_encoder.h" + +namespace libvpx_test { + +// Abstract base class for test video sources, which provide a stream of +// vpx_image_t images with associated timestamps and duration. +class VideoSource { + public: + virtual ~VideoSource() {} + + // Prepare the stream for reading, rewind/open as necessary. + virtual void Begin() = 0; + + // Advance the cursor to the next frame + virtual void Next() = 0; + + // Get the current video frame, or NULL on End-Of-Stream. + virtual vpx_image_t *img() const = 0; + + // Get the presentation timestamp of the current frame. + virtual vpx_codec_pts_t pts() const = 0; + + // Get the current frame's duration + virtual unsigned long duration() const = 0; + + // Get the timebase for the stream + virtual vpx_rational_t timebase() const = 0; + + // Get the current frame counter, starting at 0. + virtual unsigned int frame() const = 0; +}; + + +class DummyVideoSource : public VideoSource { + public: + DummyVideoSource() + : img_(NULL), limit_(100) { SetSize(80, 64); } + + virtual ~DummyVideoSource() { vpx_img_free(img_); } + + virtual void Begin() { + frame_ = 0; + 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 = {1, 30}; + return t; + } + + 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); + } + + protected: + virtual void FillFrame() { memset(img_->img_data, 0, raw_sz_); } + + vpx_image_t *img_; + size_t raw_sz_; + unsigned int limit_; + unsigned int frame_; +}; + + +class RandomVideoSource : public DummyVideoSource { + protected: + // 15 frames of noise, followed by 15 static frames. Reset to 0 rather + // than holding previous frames to encourage keyframes to be thrown. + virtual void FillFrame() { + if (frame_ % 30 < 15) + for (size_t i = 0; i < raw_sz_; ++i) + img_->img_data[i] = rand(); + else + memset(img_->img_data, 0, raw_sz_); + } +}; + +} // namespace libvpx_test + +#endif // TEST_VIDEO_SOURCE_H_ diff --git a/vp8/common/idctllm_test.cc b/vp8/common/idctllm_test.cc deleted file mode 100755 index 0f6ebe7fe..000000000 --- a/vp8/common/idctllm_test.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010 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. - */ - - - extern "C" { - void vp8_short_idct4x4llm_c(short *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride); -} - -#include "vpx_config.h" -#include "idctllm_test.h" -namespace -{ - -INSTANTIATE_TEST_CASE_P(C, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_c)); - -} // namespace - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk index 3a7b146fc..1fbe5d43b 100644 --- a/vp8/vp8_common.mk +++ b/vp8/vp8_common.mk @@ -30,7 +30,6 @@ VP8_COMMON_SRCS-yes += common/findnearmv.c VP8_COMMON_SRCS-yes += common/generic/systemdependent.c VP8_COMMON_SRCS-yes += common/idct_blk.c VP8_COMMON_SRCS-yes += common/idctllm.c -VP8_COMMON_SRCS-yes += common/idctllm_test.cc VP8_COMMON_SRCS-yes += common/alloccommon.h VP8_COMMON_SRCS-yes += common/blockd.h VP8_COMMON_SRCS-yes += common/common.h @@ -85,7 +84,6 @@ VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/postproc.c VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/dequantize_mmx.asm VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idct_blk_mmx.c VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx.asm -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx_test.cc VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/iwalsh_mmx.asm VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/loopfilter_mmx.asm VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/recon_mmx.asm diff --git a/vp8/vp8cx.mk b/vp8/vp8cx.mk index 28deaf276..5976297bc 100644 --- a/vp8/vp8cx.mk +++ b/vp8/vp8cx.mk @@ -88,8 +88,6 @@ VP8_CX_SRCS-yes += encoder/temporal_filter.c VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING) += encoder/mr_dissim.c VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING) += encoder/mr_dissim.h -VP8_CX_SRCS-$(CONFIG_UNIT_TESTS) += encoder/boolcoder_test.cc - ifeq ($(CONFIG_REALTIME_ONLY),yes) VP8_CX_SRCS_REMOVE-yes += encoder/firstpass.c VP8_CX_SRCS_REMOVE-yes += encoder/temporal_filter.c