Commit 7f7d1357 authored by John Koleszar's avatar John Koleszar
Browse files

Merge branch 'experimental' into master

VP9 preview bitstream 2, commit '868ecb55'

Conflicts:
	vp9/vp9_common.mk

Change-Id: I3f0f6e692c987ff24f98ceafbb86cb9cf64ad8d3
parents 282c9639 868ecb55
......@@ -3,6 +3,8 @@
*.d
*.o
*~
/*.ivf
/*.ivf.md5
/*-*.mk
/*.asm
/*.doxy
......
......@@ -460,6 +460,7 @@ write_common_target_config_h() {
#ifndef VPX_CONFIG_H
#define VPX_CONFIG_H
#define RESTRICT ${RESTRICT}
#define INLINE ${INLINE}
EOF
print_config_h ARCH "${TMP_H}" ${ARCH_LIST}
print_config_h HAVE "${TMP_H}" ${HAVE_LIST}
......@@ -1005,12 +1006,6 @@ process_common_toolchain() {
#error "not x32"
#endif
EOF
soft_enable runtime_cpu_detect
soft_enable mmx
soft_enable sse
soft_enable sse2
soft_enable sse3
soft_enable ssse3
case ${tgt_os} in
win*)
......@@ -1064,9 +1059,15 @@ EOF
;;
esac
soft_enable runtime_cpu_detect
soft_enable mmx
soft_enable sse
soft_enable sse2
soft_enable sse3
soft_enable ssse3
# We can't use 'check_cflags' until the compiler is configured and CC is
# populated.
if enabled gcc && ! disabled sse4_1 && ! check_cflags -msse4.1; then
if enabled gcc && ! disabled sse4_1 && ! check_cflags -msse4; then
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-sse4_1 "
else
soft_enable sse4_1
......@@ -1174,6 +1175,14 @@ EOF
[ -f "${TMP_O}" ] && od -A n -t x1 "${TMP_O}" | tr -d '\n' |
grep '4f *32 *42 *45' >/dev/null 2>&1 && enable big_endian
# Try to find which inline keywords are supported
check_cc <<EOF && INLINE="inline"
static inline function() {}
EOF
check_cc <<EOF && INLINE="__attribute__((always_inline))"
static __attribute__((always_inline)) function() {}
EOF
# Almost every platform uses pthreads.
if enabled multithread; then
case ${toolchain} in
......
......@@ -239,17 +239,18 @@ HAVE_LIST="
"
EXPERIMENT_LIST="
csm
lossless
new_mvref
implicit_segmentation
newbintramodes
comp_interintra_pred
tx64x64
dwtdcthybrid
cnvcontext
newcoefcontext
enable_6tap
abovesprefmv
code_nonzerocount
useselectrefmv
modelcoefprob
loop_dering
implicit_compoundinter_weight
scatterscan
"
CONFIG_LIST="
external_build
......@@ -647,6 +648,7 @@ process_toolchain() {
enable solution
vs_version=${tgt_cc##vs}
all_targets="${all_targets} solution"
INLINE="__forceinline"
;;
esac
......
......@@ -8,19 +8,20 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {
// lookahead range: [kLookAheadMin, kLookAheadMax).
const int kLookAheadMin = 5;
const int kLookAheadMax = 26;
class AltRefTest : public libvpx_test::EncoderTest,
public ::testing::TestWithParam<int> {
class AltRefTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<int> {
protected:
AltRefTest() : altref_count_(0) {}
AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
virtual ~AltRefTest() {}
virtual void SetUp() {
......@@ -58,7 +59,7 @@ TEST_P(AltRefTest, MonotonicTimestamps) {
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = 1000;
cfg_.g_lag_in_frames = GetParam();
cfg_.g_lag_in_frames = GET_PARAM(1);
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
timebase.den, timebase.num, 0, 30);
......@@ -66,6 +67,7 @@ TEST_P(AltRefTest, MonotonicTimestamps) {
EXPECT_GE(altref_count(), 1);
}
INSTANTIATE_TEST_CASE_P(NonZeroLag, AltRefTest,
::testing::Range(kLookAheadMin, kLookAheadMax));
VP8_INSTANTIATE_TEST_CASE(AltRefTest,
::testing::Range(kLookAheadMin, kLookAheadMax));
} // namespace
/*
* Copyright (c) 2013 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_CODEC_FACTORY_H_
#define TEST_CODEC_FACTORY_H_
extern "C" {
#include "./vpx_config.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_encoder.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#include "vpx/vp8cx.h"
#endif
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
#include "vpx/vp8dx.h"
#endif
}
#include "test/decode_test_driver.h"
#include "test/encode_test_driver.h"
namespace libvpx_test {
class CodecFactory {
public:
CodecFactory() {}
virtual ~CodecFactory() {}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const = 0;
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
TwopassStatsStore *stats) const = 0;
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
int usage) const = 0;
};
/* Provide CodecTestWith<n>Params classes for a variable number of parameters
* to avoid having to include a pointer to the CodecFactory in every test
* definition.
*/
template<class T1>
class CodecTestWithParam : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1 > > {
};
template<class T1, class T2>
class CodecTestWith2Params : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2 > > {
};
template<class T1, class T2, class T3>
class CodecTestWith3Params : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2, T3 > > {
};
/*
* VP8 Codec Definitions
*/
#if CONFIG_VP8
class VP8Decoder : public Decoder {
public:
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
protected:
virtual const vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP8_DECODER
return &vpx_codec_vp8_dx_algo;
#else
return NULL;
#endif
}
};
class VP8Encoder : public Encoder {
public:
VP8Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
const unsigned long init_flags, TwopassStatsStore *stats)
: Encoder(cfg, deadline, init_flags, stats) {}
protected:
virtual const vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP8_ENCODER
return &vpx_codec_vp8_cx_algo;
#else
return NULL;
#endif
}
};
class VP8CodecFactory : public CodecFactory {
public:
VP8CodecFactory() : CodecFactory() {}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
#if CONFIG_VP8_DECODER
return new VP8Decoder(cfg, deadline);
#else
return NULL;
#endif
}
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
TwopassStatsStore *stats) const {
#if CONFIG_VP8_ENCODER
return new VP8Encoder(cfg, deadline, init_flags, stats);
#else
return NULL;
#endif
}
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
int usage) const {
#if CONFIG_VP8_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
#else
return VPX_CODEC_INCAPABLE;
#endif
}
};
const libvpx_test::VP8CodecFactory kVP8;
#define VP8_INSTANTIATE_TEST_CASE(test, params)\
INSTANTIATE_TEST_CASE_P(VP8, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP8)), \
params))
#else
#define VP8_INSTANTIATE_TEST_CASE(test, params)
#endif // CONFIG_VP8
/*
* VP9 Codec Definitions
*/
#if CONFIG_VP9
class VP9Decoder : public Decoder {
public:
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
protected:
virtual const vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP9_DECODER
return &vpx_codec_vp9_dx_algo;
#else
return NULL;
#endif
}
};
class VP9Encoder : public Encoder {
public:
VP9Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
const unsigned long init_flags, TwopassStatsStore *stats)
: Encoder(cfg, deadline, init_flags, stats) {}
protected:
virtual const vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP9_ENCODER
return &vpx_codec_vp9_cx_algo;
#else
return NULL;
#endif
}
};
class VP9CodecFactory : public CodecFactory {
public:
VP9CodecFactory() : CodecFactory() {}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
#if CONFIG_VP9_DECODER
return new VP9Decoder(cfg, deadline);
#else
return NULL;
#endif
}
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
TwopassStatsStore *stats) const {
#if CONFIG_VP9_ENCODER
return new VP9Encoder(cfg, deadline, init_flags, stats);
#else
return NULL;
#endif
}
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
int usage) const {
#if CONFIG_VP9_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
#else
return VPX_CODEC_INCAPABLE;
#endif
}
};
const libvpx_test::VP9CodecFactory kVP9;
#define VP9_INSTANTIATE_TEST_CASE(test, params)\
INSTANTIATE_TEST_CASE_P(VP9, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP9)), \
params))
#else
#define VP9_INSTANTIATE_TEST_CASE(test, params)
#endif // CONFIG_VP9
} // namespace libvpx_test
#endif // TEST_CODEC_FACTORY_H_
......@@ -8,20 +8,22 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/video_source.h"
namespace {
class ConfigTest : public ::libvpx_test::EncoderTest,
public ::testing::TestWithParam<enum libvpx_test::TestMode> {
public:
ConfigTest() : frame_count_in_(0), frame_count_out_(0), frame_count_max_(0) {}
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ConfigTest() : EncoderTest(GET_PARAM(0)),
frame_count_in_(0), frame_count_out_(0), frame_count_max_(0) {}
virtual void SetUp() {
InitializeConfig();
SetMode(GetParam());
SetMode(GET_PARAM(1));
}
virtual void BeginPassHook(unsigned int /*pass*/) {
......@@ -57,5 +59,5 @@ TEST_P(ConfigTest, LagIsDisabled) {
EXPECT_EQ(frame_count_in_, frame_count_out_);
}
INSTANTIATE_TEST_CASE_P(OnePassModes, ConfigTest, ONE_PASS_TEST_MODES);
VP8_INSTANTIATE_TEST_CASE(ConfigTest, ONE_PASS_TEST_MODES);
} // namespace
/*
* 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" {
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_filter.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
}
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
#include "test/util.h"
namespace {
typedef void (*convolve_fn_t)(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride,
const int16_t *filter_x, int filter_x_stride,
const int16_t *filter_y, int filter_y_stride,
int w, int h);
struct ConvolveFunctions {
ConvolveFunctions(convolve_fn_t h8, convolve_fn_t h8_avg,
convolve_fn_t v8, convolve_fn_t v8_avg,
convolve_fn_t hv8, convolve_fn_t hv8_avg)
: h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg), v8_avg_(v8_avg),
hv8_avg_(hv8_avg) {}
convolve_fn_t h8_;
convolve_fn_t v8_;
convolve_fn_t hv8_;
convolve_fn_t h8_avg_;
convolve_fn_t v8_avg_;
convolve_fn_t hv8_avg_;
};
// Reference 8-tap subpixel filter, slightly modified to fit into this test.
#define VP9_FILTER_WEIGHT 128
#define VP9_FILTER_SHIFT 7
static uint8_t clip_pixel(int x) {
return x < 0 ? 0 :
x > 255 ? 255 :
x;
}
static void filter_block2d_8_c(const uint8_t *src_ptr,
const unsigned int src_stride,
const int16_t *HFilter,
const int16_t *VFilter,
uint8_t *dst_ptr,
unsigned int dst_stride,
unsigned int output_width,
unsigned int output_height) {
// Between passes, we use an intermediate buffer whose height is extended to
// have enough horizontally filtered values as input for the vertical pass.
// This buffer is allocated to be big enough for the largest block type we
// support.
const int kInterp_Extend = 4;
const unsigned int intermediate_height =
(kInterp_Extend - 1) + output_height + kInterp_Extend;
/* Size of intermediate_buffer is max_intermediate_height * filter_max_width,
* where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
* + kInterp_Extend
* = 3 + 16 + 4
* = 23
* and filter_max_width = 16
*/
uint8_t intermediate_buffer[23 * 16];
const int intermediate_next_stride = 1 - intermediate_height * output_width;
// Horizontal pass (src -> transposed intermediate).
{
uint8_t *output_ptr = intermediate_buffer;
const int src_next_row_stride = src_stride - output_width;
unsigned int i, j;
src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
for (i = 0; i < intermediate_height; ++i) {
for (j = 0; j < output_width; ++j) {
// Apply filter...
int temp = ((int)src_ptr[0] * HFilter[0]) +
((int)src_ptr[1] * HFilter[1]) +
((int)src_ptr[2] * HFilter[2]) +
((int)src_ptr[3] * HFilter[3]) +
((int)src_ptr[4] * HFilter[4]) +
((int)src_ptr[5] * HFilter[5]) +
((int)src_ptr[6] * HFilter[6]) +
((int)src_ptr[7] * HFilter[7]) +
(VP9_FILTER_WEIGHT >> 1); // Rounding
// Normalize back to 0-255...
*output_ptr = clip_pixel(temp >> VP9_FILTER_SHIFT);
++src_ptr;
output_ptr += intermediate_height;
}
src_ptr += src_next_row_stride;
output_ptr += intermediate_next_stride;
}
}
// Vertical pass (transposed intermediate -> dst).
{
uint8_t *src_ptr = intermediate_buffer;
const int dst_next_row_stride = dst_stride - output_width;
unsigned int i, j;
for (i = 0; i < output_height; ++i) {
for (j = 0; j < output_width; ++j) {
// Apply filter...
int temp = ((int)src_ptr[0] * VFilter[0]) +
((int)src_ptr[1] * VFilter[1]) +
((int)src_ptr[2] * VFilter[2]) +
((int)src_ptr[3] * VFilter[3]) +
((int)src_ptr[4] * VFilter[4]) +
((int)src_ptr[5] * VFilter[5]) +
((int)src_ptr[6] * VFilter[6]) +
((int)src_ptr[7] * VFilter[7]) +
(VP9_FILTER_WEIGHT >> 1); // Rounding
// Normalize back to 0-255...
*dst_ptr++ = clip_pixel(temp >> VP9_FILTER_SHIFT);
src_ptr += intermediate_height;
}
src_ptr += intermediate_next_stride;
dst_ptr += dst_next_row_stride;
}
}
}
static void block2d_average_c(uint8_t *src,
unsigned int src_stride,
uint8_t *output_ptr,
unsigned int output_stride,
unsigned int output_width,
unsigned int output_height) {
unsigned int i, j;
for (i = 0; i < output_height; ++i) {
for (j = 0; j < output_width; ++j) {
output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
}
output_ptr += output_stride;
}
}
static void filter_average_block2d_8_c(const uint8_t *src_ptr,
const unsigned int src_stride,
const int16_t *HFilter,
const int16_t *VFilter,
uint8_t *dst_ptr,
unsigned int dst_stride,
unsigned int output_width,
unsigned int output_height) {
uint8_t tmp[16*16];
assert(output_width <= 16);
assert(output_height <= 16);
filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, 16,
output_width, output_height);
block2d_average_c(tmp, 16, dst_ptr, dst_stride,
output_width, output_height);
}
class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
public:
static void SetUpTestCase() {
// Force input_ to be unaligned, output to be 16 byte aligned.
input_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kOuterBlockSize * kOuterBlockSize + 1))
+ 1;
output_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kOuterBlockSize * kOuterBlockSize));
}
static void TearDownTestCase() {
vpx_free(input_ - 1);
input_ = NULL;
vpx_free(output_);
output_ = NULL;
}
protected:
static const int kDataAlignment = 16;
static const int kOuterBlockSize = 32;
static const int kInputStride = kOuterBlockSize;
static const int kOutputStride = kOuterBlockSize;
static const int kMaxDimension = 16;
int Width() const { return GET_PARAM(0); }
int Height() const { return GET_PARAM(1); }
int BorderLeft() const {
const int center = (kOuterBlockSize - Width()) / 2;
return (center + (kDataAlignment - 1)) & ~(kDataAlignment - 1);
}
int BorderTop() const { return (kOuterBlockSize - Height()) / 2; }
bool IsIndexInBorder(int i) {
return (i < BorderTop() * kOuterBlockSize ||
i >= (BorderTop() + Height()) * kOuterBlockSize ||
i % kOuterBlockSize < BorderLeft() ||
i % kOuterBlockSize >= (BorderLeft() + Width()));
}
virtual void SetUp() {
UUT_ = GET_PARAM(2);
memset(input_, 0, sizeof(input_));
/* Set up guard blocks for an inner block cetered in the outer block */
for (int i = 0; i < kOuterBlockSize * kOuterBlockSize; ++i) {
if (IsIndexInBorder(i))