Commit a419f0f2 authored by John Koleszar's avatar John Koleszar Committed by Gerrit Code Review
Browse files

Merge changes I38e93fe2,I6d6a0fb6,I51155833,If4c3e5d4,Ia2f40ef2

* changes:
  Add initial keyframe tests
  Move all tests to test/ directory
  Enable unit tests by default
  Build unit tests monolithically
  configure: initial support for CXX, CXXFLAGS variables
parents ad479a9b b9180fc0
...@@ -66,6 +66,7 @@ endif ...@@ -66,6 +66,7 @@ endif
BUILD_ROOT?=. BUILD_ROOT?=.
VPATH=$(SRC_PATH_BARE) VPATH=$(SRC_PATH_BARE)
CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH) 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)/ ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/ -I$(SRC_PATH)/
DIST_DIR?=dist DIST_DIR?=dist
HOSTCC?=gcc HOSTCC?=gcc
...@@ -111,11 +112,11 @@ $(BUILD_PFX)%.c.o: %.c ...@@ -111,11 +112,11 @@ $(BUILD_PFX)%.c.o: %.c
$(BUILD_PFX)%.cc.d: %.cc $(BUILD_PFX)%.cc.d: %.cc
$(if $(quiet),@echo " [DEP] $@") $(if $(quiet),@echo " [DEP] $@")
$(qexec)mkdir -p $(dir $@) $(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 $(BUILD_PFX)%.cc.o: %.cc
$(if $(quiet),@echo " [CXX] $@") $(if $(quiet),@echo " [CXX] $@")
$(qexec)g++ $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $< $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
$(BUILD_PFX)%.asm.d: %.asm $(BUILD_PFX)%.asm.d: %.asm
$(if $(quiet),@echo " [DEP] $@") $(if $(quiet),@echo " [DEP] $@")
...@@ -213,7 +214,7 @@ define linkerxx_template ...@@ -213,7 +214,7 @@ define linkerxx_template
$(1): $(filter-out -%,$(2)) $(1): $(filter-out -%,$(2))
$(1): $(1):
$(if $(quiet),@echo " [LD] $$@") $(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 endef
# make-3.80 has a bug with expanding large input strings to the eval function, # 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 # which was triggered in some cases by the following component of
......
...@@ -166,6 +166,17 @@ is_in(){ ...@@ -166,6 +166,17 @@ is_in(){
add_cflags() { add_cflags() {
CFLAGS="${CFLAGS} $@" CFLAGS="${CFLAGS} $@"
CXXFLAGS="${CXXFLAGS} $@"
}
add_cflags_only() {
CFLAGS="${CFLAGS} $@"
}
add_cxxflags_only() {
CXXFLAGS="${CXXFLAGS} $@"
} }
...@@ -277,6 +288,13 @@ check_cc() { ...@@ -277,6 +288,13 @@ check_cc() {
check_cmd ${CC} ${CFLAGS} "$@" -c -o ${TMP_O} ${TMP_C} 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() { check_cpp() {
log check_cpp "$@" log check_cpp "$@"
cat > ${TMP_C} cat > ${TMP_C}
...@@ -310,8 +328,25 @@ int x; ...@@ -310,8 +328,25 @@ int x;
EOF EOF
} }
check_cxxflags() {
log check_cxxflags "$@"
# Catch CFLAGS that trigger CXX warnings
case "$CXX" in
*g++*) check_cxx -Werror "$@" <<EOF
int x;
EOF
;;
*) check_cxx "$@" <<EOF
int x;
EOF
;;
esac
}
check_add_cflags() { check_add_cflags() {
check_cflags "$@" && add_cflags "$@" check_cxxflags "$@" && add_cxxflags_only "$@"
check_cflags "$@" && add_cflags_only "$@"
} }
check_add_asflags() { check_add_asflags() {
...@@ -367,7 +402,9 @@ true ...@@ -367,7 +402,9 @@ true
write_common_target_config_mk() { write_common_target_config_mk() {
local CC=${CC} local CC=${CC}
local CXX=${CXX}
enabled ccache && CC="ccache ${CC}" enabled ccache && CC="ccache ${CC}"
enabled ccache && CXX="ccache ${CXX}"
print_webm_license $1 "##" "" print_webm_license $1 "##" ""
cat >> $1 << EOF cat >> $1 << EOF
...@@ -379,6 +416,7 @@ TOOLCHAIN=${toolchain} ...@@ -379,6 +416,7 @@ TOOLCHAIN=${toolchain}
ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl} ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl}
CC=${CC} CC=${CC}
CXX=${CXX}
AR=${AR} AR=${AR}
LD=${LD} LD=${LD}
AS=${AS} AS=${AS}
...@@ -386,6 +424,7 @@ STRIP=${STRIP} ...@@ -386,6 +424,7 @@ STRIP=${STRIP}
NM=${NM} NM=${NM}
CFLAGS = ${CFLAGS} CFLAGS = ${CFLAGS}
CXXFLAGS = ${CXXFLAGS}
ARFLAGS = -rus\$(if \$(quiet),c,v) ARFLAGS = -rus\$(if \$(quiet),c,v)
LDFLAGS = ${LDFLAGS} LDFLAGS = ${LDFLAGS}
ASFLAGS = ${ASFLAGS} ASFLAGS = ${ASFLAGS}
...@@ -538,6 +577,7 @@ post_process_cmdline() { ...@@ -538,6 +577,7 @@ post_process_cmdline() {
setup_gnu_toolchain() { setup_gnu_toolchain() {
CC=${CC:-${CROSS}gcc} CC=${CC:-${CROSS}gcc}
CXX=${CXX:-${CROSS}g++}
AR=${AR:-${CROSS}ar} AR=${AR:-${CROSS}ar}
LD=${LD:-${CROSS}${link_with_cc:-ld}} LD=${LD:-${CROSS}${link_with_cc:-ld}}
AS=${AS:-${CROSS}as} AS=${AS:-${CROSS}as}
...@@ -792,6 +832,7 @@ process_common_toolchain() { ...@@ -792,6 +832,7 @@ process_common_toolchain() {
-name "arm-linux-androideabi-gcc*" -print -quit` -name "arm-linux-androideabi-gcc*" -print -quit`
TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi- TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi-
CC=${TOOLCHAIN_PATH}gcc CC=${TOOLCHAIN_PATH}gcc
CXX=${TOOLCHAIN_PATH}g++
AR=${TOOLCHAIN_PATH}ar AR=${TOOLCHAIN_PATH}ar
LD=${TOOLCHAIN_PATH}gcc LD=${TOOLCHAIN_PATH}gcc
AS=${TOOLCHAIN_PATH}as AS=${TOOLCHAIN_PATH}as
...@@ -827,6 +868,7 @@ process_common_toolchain() { ...@@ -827,6 +868,7 @@ process_common_toolchain() {
SDK_PATH=${sdk_path} SDK_PATH=${sdk_path}
fi fi
TOOLCHAIN_PATH=${SDK_PATH}/usr/bin TOOLCHAIN_PATH=${SDK_PATH}/usr/bin
CXX=${TOOLCHAIN_PATH}/g++
CC=${TOOLCHAIN_PATH}/gcc CC=${TOOLCHAIN_PATH}/gcc
AR=${TOOLCHAIN_PATH}/ar AR=${TOOLCHAIN_PATH}/ar
LD=${TOOLCHAIN_PATH}/arm-apple-darwin10-llvm-gcc-4.2 LD=${TOOLCHAIN_PATH}/arm-apple-darwin10-llvm-gcc-4.2
...@@ -938,6 +980,7 @@ process_common_toolchain() { ...@@ -938,6 +980,7 @@ process_common_toolchain() {
;; ;;
solaris*) solaris*)
CC=${CC:-${CROSS}gcc} CC=${CC:-${CROSS}gcc}
CXX=${CXX:-${CROSS}g++}
LD=${LD:-${CROSS}gcc} LD=${LD:-${CROSS}gcc}
CROSS=${CROSS:-g} CROSS=${CROSS:-g}
;; ;;
......
...@@ -586,6 +586,16 @@ process_toolchain() { ...@@ -586,6 +586,16 @@ process_toolchain() {
if enabled postproc_visualizer; then if enabled postproc_visualizer; then
enabled postproc || die "postproc_visualizer requires postproc to be enabled" enabled postproc || die "postproc_visualizer requires postproc to be enabled"
fi fi
# Enable unit tests if we have a working C++ compiler
case "$tgt_cc" in
vs*)
soft_enable unit_tests;;
*)
check_cxx "$@" <<EOF && soft_enable unit_tests
int z;
EOF
esac
} }
......
...@@ -329,7 +329,6 @@ CLEAN-OBJS += $(BUILD_PFX)vpx_version.h ...@@ -329,7 +329,6 @@ CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
# #
# Rule to generate runtime cpu detection files # Rule to generate runtime cpu detection files
# #
$(OBJS-yes:.o=.d): $(BUILD_PFX)vpx_rtcd.h
$(BUILD_PFX)vpx_rtcd.h: $(SRC_PATH_BARE)/$(sort $(filter %rtcd_defs.sh,$(CODEC_SRCS))) $(BUILD_PFX)vpx_rtcd.h: $(SRC_PATH_BARE)/$(sort $(filter %rtcd_defs.sh,$(CODEC_SRCS)))
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(qexec)$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$(TGT_ISA) \ $(qexec)$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$(TGT_ISA) \
...@@ -346,14 +345,15 @@ CODEC_DOC_SRCS += vpx/vpx_codec.h \ ...@@ -346,14 +345,15 @@ CODEC_DOC_SRCS += vpx/vpx_codec.h \
## ##
## libvpx test directives ## libvpx test directives
## ##
ifeq ($(CONFIG_UNIT_TESTS),yes) ifeq ($(CONFIG_UNIT_TESTS),yes)
include $(SRC_PATH_BARE)/test/test.mk
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
LIBVPX_TEST_BINS=./test_libvpx
ifeq ($(CONFIG_EXTERNAL_BUILD),yes) ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
ifeq ($(CONFIG_MSVS),yes) ifeq ($(CONFIG_MSVS),yes)
LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS))
LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_SRCS:.cc.o=))
gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ $(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
...@@ -397,23 +397,26 @@ else ...@@ -397,23 +397,26 @@ else
include $(SRC_PATH_BARE)/third_party/googletest/gtest.mk include $(SRC_PATH_BARE)/third_party/googletest/gtest.mk
GTEST_SRCS := $(addprefix third_party/googletest/src/,$(call enabled,GTEST_SRCS)) GTEST_SRCS := $(addprefix third_party/googletest/src/,$(call enabled,GTEST_SRCS))
GTEST_OBJS=$(call objs,$(GTEST_SRCS)) GTEST_OBJS=$(call objs,$(GTEST_SRCS))
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS) OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS)
LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS) $(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS)) LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
LIBVPX_TEST_OBJS=$(call objs,$(LIBVPX_TEST_SRCS)) $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_OBJS:.cc.o=))
OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS) OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS)
# Install test sources only if codec source is included
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
$(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
$(foreach bin,$(LIBVPX_TEST_BINS),\ $(foreach bin,$(LIBVPX_TEST_BINS),\
$(if $(BUILD_LIBVPX),$(eval $(bin): libvpx.a libgtest.a ))\ $(if $(BUILD_LIBVPX),$(eval $(bin): libvpx.a libgtest.a ))\
$(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\ $(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\
$(bin).cc.o \ $(LIBVPX_TEST_OBJS) \
-L. -lvpx -lgtest -lpthread -lm)\ -L. -lvpx -lgtest -lpthread -lm)\
)))\ )))\
$(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\ $(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
...@@ -436,3 +439,6 @@ libs.doxy: $(CODEC_DOC_SRCS) ...@@ -436,3 +439,6 @@ libs.doxy: $(CODEC_DOC_SRCS)
@echo "PREDEFINED = VPX_CODEC_DISABLE_COMPAT" >> $@ @echo "PREDEFINED = VPX_CODEC_DISABLE_COMPAT" >> $@
@echo "INCLUDE_PATH += ." >> $@; @echo "INCLUDE_PATH += ." >> $@;
@echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@ @echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@
## Generate vpx_rtcd.h for all objects
$(OBJS-yes:.o=.d): $(BUILD_PFX)vpx_rtcd.h
...@@ -121,9 +121,3 @@ TEST(VP8, TestBitIO) ...@@ -121,9 +121,3 @@ TEST(VP8, TestBitIO)
} }
} }
} }
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
/*
* 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
/*
* 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 <string>
#include <vector>
#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<char *>(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.